feat(telegram): implement sendPayload for channelData support

Add sendPayload handler to Telegram outbound adapter to support
channel-specific data via the channelData pattern. This enables
features like inline keyboard buttons without custom ReplyPayload fields.

Implementation:
- Extract telegram.buttons from payload.channelData
- Pass buttons to sendMessageTelegram (already supports this)
- Follows existing sendText/sendMedia patterns
- Completes optional ChannelOutboundAdapter.sendPayload interface

This enables plugins to send Telegram-specific features (buttons, etc.)
using the standard channelData envelope pattern instead of custom fields.

Related: delivery system in src/infra/outbound/deliver.ts:324 already
checks for sendPayload handler and routes accordingly.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Joshua Mitchell
2026-01-25 13:26:37 -06:00
committed by Ayaan Zaidi
parent c01cc61f9a
commit ce60c6db1b

View File

@@ -50,4 +50,24 @@ export const telegramOutbound: ChannelOutboundAdapter = {
});
return { channel: "telegram", ...result };
},
sendPayload: async ({ to, payload, accountId, deps, replyToId, threadId }) => {
const send = deps?.sendTelegram ?? sendMessageTelegram;
const replyToMessageId = parseReplyToMessageId(replyToId);
const messageThreadId = parseThreadId(threadId);
// Extract Telegram-specific data from channelData
const telegramData = payload.channelData?.telegram as
| { buttons?: Array<Array<{ text: string; callback_data: string }>> }
| undefined;
const result = await send(to, payload.text ?? "", {
verbose: false,
textMode: "html",
messageThreadId,
replyToMessageId,
accountId: accountId ?? undefined,
buttons: telegramData?.buttons,
});
return { channel: "telegram", ...result };
},
};