import { Client, WebhookEvent, Message } from '@line/bot-sdk'; export type Sender = { // send (or reply) message send: (message: Message) => Promise; // flush the reply message queue flush: () => Promise; }; // messages will be sent by replyMessage during this period const REPLY_TIMEOUT = 10 * 1000; function getSourceId(event: WebhookEvent): string { if (event.source.type === 'user') { return event.source.userId; } else if (event.source.type === 'group') { return event.source.groupId; } else if (event.source.type === 'room') { return event.source.roomId; } else { throw new Error('unreachable'); } } export function createSender(client: Client, event: WebhookEvent): Sender { const sourceId = getSourceId(event); const replyToken: string | undefined = (event as any).replyToken; if (replyToken) { // return replyable sender with replyMessage timeout let flushed = false; let messages: Array = []; const now = Date.now(); const sender: Sender = { async send(message) { if (flushed) { await client.pushMessage(sourceId, message); } else { messages.push(message); } }, async flush() { if (flushed) return; flushed = true; if (messages.length === 0) { return; } try { await client.replyMessage(replyToken, messages); } catch (err) { console.error(err); } finally { messages = []; } }, }; setTimeout(() => sender.flush(), REPLY_TIMEOUT); return sender; } else { // return trivial sender for non-replyable event return { send: message => client.pushMessage(sourceId, message), flush: () => Promise.resolve(), }; } }