GNL 0.17: erken aşamada ve hızlı ilerliyor — API'ler sürümden sürüme değişebilirBize katıl

GNL
Dokümanlar menüsü
Core · Ücretsiz@gnldev/channels

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.

slack.ts
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.

telegram.ts
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ı#

fnslackChannel

(config, { signingSecret, botToken, agent, workspaces, studioUrl?, approvers?, worker?, workerOptions? }) → { handle(req), worker(), close() }.

fntelegramChannel

(config, { botToken, secretToken, agent, chats, studioUrl?, worker?, workerOptions? }) → { handle(req), worker(), close() }.

fnverifySlackSignature

(rawBody, headers, signingSecret, nowMs) → boolean — Slack'in v0 imzası, sabit zamanlı karşılaştırma, beş dakika sınırı.

Uzun yaşayan bir süreç gerekir
Ajan, webhook cevap verdikten sonra kuyruk işçisinde çalışır. Cevabı gönderince fonksiyonu donduran bir platformda run bir sonraki isteği bekler. İşçiyi bir sunucuda ya da konteynerde çalıştırın (başka yerde çalıştırmak için worker: false ve channel.worker().start()).