# Microsoft Teams entegrasyonu

> Sorgu taleplerini bir Teams kanalında duyurun ve onayları HMAC ile doğrulanan aksiyon ucu üzerinden bağlayın.

- Dokümantasyon: Kılavuzlar
- Güncelleme: 2026-10-25
- Kaynak: https://queryproxy.com/tr/docs/teams-entegrasyonu/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Teams entegrasyonunun iki yarısı vardır: Workflows (ya da eski connector) webhook'u ile kanala
**duyurular** ve otomasyonunuzun (outgoing webhook ya da Power Automate akışı)
onaylamak/reddetmek için çağırabileceği bir **aksiyon ucu**.

## Duyurular

1. Teams kanalınız için bir **Workflows** (Power Automate) webhook'u oluşturun
   ve URL'sini kopyalayın. `*.powerplatform.com` ya da `*.logic.azure.com`
   üzerindeki bir URL Adaptive Card alır. Eski Office 365 connector URL'leri
   (`*.webhook.office.com`; `outlook.office.com` URL'si ise yalnızca o host'u
   `QUERYPROXY_CHAT_WEBHOOK_ALLOWED_HOSTS`'a ekledikten sonra) hâlâ MessageCard
   alır, ancak Microsoft Office 365 Connectors'ı emekliye ayırdı: [emeklilik
   duyurusu](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/)
   (14 Nisan 2026 güncellemesi), bunların 18-22 Mayıs 2026 arasındaki
   yaygınlaştırmadan sonra artık çalışmadığını söylüyor. Bir Workflows URL'si
   kullanın.
2. QueryProxy'de **ChatOps**'u açın; webhook URL'sini yapıştırın ve bir **HMAC
   secret** belirleyin (güçlü, rastgele bir dize — aşağıdaki aksiyon ucunda da
   aynı secret kullanılır). İkisi de şifreli saklanır. İlk kurulum secret'sız
   kaydedilemediği için bu adımı **bir sistem yöneticisi** yapar; sonrasında
   webhook URL'sini ve açık/kapalı bayrağını takımın DBA'leri güncellemeye devam
   eder. Webhook URL'si `https://` olmalı ve host'u izin
   listesinde bulunmalıdır (varsayılan olarak `hooks.slack.com`,
   `*.webhook.office.com`, `*.logic.azure.com` ve `*.powerplatform.com`; liste sohbet sağlayıcıları
   arasında ortaktır; `QUERYPROXY_CHAT_WEBHOOK_ALLOWED_HOSTS` ile genişletin).

> **Kırıcı değişiklik — signing secret'ı yalnızca sistem yöneticisi
> belirleyebilir.** DBA'ler webhook URL'sini ve enabled bayrağını yönetmeye devam
> eder ama secret'ı giremez ya da döndüremez; yönetici de mevcut bir secret'ı
> değiştirirken **yürürlükteki secret'ı ispat etmek zorundadır**. HMAC yalnızca
> "çağıran secret'ı biliyor" der, "şu kişi onayladı" demez — secret'ı kendi
> seçebilen bir DBA, kendi talebini bir meslektaşı adına onaylayıp denetim izine
> o kişinin adını yazdırabiliyordu. ChatOps'u zaten kurmuş kurulumlarda secret'ın
> yükseltmeden sonra bir kez döndürülmesi önerilir.
>
> Aynı gerekçeyle entegrasyonu **silmek de yalnızca sistem yöneticisinin
> işidir** — yeniden kurmak için gereken secret'ı ancak bir yönetici
> girebiliyor. DBA'in gündelik, geri alınabilir kontrolü **Enabled** bayrağını
> kapatıp kaydetmektir.

Yeni talepler; talep sahibi, bağlantı, ifade sayısı, SQL önizlemesi ve
**Review in QueryProxy** bağlantısıyla bir kart olarak yayınlanır. Önizleme 400
karakterde kesilir ve varsayılan olarak metin ve sayı literallerini `?` gösterir;
`QUERYPROXY_CHAT_INCLUDE_SQL` onu `full` ya da `none` yapar. Kararlar da
alındıkça kanala duyurulur.

