// re-exports export * from '@line/bot-sdk'; import './polyfill'; import { resolve } from 'path'; import * as express from 'express'; import * as getPort from 'get-port'; import * as clipboardy from 'clipboardy'; import { middleware, Client, WebhookEvent, Message } from '@line/bot-sdk'; import { args, script, config } from './opts'; import { createSender } from './sender'; import { ngrok } from './ngrok'; import * as keypress from './keypress'; import { ModuleLoader } from './moduleloader'; type KaedeContext = { client: Client; baseUrl: string | null; staticRoot: string; }; type KaedeHandler = (event: WebhookEvent, ctx: KaedeContext) => AsyncIterable; export async function main() { const app = express(); const ctx: KaedeContext = { client: new Client(config), baseUrl: null, staticRoot: resolve(args.static), }; const loader = new ModuleLoader(script); function reload() { loader.reload(); console.log('updated'); } keypress.on('enter', reload); keypress.on('return', reload); app.use(express.static(ctx.staticRoot)); app.post('*', middleware(config), (req, res) => { // early return res.end(); const events: Array = req.body.events; events.forEach(async event => { const sender = createSender(ctx.client, event); try { for await (const message of loader.content(event, ctx)) { await sender.send(message); } } catch (err) { console.error(err); } finally { await sender.flush(); } }); }); const port = await getPort(); await new Promise(resolve => app.listen(port, resolve)); ctx.baseUrl = await ngrok(port); console.log(`Listening at ${ctx.baseUrl}`); const baseUrlWithoutProtocol = ctx.baseUrl.split('//')[1]; // remove https:// await clipboardy.write(baseUrlWithoutProtocol); console.log(`${baseUrlWithoutProtocol} is copied to the clipboard\n`); keypress.init(); console.log('Press Enter/Return to reload the bot script'); console.log('Press Ctrl+C/D to quit'); }