Dokümanlar menüsü
Kanallar: Slack ve Telegram
Slack ya da Telegram'da bir ajan: mesaj bir kez çalışır, cevap bir kez gider, onay butonunu yalnızca soran kişi yanıtlar — Redis yok, kuyruk deponun kendisi.
Ne işe yarar / ne zaman kullanılır#
Ajanı ekibinizin ya da müşterilerinizin zaten konuştuğu yere koyun. @gnldev/channels platformun imzalı webhook'unu alır, her mesajı deponuzda kalıcı bir kuyruk işine çevirir, ajanı çalıştırır ve cevabı thread'e geri yazar.
Sohbet platformları tekrar gönderir: Slack cevap gecikince olayı yeniden yollar, Telegram 2xx alana kadar. Her teslimde ajanı çalıştıran bir bot iki kez cevap verir; daha kötüsü, araçlarını iki kez çalıştırır. Burada bir mesaj platformun ona verdiği kimlikle adlandırılır; tekrar teslim aynı iş ve aynı run'dır, cevap da her araç çağrısı gibi kayda geçen bir yan etkidir.
Slack#
slackChannel(config, opts) bir handle(request) döndürür — Slack uygulamanızın Event Subscriptions ve Interactivity adresine bağlayın — ve bir kuyruk işçisi başlatır. workspaces hangi çalışma alanlarının yanıtlanacağını ve her birinin hangi organizasyonda çalışacağını söyler; listede olmayan çalışma alanının mesajı alındı denip hiç çalıştırılmaz.
import { slackChannel } from '@gnldev/channels';
import { SqliteStorage } from '@gnldev/durable/sqlite';
const slack = slackChannel({ storage: new SqliteStorage('runs.db'), agents }, {
signingSecret: process.env.SLACK_SIGNING_SECRET!,
botToken: process.env.SLACK_BOT_TOKEN!,
agent: 'support',
workspaces: { T0123ABCD: { orgId: 'acme' } },
studioUrl: 'https://studio.acme.example',
});
// Event Subscriptions and Interactivity both point here:
export const handleSlack = (req: Request) => slack.handle(req);Bot olayları app_mention ve message.im; izinler app_mentions:read, chat:write, im:history, ve botun anıldığı kanallar için channels:history / groups:history (kopan bağlantıdan sonra cevap orada aranır). approvers, soran kişi dışında birinin onay vermesine izin verir.
Telegram#
telegramChannel(config, opts) bir bot için aynısıdır: setWebhook'u adresinize, secret_token = secretToken ile yönlendirin. chats hangi sohbetlerin yanıtlanacağını ve hangi organizasyonda çalışacağını söyler — bir bota onu bulan herkes yazabilir.
import { telegramChannel } from '@gnldev/channels';
const telegram = telegramChannel({ storage, agents }, {
botToken: process.env.TELEGRAM_BOT_TOKEN!,
secretToken: process.env.TELEGRAM_WEBHOOK_SECRET!, // the secret_token you give setWebhook
agent: 'support',
chats: (chat) => (chat.id === -1001234567890 ? { orgId: 'acme' } : undefined),
});
export const handleTelegram = (req: Request) => telegram.handle(req);Saklamadan söylenen tek fark: bir bot sohbet geçmişini okuyamaz, bu yüzden bağlantısı kopan bir cevabın gidip gitmediğine bakılamaz. Telegram'da cevap en fazla bir kez gider — belirsiz kalır, tekrar gönderilmez; Slack'te ise bulunur ya da gönderilir.
Neyi garanti eder#
- Yalnızca platform dinlenir. Slack: gövdeye ait imzası olmayan ya da beş dakikadan eski istek 401. Telegram: webhook'un gizli değerini taşımayan istek 401.
- Bir mesaj bir kez çalışır. Platformun mesaja verdiği kimlikle adlandırılan bir kuyruk işi (Slack'te olay kimliği; Telegram'da sohbet ve mesaj kimliği); run da aynı adı taşır, çökme sonrası yeniden denenen iş run'ı tekrar oynatır — araçlar ikinci kez çalışmaz. Ölçüldü: bir olayın altı teslimi, bir model çağrısı, bir cevap.
- Slack'te cevap bir kez gider. Gönderim tekrar anahtarını Slack mesaj metadata'sında taşır; yarıda kesilen gönderim thread okunarak çözülür — bulundu: gitmiş; bulunmadı: şimdi gider. İki yön de ölçüldü: her birinde tek mesaj.
- Herkesin konuşması kendinedir. GNL thread'i, platformun thread'i ve kişidir; iki kişinin paylaştığı bir thread'de hiçbir run diğerinin mesajını okumaz.
- Onay sohbetin içinde. Onay için duran bir run, her çağrı için Onayla / Reddet gönderir. Yalnızca soran kişi yanıtlayabilir (Slack'te ayrıca
approvers'ın izin verdiği kişi); Slack butonunun değeri imzalıdır, değiştirilen değer hiçbir şeye karar vermez; her çağrı için tek karar. Telegram'da soran kişi, butonların yanıt verdiği mesajdan okunur. - Platform cevabını hemen alır (Slack 3 sn içinde ister); ajan sonra kuyruk işçisinde çalışır — ayakta kalan bir süreçte, cevaptan sonra donan bir fonksiyonda değil.
API referansı#
slackChannel(config, { signingSecret, botToken, agent, workspaces, studioUrl?, approvers?, worker?, workerOptions? }) → { handle(req), worker(), close() }.
telegramChannel(config, { botToken, secretToken, agent, chats, studioUrl?, worker?, workerOptions? }) → { handle(req), worker(), close() }.
verifySlackSignature(rawBody, headers, signingSecret, nowMs) → boolean — Slack'in v0 imzası, sabit zamanlı karşılaştırma, beş dakika sınırı.
worker: false ve channel.worker().start()).