Bir Workflows URL'sinde kart, bir olgu listesi (talep sahibi, bağlantı, ifadeler),
sabit genişlikli bir metin parçasındaki SQL önizlemesi (markdown olarak
ayrıştırılmaz, dolayısıyla `a*b, c*d` yazıldığı gibi gelir) ve bir **Open URL**
aksiyonu olan Adaptive Card 1.5'tir. Gövde, Workflows'un "post card" mesajıdır:
kart `attachments[0].content` içinde olmak üzere `type: message`.

> **Özel akışlar için kırıcı değişiklik.** MessageCard alanlarını (`title`,
> `summary`, `sections[0].facts`) okuyan, `logic.azure.com` URL'sindeki bir akış
> artık bunları boş okur. Adaptive Card'ı `attachments[0].content` içinden okuyun
> ya da gövdeyi olduğu gibi iletin. `queryproxy` zarfı değişmez ve üst düzeyde
> kalır.

Kart ayrıca, kanalda görünmeyen bir `queryproxy` zarfı taşır: otomasyonunuzun
aksiyon ucuna iletmesi gereken `request_id` ve `action_token` alanları buradadır.
MessageCard işleyicileri tanımadıkları üst düzey anahtarları yok saydığı için
token kanala serpilmez.

```json
{
  "queryproxy": { "request_id": 123, "action_token": "…" },
  "type": "message",
  "attachments": [{ "contentType": "application/vnd.microsoft.card.adaptive", "content": { "type": "AdaptiveCard", "version": "1.5" } }]
}
```

Eski bir connector URL'sinde aynı zarf `"type": "MessageCard"` yanında durur.

## Aksiyon ucu

Teams tarafındaki otomasyondan onaylamak/reddetmek için şu çağrıyı yapın:

```
POST https://queryproxy-sunucunuz/webhooks/teams/actions
X-QueryProxy-Timestamp: <unix saniye>
Authorization: HMAC <base64(HMAC_SHA256("{timestamp}:{raw_body}", secret))>
Content-Type: application/json
```

```json
{
  "action": "approve",
  "request_id": 123,
  "actor_id": "<AAD object id>",
  "token": "<kartın queryproxy.action_token değeri>",
  "reason": "opsiyonel — reject için kullanılır"
}
```

- `action` — `approve` ya da `reject`.
- `request_id` — duyuru kartındaki talep numarası.
- `actor_id` — onaylayanın Azure AD **object id**'si. QueryProxy bunu, bir
  yöneticinin **Teams & Users → Manage users** ekranında belirlediği **Teams ID** eşlemesi
  üzerinden bir kullanıcıya çözer (eşlenmemiş bir id `422` ile reddedilir); asla beyan
  edilen bir e-posta ile çözülmez. Çözülen kullanıcı ayrıca **entegrasyonun
  takımına üye** olmalıdır (admin bu kontrolden her zaman geçer); değilse istek
  `403` ile geri çevrilir ve politikaya hiç ulaşmaz. Webdeki kurallar aynen
  geçerlidir: kullanıcının talebin takımında DBA rolü olmalı ve kendi talebine
  karar verememelidir. Webde olduğu gibi admin'ler bu iki kuralı da aşabilir;
  kuralı aşan bir admin onayı denetim günlüğünde işaretlenir.
- `token` — **zorunlu.** Kartın `queryproxy` zarfındaki `action_token` değeri;
  o tek talebe bağlı, 24 saat ömürlü ve tek kullanımlıktır.
