Skip to content

Commit

Permalink
03 Add ESM test project
Browse files Browse the repository at this point in the history
  • Loading branch information
Yang-33 committed Apr 1, 2024
1 parent fb798c5 commit 2375da6
Show file tree
Hide file tree
Showing 8 changed files with 1,621 additions and 1 deletion.
9 changes: 8 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,17 @@ jobs:
run: export NODE_OPTIONS=--openssl-legacy-provider; npm run apidocs
- name: Test building docs
run: export NODE_OPTIONS=--openssl-legacy-provider; npm run docs:build
- name: Test building examples
- name: Test building examples (CJS)
run: |
cd examples/echo-bot-ts
npm run build-sdk
npm install
npm run build
cd -
- name: Test building examples (ESM)
run: |
cd examples/echo-bot-ts-esm
npm run build-sdk
npm install
npm run build
cd -
5 changes: 5 additions & 0 deletions examples/echo-bot-ts-esm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Dependencies
node_modules/

# Built files.
dist/
57 changes: 57 additions & 0 deletions examples/echo-bot-ts-esm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# LINE Echo Bot with TypeScript (ESM)

An example LINE bot to echo message with TypeScript. The bot is coded according to TypeScript's best practices.

## Prerequisite

- Git
- Node.js version 10 and up
- LINE Developers Account for the bot

## Installation

- Clone the repository.

```bash
git clone https://github.com/line/line-bot-sdk-nodejs.git
```

- Change directory to the example.

```bash
cd line-bot-sdk-nodejs/examples/echo-bot-ts
```

- Install all dependencies.

```bash
npm run build-sdk
npm install
```

- Configure all the environment variables.

```bash
export CHANNEL_ACCESS_TOKEN=<YOUR_CHANNEL_ACCESS_TOKEN>
export CHANNEL_SECRET=<YOUR_CHANNEL_SECRET>
export PORT=<YOUR_PORT>
```

- 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.

```bash
https://example.com/callback
```

- Compile the TypeScript files.

```bash
npm run build
```

- Run the application.

```bash
npm start
```

11 changes: 11 additions & 0 deletions examples/echo-bot-ts-esm/environment.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare global {
namespace NodeJS {
interface ProcessEnv {
CHANNEL_ACCESS_TOKEN: string;
CHANNEL_SECRET: string;
PORT: string;
}
}
}

export {};
111 changes: 111 additions & 0 deletions examples/echo-bot-ts-esm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Import all dependencies, mostly using destructuring for better view.
import {
ClientConfig,
MessageAPIResponseBase,
messagingApi,
middleware,
MiddlewareConfig,
webhook,
HTTPFetchError,
} from '@line/bot-sdk';
import express, {Application, Request, Response} from 'express';

// Setup all LINE client and Express configurations.
const clientConfig: ClientConfig = {
channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '',
};

const middlewareConfig: MiddlewareConfig = {
channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
channelSecret: process.env.CHANNEL_SECRET || '',
};

const PORT = process.env.PORT || 3000;

// Create a new LINE SDK client.
const client = new messagingApi.MessagingApiClient(clientConfig);

// Create a new Express application.
const app: Application = express();

const isTextEvent = (event: any): event is webhook.MessageEvent & { message: webhook.TextMessageContent } => {
return event.type === 'message' && event.message && event.message.type === 'text';
};

// Function handler to receive the text.
const textEventHandler = async (event: webhook.Event): Promise<MessageAPIResponseBase | undefined> => {
// Process all variables here.
if (!isTextEvent(event)) {
return;
}

// Process all message related variables here.
// Create a new message.
// Reply to the user.
await client.replyMessage({
replyToken: event.replyToken as string,
messages: [{
type: 'text',
text: event.message.text,
}],
});
};

// Register the LINE middleware.
// As an alternative, you could also pass the middleware in the route handler, which is what is used here.
// app.use(middleware(middlewareConfig));

// Route handler to receive webhook events.
// This route is used to receive connection tests.
app.get(
'/',
async (_: Request, res: Response): Promise<Response> => {
return res.status(200).json({
status: 'success',
message: 'Connected successfully!',
});
}
);

// This route is used for the Webhook.
app.post(
'/callback',
middleware(middlewareConfig),
async (req: Request, res: Response): Promise<Response> => {
const callbackRequest: webhook.CallbackRequest = req.body;
const events: webhook.Event[] = callbackRequest.events!;

// Process all the received events asynchronously.
const results = await Promise.all(
events.map(async (event: webhook.Event) => {
try {
await textEventHandler(event);
} catch (err: unknown) {
if (err instanceof HTTPFetchError) {
console.error(err.status);
console.error(err.headers.get('x-line-request-id'));
console.error(err.body);
} else if (err instanceof Error) {
console.error(err);
}

// Return an error message.
return res.status(500).json({
status: 'error',
});
}
})
);

// Return a successful message.
return res.status(200).json({
status: 'success',
results,
});
}
);

// Create a server and listen to it.
app.listen(PORT, () => {
console.log(`Application is live and listening on port ${PORT}`);
});
Loading

0 comments on commit 2375da6

Please sign in to comment.