Teams Workflows ile günlük işlerimi kolaylaştıran 3 akış.
Roz anlatıyorNeden Teams Workflows?

Bu yazıda, Teams’in içindeki Workflows uygulamasını kullanarak günlük işlerde karşılaşılabilecek üç farklı ihtiyaca yönelik akışları ele alıyorum.
Workflows, Power Automate akışlarını doğrudan Teams üzerinden oluşturup çalıştırmayı sağlayan bir deneyim sunuyor. Standart bağlayıcılarla pek çok senaryoyu ek bir lisans gerektirmeden hayata geçirmek mümkün. Uygulama, 2026 yılında hem bağlantı yöntemleri hem de kullanım deneyimi açısından bazı değişiklikler geçirdi.
Öne çıkan değişikliklerden biri, eski Office 365 Connectors altyapısının devre dışı bırakılması ve Teams kanallarına webhook üzerinden bildirim göndermek için Workflows tabanlı yaklaşımın öne çıkması. Yeni Workflows deneyimiyle birlikte akış oluşturma ve yönetme tarafında da yenilikler sunuldu.
Bu yazıda üç senaryoya odaklanıyorum:
| Akış | Tetikleyici | Kullanım amacı |
|---|---|---|
| CRM’den Teams kanalına bildirim | Webhook | Yeni kayıtları ilgili ekibe duyurmak |
| Teams mesajından güncelleme talebi oluşturma | Mesaj üzerindeki özel eylem | Gelen talepleri kayıt altına almak |
| Haftalık açık talep özeti | Zamanlayıcı | Bekleyen işleri düzenli olarak takip etmek |
Bu üç senaryonun ortak noktası, günlük işlerde sıkça karşılaşılan bildirim ve takip adımlarını otomatikleştirmek. Böylece hem bilgilerin sohbetler arasında kaybolmasını önlemek hem de manuel takibi azaltmak mümkün.
1. On-premises Dynamics 365’ten Teams kanalına bildirim gönderme
Karşılaşılan sorun
Dynamics 365’te yeni bir fırsat veya başka bir kayıt oluşturulduğunda ilgili ekibe otomatik bildirim göndermek isteyebilirsiniz. Ancak CRM’in on-premises ortamda çalıştığı bir yapıda, cloud flow’larının CRM’i doğrudan izlemesi için ek bağlantı ve yapılandırma gereksinimleri ortaya çıkabilir.
E-posta bildirimi göndermek bir seçenek olsa da bu bildirimlerin gözden kaçması veya gelen kutusunda kaybolması mümkün.
Alternatif bir yaklaşım, bildirimi CRM’den başlatıp Teams’e göndermek.
Çözüm nasıl çalışıyor?
Bu senaryoda Teams tarafında bir webhook adresi oluşturuluyor. CRM tarafında çalışan bir asenkron plugin ise yeni kayıt oluştuğunda bu adrese HTTP POST isteği gönderiyor.
Buradaki yaklaşımın temel farkı şu: Power Automate akışı CRM’deki değişikliği kendisi takip etmiyor. Bunun yerine CRM, gerekli olay gerçekleştiğinde Teams tarafındaki akışı tetikliyor.
Adım 1: Teams’te webhook oluşturma
Bildirimlerin gönderileceği Teams kanalını açın.
- Kanalın seçenekler menüsünden (More options) Workflows bölümüne girin.
- Webhook isteği alındığında kanala mesaj gönderen şablonu seçin.
- Ortama göre şablonun adı farklı görünebilir.
- Akışa bir ad verin ve ilgili takım ile kanalı belirleyin.
- Akışı kaydedin ve oluşturulan webhook URL’sini alın.
Webhook URL’sinin biçimini kontrol etmek önemlidir. Yeni bağlantı biçimlerinde environment.api.powerplatform.com adresi ve api-version=1 parametresi görülebilir. Eski bağlantıların çalıştığını varsaymak yerine kullanılan URL’nin güncel yapıyla uyumlu olduğunu doğrulayın.
Güvenlik notu: Webhook URL’si gizli tutulması gereken bir bilgidir. URL’yi bilen kişiler, gerekli erişim koşulları sağlandığında kanala mesaj gönderebilir. Bu nedenle URL’yi kaynak koda doğrudan yazmak veya istemci tarafında görünür hâle getirmek doğru bir yaklaşım değildir.
Adım 2: CRM plugin’ini yapılandırma
CRM tarafındaki plugin, kayıt oluşturulduktan sonra webhook adresine istek gönderir. Dynamics 365 v9 on-premises ortamlarında kullanılan .NET Framework hedefi ve TLS yapılandırması gibi ayrıntılar, bağlantının başarılı olması açısından önemlidir.
Örnek uygulamada webhook adresi plugin koduna doğrudan yazılmıyor. Bunun yerine Plugin Registration Tool üzerinden Secure Configuration alanında saklanıyor.
Aşağıdaki örnek, temel yaklaşımı göstermek amacıyla hazırlanmıştır. Kendi ortamınızda kullanmadan önce hedef .NET Framework sürümünü, TLS ayarlarını, ağ erişimini ve hata yönetimini doğrulamanız gerekir.
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.Xrm.Sdk;
public class NotifyTeamsOnCreate : IPlugin
{
private readonly string _webhookUrl;
public NotifyTeamsOnCreate(string unsecureConfig, string secureConfig)
{
_webhookUrl = secureConfig;
}
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
if (string.IsNullOrWhiteSpace(_webhookUrl))
{
tracing.Trace("Webhook URL tanımlı değil, bildirim atlanıyor.");
return;
}
var target = context.InputParameters.Contains("Target")
? context.InputParameters["Target"] as Entity
: null;
if (target == null) return;
var name = target.GetAttributeValue<string>("name") ?? "(isimsiz kayıt)";
var recordUrl = string.Format(
"https://crm.example.local/ORG/main.aspx?etn={0}&id={1}&pagetype=entityrecord",
target.LogicalName, target.Id);
var payload = BuildCard("Yeni kayıt oluşturuldu", name, target.LogicalName, recordUrl);
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) })
{
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = client.PostAsync(_webhookUrl, content).GetAwaiter().GetResult();
tracing.Trace("Teams webhook yanıtı: {0}", (int)response.StatusCode);
}
}
private static string BuildCard(string title, string recordName, string entity, string url)
{
return @"{
""type"": ""message"",
""attachments"": [{
""contentType"": ""application/vnd.microsoft.card.adaptive"",
""content"": {
""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"",
""type"": ""AdaptiveCard"",
""version"": ""1.4"",
""body"": [
{ ""type"": ""TextBlock"", ""text"": """ + Esc(title) + @""", ""weight"": ""Bolder"", ""size"": ""Medium"" },
{ ""type"": ""FactSet"", ""facts"": [
{ ""title"": ""Kayıt"", ""value"": """ + Esc(recordName) + @""" },
{ ""title"": ""Varlık"", ""value"": """ + Esc(entity) + @""" }
]}
],
""actions"": [
{ ""type"": ""Action.OpenUrl"", ""title"": ""CRM'de aç"", ""url"": """ + Esc(url) + @""" }
]
}
}]
}";
}
private static string Esc(string value)
{
return (value ?? string.Empty)
.Replace("\\", "\\\\")
.Replace("\"", "\\\"")
.Replace("\r", "\\r")
.Replace("\n", "\\n");
}
}
Kodda geçen CRM adresi örnek amaçlıdır. Kendi ortamınızdaki doğru adresle değiştirilmelidir. Ayrıca name alanının her varlıkta bulunmayabileceğini göz önünde bulundurun; örneği farklı varlıklarda kullanacaksanız kayıt adının nasıl alınacağını buna göre düzenleyin.
Adım 3: Plugin kayıt ayarları
Örnekteki plugin için temel kayıt ayarları şu şekilde planlanabilir:
| Alan | Değer | Açıklama |
|---|---|---|
| Message | Create | Yeni kayıt oluşturulduğunda çalışır |
| Primary Entity | opportunity | Örnek olarak fırsat varlığı seçilmiştir |
| Stage | PostOperation | Kayıt oluşturma işleminin ardından çalışır |
| Execution Mode | Asynchronous | Bildirim işleminin kullanıcıyı bekletmesini önlemeyi amaçlar |
| Secure Configuration | Webhook URL | Bağlantı adresinin yapılandırmada tutulmasını sağlar |
Burada özellikle dikkat edilmesi gereken bir konu var: Asenkron plugin, kullanıcının tarayıcısında veya CRM’in ön yüzünde çalışmaz. İşlem, asenkron servis altyapısı üzerinden yürütülür. Bu nedenle dış bağlantı izinlerinin doğru sunucuda tanımlanması gerekir.
Bağlantı kurulamazsa TLS yapılandırması, proxy ayarları, güvenlik duvarı kuralları ve HTTP yanıt kodları kontrol edilmelidir.
Bu senaryodan çıkarılabilecek sonuç: On-premises CRM ile buluttaki Teams arasında bildirim akışı kurmak için CRM’in doğrudan bir cloud flow tarafından izlenmesi her zaman tek seçenek değildir. Ancak bu yaklaşımın uygulanabilirliği, kurumun ağ ve güvenlik yapılandırmasına bağlıdır.
2. Teams mesajından CRM güncelleme talebi oluşturma
Karşılaşılan sorun
CRM verilerinin güncellenmesiyle ilgili talepler çoğu zaman Teams sohbetlerinde ortaya çıkıyor. Örneğin:
- Bir kişinin şirket bilgisinin değiştiğinin bildirilmesi
- CRM’de bulunmayan bir kişi için kayıt açılmasının istenmesi
- Yanlış veya eksik bir kaydın düzeltilmesinin talep edilmesi
Bu talepler yalnızca sohbet mesajı olarak kaldığında, daha sonra tekrar bulmak veya hangi işlerin tamamlandığını takip etmek zorlaşabiliyor.
Çözüm nasıl çalışıyor?
Teams mesajının üzerindeki seçenekler menüsünden çalıştırılabilen bir akış oluşturulabilir. Kullanıcı, mesaj üzerinden özel eylemi seçtiğinde talep türünü belirler ve ilgili mesaj Planner’da bir göreve dönüştürülür.
Akış, talebi gönderen kişiye de mesajın yanıtı üzerinden bilgilendirme yapabilir.
Aslında yalnızca bir Planner görevi oluşturmak istiyorsanız özel bir akış hazırlamak zorunda değilsiniz. Teams’in yerleşik Create Planner task seçeneği de bu ihtiyacı karşılayabilir. Özel akışın avantajı, talep türünü seçtirmek, görev başlığını belirli bir formatta oluşturmak ve otomatik yanıt göndermek gibi ek adımların tek süreçte birleştirilebilmesidir.
Kurulum adımları
- Planner’da CRM Güncelleme Talepleri adında bir plan oluşturun.
- Gelen talepleri toplamak için Gelen adında bir bölüm (bucket) ekleyin.
- Teams Workflows uygulamasında yeni bir akış oluşturun.
- Tetikleyici olarak Microsoft Teams bağlayıcısındaki For a selected message (V2) seçeneğini kullanın.
- Kullanıcının talep türünü seçebilmesi için bir Adaptive Card formu ekleyin.
- Planner bağlayıcısındaki Create a task adımıyla görevi oluşturun.
- Son olarak Teams üzerinden talebi gönderen kişiye bir yanıt iletin.
Formda başlangıç için üç seçenek yeterli olabilir:
- Kişi güncelleme
- Firma güncelleme
- Hata bildirimi
Bu sayede talepler daha en başta sınıflandırılır ve daha sonra filtrelenmeleri kolaylaşır.
Görev başlığını otomatik oluşturma
Görev başlığında talep türü ile mesajın ilk 80 karakterini bir araya getirebiliriz. Böylece görev listesine bakıldığında talebin ne hakkında olduğu daha kolay anlaşılır.
Örnek Power Automate ifadesi:
concat(
'[', triggerBody()?['cardOutputs']?['talepTipi'], '] ',
if(
greater(length(triggerBody()?['messagePayload']?['body']?['plainTextContent']), 80),
substring(triggerBody()?['messagePayload']?['body']?['plainTextContent'], 0, 80),
triggerBody()?['messagePayload']?['body']?['plainTextContent']
)
)
Görev açıklamasına ise talebi gönderen kişinin adını ve ilgili Teams mesajının bağlantısını ekleyebiliriz:
concat(
'Talep eden: ', triggerBody()?['messagePayload']?['from']?['user']?['displayName'],
decodeUriComponent('%0A'),
'Mesaj: ', triggerBody()?['messagePayload']?['linkToMessage']
)
Bu ifadelerdeki alan yolları kullanılan tetikleyiciye ve dönen verinin yapısına bağlıdır. İlk çalıştırmadan sonra akışın çalışma geçmişini (Run history) inceleyerek gerçek çıktı alanlarını kontrol etmek gerekir. Alan adları farklıysa ifadeler de buna göre güncellenmelidir.
Bu senaryodan çıkarılabilecek sonuç: Teams üzerinden gelen talepleri ayrı bir uygulamaya geçmeden görev listesine dönüştürmek, manuel kayıt ve takip ihtiyacını azaltabilir. Ancak akışı kullanıma almadan önce tetikleyici çıktılarının ve görev oluşturma adımlarının test edilmesi gerekir.
3. Haftalık açık talep özeti oluşturma
Karşılaşılan sorun
İkinci akışla talepleri Planner’da toplamaya başladığımızı düşünelim. Bu kez başka bir sorun ortaya çıkıyor: Talepler kayıt altına alınmış olsa da Planner düzenli olarak kontrol edilmiyorsa bekleyen işler gözden kaçabiliyor.
Bu noktada haftalık bir özet, bekleyen işleri görünür hâle getirmek için kullanılabilir.
Çözüm nasıl çalışıyor?
Her pazartesi sabahı çalışan bir akış, Planner’daki tamamlanmamış görevleri listeler ve ilgili Teams kanalına toplu bir özet gönderir.
Özet tablosunda talep başlığı ve oluşturulma tarihinden hesaplanan bekleme süresi bulunur. Böylece hangi taleplerin daha uzun süredir beklediği kolayca görülebilir.
Akışın kurulumu
- Recurrence tetikleyicisini ekleyin. Akış haftada bir, pazartesi günü saat 09.00’da çalışacak şekilde ayarlanabilir. Saat dilimini İstanbul olarak belirleyin.
- List tasks (Planner) adımıyla ilgili planın görevlerini alın.
- Filter array adımıyla tamamlanmamış görevleri filtreleyin.
- Select adımıyla özet tablosunda gösterilecek alanları belirleyin.
- Liste boşsa mesaj gönderilmesini önleyen bir koşul ekleyin.
- Create HTML table adımıyla tabloyu oluşturun ve Post message in a chat or channel adımıyla Teams’e gönderin.
Tamamlanmamış görevleri filtreleme
Filter array adımının gelişmiş modunda şu ifade kullanılabilir:
@less(item()?['percentComplete'], 100)
Tabloya aktarılacak alanlar için Select adımında şu eşlemeler örnek alınabilir:
| Alan | Değer |
|---|---|
| Talep | item()?['title'] |
| Bekleyen gün | div(sub(ticks(utcNow()), ticks(item()?['createdDateTime'])), 864000000000) |
İkinci ifade, görevin oluşturulma zamanı ile mevcut zaman arasındaki farkı gün cinsinden hesaplamayı amaçlar. Buradaki 864000000000 değeri bir gündeki tick sayısıdır.
Liste boş değilse tablo gönderilmesini sağlayan koşul şu şekilde yazılabilir:
greater(length(body('Filter_array')), 0)
Böylece hiç açık talep bulunmayan haftalarda gereksiz mesaj gönderilmez. Aksi durumda kanalda sürekli tekrarlanan boş özetler zamanla göz ardı edilebilir.
Bekleme süresi en yüksek olan taleplerin tablonun üst kısmında görünmesini istiyorsanız sıralama adımını da ekleyebilirsiniz. Ancak bunun için kullanılan sıralama ifadesinin, oluşturduğunuz Select çıktısının yapısıyla uyumlu olduğunu doğrulamanız gerekir.
Copilot lisansınız ve ilgili özelliklere erişiminiz varsa zamanlanmış prompt seçeneklerini de değerlendirebilirsiniz. Bununla birlikte, her hafta aynı alanların aynı formatta raporlanması gerekiyorsa açıkça tanımlanmış bir akış daha öngörülebilir bir çözüm sunabilir.
Bu senaryodan çıkarılabilecek sonuç: Otomasyon yalnızca veri toplamakla bitmiyor. Toplanan bilgiyi düzenli olarak görünür kılmak da sürecin önemli bir parçası.
Workflows kullanırken dikkat edilmesi gerekenler
Akışları oluşturmak kadar, zaman içinde güvenli ve sürdürülebilir biçimde çalışmaya devam etmelerini sağlamak da önemli. Kullanıma almadan önce şu noktaları kontrol etmekte fayda var:
- Servis hesabını değerlendirin. Akışların tek bir çalışanın hesabına bağlı kalması, hesap kapatıldığında veya yetkiler değiştiğinde sorun yaratabilir. Kurumunuzun politikalarına uygun bir sahiplik ve işletim modeli belirleyin.
- Webhook URL’sini istemci tarafında saklamayın. URL’nin JavaScript web resource gibi tarayıcıda görülebilen bir yerde bulunması, kötüye kullanım riskini artırır. Mümkün olduğunda çağrıyı sunucu tarafında gerçekleştirin.
- Mesajlarda hassas bilgileri paylaşmayın. Hukuk, finans ve benzeri gizlilik gerektiren alanlarda müvekkil veya müşteri ayrıntılarını Teams kartına taşımak yerine kayıt bağlantısı paylaşmayı tercih edin. Bağlantı üzerinden erişim de ilgili yetkilendirme kurallarına tabi olmalıdır.
- Eski bağlantıları kontrol edin. Daha önce kullanılan webhook adresleri ve entegrasyon yapılandırmaları yeni altyapıyla uyumlu olmayabilir. Kullanımdaki bağlantıların geçerliliğini doğrulayın.
- Kanal türünü test edin. Özel kanalların desteklenmesi, tenant yapılandırmasına ve kullanılan Workflows deneyimine göre değişebilir. Akışı kullanacağınız kanal türünde deneyin.
- Tetikleyici davranışını doğrulayın. Yeni mesajları belirli aralıklarla kontrol eden tetikleyiciler anlık tepki vermeyebilir. Gecikmenin önemli olduğu senaryolarda uygun tetikleyiciyi seçin.
- Asenkron plugin’in ağ erişimini kontrol edin. Dış bağlantı için gereken HTTPS ve TLS izinlerinin doğru sunucuda tanımlandığından emin olun.
- Çalışma geçmişini takip edin. Workflows içindeki Run history bölümü, başarısız adımları ve hata mesajlarını incelemek için ilk başvurulacak yerlerden biridir.
Sonuç
Teams Workflows, özellikle günlük bildirim ve takip adımlarını azaltmak isteyen ekipler için değerlendirilebilecek bir seçenek. On-premises Dynamics 365 ile bulutta çalışan Microsoft 365 hizmetlerini birlikte kullanan ortamlarda da belirli ihtiyaçlara yönelik çözümler üretmeye yardımcı olabilir.
Bu yazıda ele aldığımız üç senaryo farklı sorunlara odaklanıyor:
- CRM’deki yeni kayıtları Teams kanalına bildirmek
- Sohbetlerde gelen talepleri Planner görevlerine dönüştürmek
- Bekleyen işleri haftalık bir özetle görünür hâle getirmek
Her senaryonun kurumun altyapısına, lisanslarına, güvenlik politikalarına ve mevcut süreçlerine göre değerlendirilmesi gerekiyor. Küçük bir akışla başlamak, ihtiyacı doğrulamak ve ardından kapsamı genişletmek genellikle daha yönetilebilir bir yaklaşım.
Microsoft Teams ve Power Platform’un sunduğu otomasyon olanaklarını değerlendirirken, asıl hedefin yalnızca yeni bir akış oluşturmak değil, günlük işlerde gerçekten zaman kazandıran ve sürdürülebilir bir süreç kurmak olduğunu unutmamak gerekiyor.
Kaynak: Microsoft Learn — Create incoming webhooks with Workflows for Microsoft Teams.
Esenlikler.