- `reason` — `reject` için opsiyonel; varsayılanı "Rejected via Teams by
  &lt;isim&gt;". `approve` için, onay bir yönetici **override**'ı olduğunda
  (onaylayan takımın DBA'si değil ya da kendi talebine karar veriyor) zorunludur:
  gerekçe (1 ile 1000 karakter) olmadan çağrı `422` ile reddedilir ve token
  harcanmaz. Gerekçe denetim günlüğüne kaydedilir.

> **Kırıcı değişiklik — `token` alanı olmadan çağrı kabul edilmez.** Aksiyon ucu
> bu sürümden itibaren her istekte geçerli bir aksiyon token'ı bekler;
> otomasyonlarınızı kartın `queryproxy` zarfındaki `action_token` değerini
> iletecek şekilde güncelleyin. Bu sürümden önce yayınlanmış kartlarda böyle bir
> token yoktur — o talepleri web arayüzünden karara bağlayın. Token'ı olmayan,
> süresi dolmuş ya da harcanmış bir çağrı `422` ile ve bilerek belirsiz bir mesajla döner.

İmza `"{timestamp}:{raw_body}"` üzerinden hesaplanır ([Slack](/tr/docs/slack-entegrasyonu/)
ile aynı zaman damgalı şema), base64 kodlu, `Authorization: HMAC …`
başlığında. Bir Power Automate akışı bu başlığı doğrudan hesaplayabilir.

HMAC anahtarı, saklandığı hâliyle secret'tır; **secret geçerli bir base64 ise**
QueryProxy onu çözer ve çözülmüş baytlarla imzalar (Teams outgoing webhook'larının
kullandığı kural). Salt alfanümerik dizgelerin çoğu geçerli base64'tür; bu
yüzden kendi tarafınızda çözülmüş baytlarla imzalayın — ya da secret'ın olduğu
gibi kullanılması için base64 alfabesi dışında bir karakter (`-` ya da `!`)
ekleyin.

## Güvenlik

- `X-QueryProxy-Timestamp` başlığı zorunludur ve sunucu saatine göre **±5
  dakika** içinde olmalıdır; böylece yakalanan bir istek sonradan yeniden
  oynatılamaz.
- Geçersiz ya da eksik HMAC (ya da eski/eksik zaman damgası) `401` döner ve
  hiçbir şeyi değiştirmez.
- Onaylayan **Teams ID** eşlemesiyle önceden bağlanmış ve entegrasyonun takımına
  üye (ya da admin) olmalıdır — paylaşılan secret tek başına rastgele bir
  kullanıcı adına işlem yapamaz.
- Tek kullanımlık aksiyon token'ı, çağrının QueryProxy'nin gerçekten yayınladığı
  bir kartı yanıtladığını gösterir ve yalnızca bir kez harcanabilir. Token,
  karar gerçekten kaydedildikten sonra yakılır; yetkilendirmeye takılan bir
  çağrı kartın tek hakkını harcamaz. HMAC tek başına yalnızca çağıranın paylaşılan
  secret'ı bildiğini kanıtlar, hangi kişinin işlem yaptığını değil; secret'ın
  yalnızca sistem yöneticisine ait olmasının nedeni de budur.
- Yanıtlar JSON'dur (`{"ok": true|false, "message": "…"}`); yetkilendirme
  hataları gerekçesiyle `403`, geçersiz token ya da bağlanmamış kimlik `422`,
  bilinmeyen ya da başka takıma ait bir `request_id` ise `404` döner.
- Uç, QueryProxy'deki her webhook gibi hız sınırlıdır.

## Hatırlatmalar ve süresi dolmuş düğmeler

`QUERYPROXY_PENDING_REMIND_AFTER` saat (varsayılan `4`) boyunca `pending` kalan
bir talep, kanal için ve portalda, yeni bir aksiyon token'ıyla bir hatırlatma
alır. Talepler asla zaman aşımına uğramaz. Süresi dolmuş bir token taşıyan karar
çağrısı, aksiyonun süresinin dolduğunu söyleyerek yanıt verir ve daha yeni mesaja
işaret eder.

> [Slack'teki](/tr/docs/slack-entegrasyonu/) gibi tam etkileşimli Adaptive Card
> düğmeleri bir Teams bot kaydı gerektirir ve yol haritasındadır; bugün
> Teams'ten onay akışını aksiyon ucu karşılar.
