Chapter 10 · Channels: Event Inbound Routing
Chapter goals: Understand Flue's Channels inbound event model, learn to receive验证 events from Slack/GitHub等外部平台, and route events into agent sessions via
dispatch(...).
10.1 What Is a Channel
A channel connects external services (Slack, GitHub, Stripe…) to your agents. It本质上是经过验证的 HTTP入口: each arriving投递 (delivery) is first verified for signature and身份, then the platform-native payload is handed to your code, which decides which agent session to route to.
Key design: inbound-only
Channels only负责 "coming in". Outbound calls (sending Slack messages, creating GitHub issues) stay in your application —写 them directly using the对应平台's own SDK. This boundary lets Flue avoid封装 all third-party APIs.
// src/channels/github.ts
// GitHub channel: receives webhooks and verifies来源
import { defineChannel } from '@flue/runtime';
export const githubChannel = defineChannel({
name: 'github',
// Platform identifier: Flue uses this to select the对应 signature verification logic
provider: 'github',
});10.2 Verification and Trust
"Verified events" are the核心承诺 of channels: not anyone POSTing a JSON triggers your agent. Take GitHub as an example — the standard做法 is to verify X-Hub-Signature-256:
// Manual webhook signature verification (understanding what the channel layer does internally)
import { createHmac } from 'node:crypto';
export function verifyGithubSignature(
rawBody: string,
signature: string | undefined,
secret: string,
): boolean {
if (!signature) return false;
// HMAC-SHA256 compute摘要
const expected =
'sha256=' +
createHmac('sha256', secret).update(rawBody).digest('hex');
// Constant-time comparison to prevent timing attacks
return signature === expected;
}Flue's channel layer standardizes this验证: you配置好密钥, and unverified deliveries never进入 your handler.
10.3 dispatch(...): Routing Events to Agents
After obtaining the verified native payload, use dispatch(...) to送 it into an agent's session:
// src/agents/triage.ts (excerpt)
'use agent';
import { useModel, useTool } from '@flue/runtime';
import { searchCode } from '../tools/github.ts';
export function Triage() {
useModel('anthropic/claude-sonnet-4-6');
useTool(searchCode);
return 'You are an issue triage assistant. Upon receiving a新 issue, judge the priority and give a结论.';
}// src/channels/route-github.ts
// Route GitHub webhook payloads to the Triage agent
import { dispatch } from '@flue/runtime';
import type { AgentHandle } from '@flue/runtime';
export async function onIssueOpened(
triage: AgentHandle,
event: { action: string; issue: { number: number; title: string; body?: string } },
) {
// Only care about the "issue opened" action
if (event.action !== 'opened') return;
await dispatch(triage, [
{
role: 'user',
content: `New GitHub issue #${event.issue.number}:
Title: ${event.issue.title}
Body: ${event.issue.body ?? '(none)'}
Please triage: judge the type, severity, and whether immediate fix is needed.`,
},
]);
}dispatch returns "accepted"而非 "completed" — the actual执行 is taken over by the runtime. This is the基础 of the Durability contract in Chapter 12.
10.4 The Complete Event-Driven链路
A Slack message从用户发出到 agent回应, passes through four stages:
① Slack sends event → ② Flue HTTP入口 verifies signature → ③ Your routing code dispatch() → ④ agent session executes10.5 Chapter Summary
- Channels are verified HTTP入站入口; they validate signatures before handing payloads to your code;
dispatch(agentHandle, messages)routes events into an agent's session; returns "accepted" not "completed";- Outbound calls stay in your application — use the平台's own SDK;
- The event-driven链路: platform event → verify → route → agent executes.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What is the core responsibility of a Channel in Flue?
2. What does dispatch() return?
3. Why does Flue not encapsulate all third-party outbound APIs in channels?
4. What happens to an event that fails signature verification?
🛠️ Hands-On Exercises
- Create a GitHub channel that routes
issues/openedevents to a Triage agent; verify the webhooksignature in a测试 endpoint. - Add a Slack channel; simulate an event with a wrong signature and confirm it is拒绝 at the channel层.
- Write a dispatch handler that logs the事件 payload before routing — verify the log shows the verified原生 structure.
Channels mastered. Next, Sandboxes:安全执行环境.