From 4499482de9dfffc0bd65412c495e45570a75d6fb Mon Sep 17 00:00:00 2001 From: Yuta Kasai Date: Thu, 4 Apr 2024 17:50:59 +0900 Subject: [PATCH 1/3] NO-ISSUE keep --- docs/.vitepress/config.ts | 1 - docs/getting-started/basic-usage.md | 55 +- docs/guide/client.md | 11 +- docs/guide/webhook.md | 22 +- examples/echo-bot-esm/README.md | 32 ++ examples/echo-bot-esm/index.js | 51 ++ examples/echo-bot-esm/package-lock.json | 729 ++++++++++++++++++++++++ examples/echo-bot-esm/package.json | 15 + examples/echo-bot/index.js | 1 - 9 files changed, 874 insertions(+), 43 deletions(-) create mode 100644 examples/echo-bot-esm/README.md create mode 100644 examples/echo-bot-esm/index.js create mode 100644 examples/echo-bot-esm/package-lock.json create mode 100644 examples/echo-bot-esm/package.json diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index b44c7204f..84d0c2d2a 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -20,7 +20,6 @@ export default { { text: 'Guide', link: '/guide.html' }, { text: 'API Reference', link: '/apidocs/modules.html' }, { text: 'Contributing', link: '/CONTRIBUTING.html' }, - { text: 'LINE Developers', link: 'https://developers.line.biz/en/' }, { text: 'GitHub', link: 'https://github.com/line/line-bot-sdk-nodejs/' }, ], // Sidebar items diff --git a/docs/getting-started/basic-usage.md b/docs/getting-started/basic-usage.md index 37e4205b1..b0387e001 100644 --- a/docs/getting-started/basic-usage.md +++ b/docs/getting-started/basic-usage.md @@ -1,18 +1,18 @@ # Basic Usage It can be imported with [CommonJS](https://nodejs.org/docs/latest/api/modules.html), -[ES2015 modules](https://babeljs.io/learn-es2015/#ecmascript-2015-features-modules), +[ECMAScript modules(ES modules)](https://tc39.es/ecma262/#sec-modules), and preferably [TypeScript](https://www.typescriptlang.org/). The library is written in TypeScript and includes TypeScript definitions by default. Nevertheless, it can surely be used with plain JavaScript too. ``` js +// ES Modules or TypeScript +import * as line from '@line/bot-sdk'; + // CommonJS const line = require('@line/bot-sdk'); - -// ES2015 modules or TypeScript -import * as line from '@line/bot-sdk'; ``` ## Configuration @@ -26,7 +26,6 @@ new line.messagingApi.MessagingApiClient({ channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', }); line.middleware({ - channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', channelSecret: 'YOUR_CHANNEL_SECRET' }); ``` @@ -36,39 +35,57 @@ line.middleware({ Here is a synopsis of echoing webhook server with [Express](https://expressjs.com/): ``` js -const express = require('express'); -const line = require('@line/bot-sdk'); +import * as line from '@line/bot-sdk' +import express from 'express' +// create LINE SDK config from env variables const config = { - channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', - channelSecret: 'YOUR_CHANNEL_SECRET' + channelSecret: process.env.CHANNEL_SECRET, }; +// create LINE SDK client +const client = new line.messagingApi.MessagingApiClient({ + channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN +}); + +// create Express app +// about Express itself: https://expressjs.com/ const app = express(); -app.post('/webhook', line.middleware(config), (req, res) => { + +// register a webhook handler with middleware +// about the middleware, please refer to doc +app.post('/callback', line.middleware(config), (req, res) => { Promise .all(req.body.events.map(handleEvent)) - .then((result) => res.json(result)); + .then((result) => res.json(result)) + .catch((err) => { + console.error(err); + res.status(500).end(); + }); }); -const client = new line.messagingApi.MessagingApiClient({ - channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', -}); +// event handler function handleEvent(event) { if (event.type !== 'message' || event.message.type !== 'text') { + // ignore non-text-message event return Promise.resolve(null); } + // create an echoing text message + const echo = { type: 'text', text: event.message.text }; + + // use reply API return client.replyMessage({ replyToken: event.replyToken, - messages: [{ - type: 'text', - text: event.message.text - }], + messages: [echo], }); } -app.listen(3000); +// listen on port +const port = process.env.PORT || 3000; +app.listen(port, () => { + console.log(`listening on ${port}`); +}); ``` The full examples with comments can be found diff --git a/docs/guide/client.md b/docs/guide/client.md index 72576789d..9edf2b688 100644 --- a/docs/guide/client.md +++ b/docs/guide/client.md @@ -10,12 +10,15 @@ For type signatures of the methods, please refer to [its API reference](../apido The `MessagingApiClient` class is provided by the main module. ``` js -// CommonJS -const MessagingApiClient = require('@line/bot-sdk').messagingApi.MessagingApiClient; - -// ES6 modules or TypeScript +// ES modules or TypeScript import { messagingApi } from '@line/bot-sdk'; const { MessagingApiClient } = messagingApi; +// OR +import * as line from '@line/bot-sdk'; +const MessagingApiClient = line.messagingApi.MessagingApiClient; + +// CommonJS +const MessagingApiClient = require('@line/bot-sdk').messagingApi.MessagingApiClient; ``` To create a client instance: diff --git a/docs/guide/webhook.md b/docs/guide/webhook.md index c83968682..e4d0a655e 100644 --- a/docs/guide/webhook.md +++ b/docs/guide/webhook.md @@ -38,19 +38,6 @@ We skip the detailed guide for Express. If more information is needed about Express, please refer to its documentation. Here is an example of an HTTP server built with Express. - -``` js -const express = require('express') - -const app = express() - -app.post('/webhook', (req, res) => { - res.json({}) -}) - -app.listen(8080) -``` - The server above listens to 8080 and will response with an empty object for `POST /webhook`. We will add webhook functionality to this server. @@ -61,21 +48,20 @@ const middleware = require('@line/bot-sdk').middleware const app = express() const config = { - channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', channelSecret: 'YOUR_CHANNEL_SECRET' } app.post('/webhook', middleware(config), (req, res) => { - req.body.events // webhook event objects - req.body.destination // user ID of the bot (optional) + req.body.events // webhook event objects from LINE Platform + req.body.destination // user ID of the bot ... }) app.listen(8080) ``` -We have imported `middleware` from the package and make the Express app to use -the middleware. The middlware validates the request and parses webhook event +We have imported `middleware` from `@line/bot-sdk` and make the Express app to use +the middleware. The middleware validates the request and parses webhook event object. It embeds body-parser and parses them to objects. If you have a reason to use another body-parser separately for other routes, please keep in mind the followings. diff --git a/examples/echo-bot-esm/README.md b/examples/echo-bot-esm/README.md new file mode 100644 index 000000000..c827ab677 --- /dev/null +++ b/examples/echo-bot-esm/README.md @@ -0,0 +1,32 @@ +# Echo Bot + +An example LINE bot just to echo messages + +## How to use + +### Install deps + +``` shell +$ npm build-sdk +$ npm install +``` + +### Configuration + +``` shell +$ export CHANNEL_SECRET=YOUR_CHANNEL_SECRET +$ export CHANNEL_ACCESS_TOKEN=YOUR_CHANNEL_ACCESS_TOKEN +$ export PORT=1234 +``` + +### Run + +``` shell +$ node . +``` + +## Webhook URL + +``` +https://your.base.url/callback +``` diff --git a/examples/echo-bot-esm/index.js b/examples/echo-bot-esm/index.js new file mode 100644 index 000000000..309eac322 --- /dev/null +++ b/examples/echo-bot-esm/index.js @@ -0,0 +1,51 @@ +import * as line from '@line/bot-sdk' +import express from 'express' + +// create LINE SDK config from env variables +const config = { + channelSecret: process.env.CHANNEL_SECRET, +}; + +// create LINE SDK client +const client = new line.messagingApi.MessagingApiClient({ + channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN +}); + +// create Express app +// about Express itself: https://expressjs.com/ +const app = express(); + +// register a webhook handler with middleware +// about the middleware, please refer to doc +app.post('/callback', line.middleware(config), (req, res) => { + Promise + .all(req.body.events.map(handleEvent)) + .then((result) => res.json(result)) + .catch((err) => { + console.error(err); + res.status(500).end(); + }); +}); + +// event handler +function handleEvent(event) { + if (event.type !== 'message' || event.message.type !== 'text') { + // ignore non-text-message event + return Promise.resolve(null); + } + + // create an echoing text message + const echo = { type: 'text', text: event.message.text }; + + // use reply API + return client.replyMessage({ + replyToken: event.replyToken, + messages: [echo], + }); +} + +// listen on port +const port = process.env.PORT || 3000; +app.listen(port, () => { + console.log(`listening on ${port}`); +}); diff --git a/examples/echo-bot-esm/package-lock.json b/examples/echo-bot-esm/package-lock.json new file mode 100644 index 000000000..998c50e8b --- /dev/null +++ b/examples/echo-bot-esm/package-lock.json @@ -0,0 +1,729 @@ +{ + "name": "echo-bot-esm", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "echo-bot-esm", + "version": "0.0.0", + "dependencies": { + "@line/bot-sdk": "../../", + "express": "^4.17.3" + } + }, + "../..": { + "version": "__LINE_BOT_SDK_NODEJS_VERSION__", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^20.0.0" + }, + "devDependencies": { + "@types/express": "4.17.21", + "@types/finalhandler": "1.2.3", + "@types/mocha": "10.0.6", + "@vitest/coverage-v8": "^1.4.0", + "express": "4.19.2", + "finalhandler": "1.2.0", + "husky": "9.0.11", + "msw": "2.2.11", + "prettier": "3.2.5", + "ts-node": "10.9.2", + "typedoc": "^0.25.1", + "typedoc-plugin-markdown": "^3.16.0", + "typescript": "5.4.3", + "vite": "^5.2.7", + "vitepress": "^1.0.1", + "vitest": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "axios": "^1.0.0" + } + }, + "node_modules/@line/bot-sdk": { + "resolved": "../..", + "link": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/examples/echo-bot-esm/package.json b/examples/echo-bot-esm/package.json new file mode 100644 index 000000000..19f552988 --- /dev/null +++ b/examples/echo-bot-esm/package.json @@ -0,0 +1,15 @@ +{ + "name": "echo-bot-esm", + "version": "0.0.0", + "description": "An example LINE bot just to echo messages", + "main": "index.js", + "scripts": { + "build-sdk": "cd ../../; npm i; npm run build", + "start": "node ." + }, + "dependencies": { + "@line/bot-sdk": "../../", + "express": "^4.17.3" + }, + "type": "module" +} diff --git a/examples/echo-bot/index.js b/examples/echo-bot/index.js index eec2fc114..9afd80d07 100644 --- a/examples/echo-bot/index.js +++ b/examples/echo-bot/index.js @@ -5,7 +5,6 @@ const express = require('express'); // create LINE SDK config from env variables const config = { - channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN, channelSecret: process.env.CHANNEL_SECRET, }; From d9a4acd6ce55f38b2c6adb0d8e5b418265ce661b Mon Sep 17 00:00:00 2001 From: Yuta Kasai Date: Thu, 4 Apr 2024 17:59:42 +0900 Subject: [PATCH 2/3] NO-ISSUE use esm in examples --- docs/guide/webhook.md | 13 ++++--- examples/echo-bot-esm/index.js | 62 +++++++++++----------------------- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/docs/guide/webhook.md b/docs/guide/webhook.md index e4d0a655e..e567dd1a6 100644 --- a/docs/guide/webhook.md +++ b/docs/guide/webhook.md @@ -42,8 +42,8 @@ The server above listens to 8080 and will response with an empty object for `POST /webhook`. We will add webhook functionality to this server. ``` js -const express = require('express') -const middleware = require('@line/bot-sdk').middleware +import express from 'express' +import { middleware } from '@line/bot-sdk' const app = express() @@ -117,15 +117,12 @@ For type references of the errors, please refer to [the API reference](../apidoc The errors can be handled with [error middleware](https://github.com/senchalabs/connect#error-middleware). ``` js -const express = require('express') -const middleware = require('@line/bot-sdk').middleware -const JSONParseError = require('@line/bot-sdk').JSONParseError -const SignatureValidationFailed = require('@line/bot-sdk').SignatureValidationFailed +import express from 'express' +import {middleware, JSONParseError, SignatureValidationFailed} from '@line/bot-sdk' const app = express() const config = { - channelAccessToken: 'YOUR_CHANNEL_ACCESS_TOKEN', channelSecret: 'YOUR_CHANNEL_SECRET' } @@ -149,6 +146,8 @@ app.use((err, req, res, next) => { app.listen(8080) ``` +You can read other examples in [lien-bot-sdk-nodejs/examples](https://github.com/line/line-bot-sdk-nodejs/tree/master/examples) + ## HTTPS The webhook URL should have HTTPS protocol. There are several ways to build an diff --git a/examples/echo-bot-esm/index.js b/examples/echo-bot-esm/index.js index 309eac322..58b9dae89 100644 --- a/examples/echo-bot-esm/index.js +++ b/examples/echo-bot-esm/index.js @@ -1,51 +1,27 @@ -import * as line from '@line/bot-sdk' import express from 'express' +import {middleware, JSONParseError, SignatureValidationFailed} from '@line/bot-sdk' -// create LINE SDK config from env variables -const config = { - channelSecret: process.env.CHANNEL_SECRET, -}; +const app = express() -// create LINE SDK client -const client = new line.messagingApi.MessagingApiClient({ - channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN -}); +const config = { + channelSecret: 'YOUR_CHANNEL_SECRET' +} -// create Express app -// about Express itself: https://expressjs.com/ -const app = express(); +app.use(middleware(config)) -// register a webhook handler with middleware -// about the middleware, please refer to doc -app.post('/callback', line.middleware(config), (req, res) => { - Promise - .all(req.body.events.map(handleEvent)) - .then((result) => res.json(result)) - .catch((err) => { - console.error(err); - res.status(500).end(); - }); -}); +app.post('/webhook', (req, res) => { + res.json(req.body.events) // req.body will be webhook event object +}) -// event handler -function handleEvent(event) { - if (event.type !== 'message' || event.message.type !== 'text') { - // ignore non-text-message event - return Promise.resolve(null); +app.use((err, req, res, next) => { + if (err instanceof SignatureValidationFailed) { + res.status(401).send(err.signature) + return + } else if (err instanceof JSONParseError) { + res.status(400).send(err.raw) + return } + next(err) // will throw default 500 +}) - // create an echoing text message - const echo = { type: 'text', text: event.message.text }; - - // use reply API - return client.replyMessage({ - replyToken: event.replyToken, - messages: [echo], - }); -} - -// listen on port -const port = process.env.PORT || 3000; -app.listen(port, () => { - console.log(`listening on ${port}`); -}); +app.listen(8080) From 715293bc5dd4b4120c4b65f5c5800f348e5eb9c8 Mon Sep 17 00:00:00 2001 From: Yuta Kasai Date: Thu, 4 Apr 2024 18:04:08 +0900 Subject: [PATCH 3/3] NO-ISSUE fix --- examples/echo-bot-esm/README.md | 4 +- examples/echo-bot-esm/index.js | 62 +++++++++++++++++++++--------- examples/echo-bot-esm/package.json | 2 +- examples/echo-bot/README.md | 4 +- examples/echo-bot/package.json | 2 +- 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/examples/echo-bot-esm/README.md b/examples/echo-bot-esm/README.md index c827ab677..64f4161ec 100644 --- a/examples/echo-bot-esm/README.md +++ b/examples/echo-bot-esm/README.md @@ -1,6 +1,6 @@ -# Echo Bot +# Echo Bot (ES Modules) -An example LINE bot just to echo messages +An example LINE bot just to echo messages written in ES modules. ## How to use diff --git a/examples/echo-bot-esm/index.js b/examples/echo-bot-esm/index.js index 58b9dae89..309eac322 100644 --- a/examples/echo-bot-esm/index.js +++ b/examples/echo-bot-esm/index.js @@ -1,27 +1,51 @@ +import * as line from '@line/bot-sdk' import express from 'express' -import {middleware, JSONParseError, SignatureValidationFailed} from '@line/bot-sdk' - -const app = express() +// create LINE SDK config from env variables const config = { - channelSecret: 'YOUR_CHANNEL_SECRET' -} + channelSecret: process.env.CHANNEL_SECRET, +}; + +// create LINE SDK client +const client = new line.messagingApi.MessagingApiClient({ + channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN +}); -app.use(middleware(config)) +// create Express app +// about Express itself: https://expressjs.com/ +const app = express(); -app.post('/webhook', (req, res) => { - res.json(req.body.events) // req.body will be webhook event object -}) +// register a webhook handler with middleware +// about the middleware, please refer to doc +app.post('/callback', line.middleware(config), (req, res) => { + Promise + .all(req.body.events.map(handleEvent)) + .then((result) => res.json(result)) + .catch((err) => { + console.error(err); + res.status(500).end(); + }); +}); -app.use((err, req, res, next) => { - if (err instanceof SignatureValidationFailed) { - res.status(401).send(err.signature) - return - } else if (err instanceof JSONParseError) { - res.status(400).send(err.raw) - return +// event handler +function handleEvent(event) { + if (event.type !== 'message' || event.message.type !== 'text') { + // ignore non-text-message event + return Promise.resolve(null); } - next(err) // will throw default 500 -}) -app.listen(8080) + // create an echoing text message + const echo = { type: 'text', text: event.message.text }; + + // use reply API + return client.replyMessage({ + replyToken: event.replyToken, + messages: [echo], + }); +} + +// listen on port +const port = process.env.PORT || 3000; +app.listen(port, () => { + console.log(`listening on ${port}`); +}); diff --git a/examples/echo-bot-esm/package.json b/examples/echo-bot-esm/package.json index 19f552988..fd0985704 100644 --- a/examples/echo-bot-esm/package.json +++ b/examples/echo-bot-esm/package.json @@ -1,7 +1,7 @@ { "name": "echo-bot-esm", "version": "0.0.0", - "description": "An example LINE bot just to echo messages", + "description": "An example LINE bot just to echo messages written in ES modules", "main": "index.js", "scripts": { "build-sdk": "cd ../../; npm i; npm run build", diff --git a/examples/echo-bot/README.md b/examples/echo-bot/README.md index c827ab677..322ed5463 100644 --- a/examples/echo-bot/README.md +++ b/examples/echo-bot/README.md @@ -1,6 +1,6 @@ -# Echo Bot +# Echo Bot (CommonJS) -An example LINE bot just to echo messages +An example LINE bot just to echo messages written in CommonJS. ## How to use diff --git a/examples/echo-bot/package.json b/examples/echo-bot/package.json index ee6e299ae..0e3a6d2f5 100644 --- a/examples/echo-bot/package.json +++ b/examples/echo-bot/package.json @@ -1,7 +1,7 @@ { "name": "echo-bot", "version": "0.0.0", - "description": "An example LINE bot just to echo messages", + "description": "An example LINE bot just to echo messages written in CommonJS", "main": "index.js", "scripts": { "build-sdk": "cd ../../; npm i; npm run build",