Skip to content

Commit c99f1d9

Browse files
authored
Add an example with Typescript and ESM (line#795)
This change adds a sample project that is also tested in CI (Typescript + ESM).
1 parent c3a665a commit c99f1d9

File tree

7 files changed

+1558
-1
lines changed

7 files changed

+1558
-1
lines changed

.github/workflows/test.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,17 @@ jobs:
4646
run: export NODE_OPTIONS=--openssl-legacy-provider; npm run apidocs
4747
- name: Test building docs
4848
run: export NODE_OPTIONS=--openssl-legacy-provider; npm run docs:build
49-
- name: Test building examples
49+
- name: Test building examples (CJS)
5050
run: |
5151
cd examples/echo-bot-ts
5252
npm run build-sdk
5353
npm install
5454
npm run build
5555
cd -
56+
- name: Test building examples (ESM)
57+
run: |
58+
cd examples/echo-bot-ts-esm
59+
npm run build-sdk
60+
npm install
61+
npm run build
62+
cd -

examples/echo-bot-ts-esm/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Echo Bot for LINE using TypeScript and ESM
2+
3+
Welcome to this simple guide on how to create an Echo Bot for the LINE messaging platform using TypeScript and ECMAScript Modules (ESM).
4+
An Echo Bot is a basic bot that replies to a user's message with the same content.
5+
This tutorial will help you set up a LINE Echo Bot from scratch.
6+
7+
## Prerequisite
8+
9+
- Node.js version 18 or higher
10+
- You've created a channel in the LINE Developers Console, and got your channel access token and channel secret.
11+
- Read https://developers.line.biz/en/docs/messaging-api/getting-started/#using-console if you haven't done this yet.
12+
13+
## Installation
14+
15+
- Clone the repository.
16+
17+
```bash
18+
git clone https://github.com/line/line-bot-sdk-nodejs.git
19+
```
20+
21+
- Change directory to this example.
22+
23+
```bash
24+
cd line-bot-sdk-nodejs/examples/echo-bot-ts-esm
25+
```
26+
27+
- Install all dependencies.
28+
29+
```bash
30+
npm run build-sdk
31+
npm install
32+
```
33+
34+
- Set the following environment variables.
35+
36+
```bash
37+
export CHANNEL_ACCESS_TOKEN=<YOUR_CHANNEL_ACCESS_TOKEN>
38+
export CHANNEL_SECRET=<YOUR_CHANNEL_SECRET>
39+
export PORT=<YOUR_PORT>
40+
```
41+
42+
- Set up your webhook URL in your LINE Official Account to be in the following format. Don't forget to disable the greeting messages and auto-response messages for convenience.
43+
44+
```bash
45+
https://example.com/callback
46+
```
47+
48+
- Build the application.
49+
50+
```bash
51+
npm run build
52+
```
53+
54+
- Run the application.
55+
56+
```bash
57+
npm start
58+
```
59+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare global {
2+
namespace NodeJS {
3+
interface ProcessEnv {
4+
CHANNEL_ACCESS_TOKEN: string;
5+
CHANNEL_SECRET: string;
6+
PORT: string;
7+
}
8+
}
9+
}
10+
11+
export {};

examples/echo-bot-ts-esm/index.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Import all dependencies, mostly using destructuring for better view.
2+
import {
3+
ClientConfig,
4+
MessageAPIResponseBase,
5+
messagingApi,
6+
middleware,
7+
MiddlewareConfig,
8+
webhook,
9+
HTTPFetchError,
10+
} from '@line/bot-sdk';
11+
import express, {Application, Request, Response} from 'express';
12+
13+
// Setup all LINE client and Express configurations.
14+
const clientConfig: ClientConfig = {
15+
channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '',
16+
};
17+
18+
const middlewareConfig: MiddlewareConfig = {
19+
channelSecret: process.env.CHANNEL_SECRET || '',
20+
};
21+
22+
const PORT = process.env.PORT || 3000;
23+
24+
// Create a new LINE SDK client.
25+
const client = new messagingApi.MessagingApiClient(clientConfig);
26+
27+
// Create a new Express application.
28+
const app: Application = express();
29+
30+
const isTextEvent = (event: any): event is webhook.MessageEvent & { message: webhook.TextMessageContent } => {
31+
return event.type === 'message' && event.message && event.message.type === 'text';
32+
};
33+
34+
// Function handler to receive the text.
35+
const textEventHandler = async (event: webhook.Event): Promise<MessageAPIResponseBase | undefined> => {
36+
// Process all variables here.
37+
if (!isTextEvent(event)) {
38+
return;
39+
}
40+
41+
// Process all message related variables here.
42+
// Create a new message.
43+
// Reply to the user.
44+
await client.replyMessage({
45+
replyToken: event.replyToken as string,
46+
messages: [{
47+
type: 'text',
48+
text: event.message.text,
49+
}],
50+
});
51+
};
52+
53+
// Register the LINE middleware.
54+
// As an alternative, you could also pass the middleware in the route handler, which is what is used here.
55+
// app.use(middleware(middlewareConfig));
56+
57+
// Route handler to receive webhook events.
58+
// This route is used to receive connection tests.
59+
app.get(
60+
'/',
61+
async (_: Request, res: Response): Promise<Response> => {
62+
return res.status(200).json({
63+
status: 'success',
64+
message: 'Connected successfully!',
65+
});
66+
}
67+
);
68+
69+
// This route is used for the Webhook.
70+
app.post(
71+
'/callback',
72+
middleware(middlewareConfig),
73+
async (req: Request, res: Response): Promise<Response> => {
74+
const callbackRequest: webhook.CallbackRequest = req.body;
75+
const events: webhook.Event[] = callbackRequest.events!;
76+
77+
// Process all the received events asynchronously.
78+
const results = await Promise.all(
79+
events.map(async (event: webhook.Event) => {
80+
try {
81+
await textEventHandler(event);
82+
} catch (err: unknown) {
83+
if (err instanceof HTTPFetchError) {
84+
console.error(err.status);
85+
console.error(err.headers.get('x-line-request-id'));
86+
console.error(err.body);
87+
} else if (err instanceof Error) {
88+
console.error(err);
89+
}
90+
91+
// Return an error message.
92+
return res.status(500).json({
93+
status: 'error',
94+
});
95+
}
96+
})
97+
);
98+
99+
// Return a successful message.
100+
return res.status(200).json({
101+
status: 'success',
102+
results,
103+
});
104+
}
105+
);
106+
107+
// Create a server and listen to it.
108+
app.listen(PORT, () => {
109+
console.log(`Application is live and listening on port ${PORT}`);
110+
});

0 commit comments

Comments
 (0)