この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
AIソリューション部の平内(SIN)です。
サーバ側にAWS LambdaとAPI Gatewayを使用した、LINE Botの作り方(入門バージョン)が、下記の記事で公開されています。
今回は、こちらをAWS SAMとTypeScriptでやってみました。
すいません、特にヒネリがあるわけではありません。LINEデベロッパーコンソールでの、チャンネル設定などは、全て上記の記事をご参照下さい。
2 TypeScript
TypeScriptは、/srcの下で.tsを編集し、/dstの下に出力するようにしました。
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"alwaysStrict": true,// use strict;
"noUnusedLocals": true, // 未使用変数
"noUnusedParameters": true,// 未使用引数
"noImplicitAny": true, // 暗黙のAny
"allowUnreachableCode": false,// 到達しないコード
"allowUnusedLabels": false,// 到達しないラベル
"strictNullChecks": true,// null チェック
"noImplicitReturns": true,// 戻り値
"outDir": "./dst", // 出力ディレクトリ
"rootDir": "./src" // ソースディレクトリ
}
}
そして、ボットのコードが下記のとおりです。
index.ts
import * as Lambda from 'aws-lambda';
import * as Line from "@line/bot-sdk";
import * as Types from "@line/bot-sdk/lib/types";
const accessToken = process.env.ACCESS_TOKEN!;
const channelSecret = process.env.CHANNEL_SECRET!;
const config: Line.ClientConfig = {
channelAccessToken: accessToken,
channelSecret: channelSecret,
};
const client = new Line.Client(config);
async function eventHandler(event:Line.WebhookEvent): Promise<any> {
if (event.type !== 'message' || event.message.type !== 'text') {
return null;
}
const message: Types.Message = { type: "text", text: event.message.text + "ってか?" };
return client.replyMessage(event.replyToken, message);
}
export const handler: Lambda.APIGatewayProxyHandler = async (proxyEevent:Lambda.APIGatewayEvent, _context) => {
console.log(JSON.stringify(proxyEevent));
// 署名確認
const signature = proxyEevent.headers["X-Line-Signature"];
if (!Line.validateSignature(proxyEevent.body!, channelSecret, signature)) {
throw new Line.SignatureValidationFailed("signature validation failed", signature);
}
const body: Line.WebhookRequestBody = JSON.parse(proxyEevent.body!);
await Promise
.all(body.events.map( async event => eventHandler(event)))
.catch( err => {
console.error(err.Message);
return {
statusCode: 500,
body: "Error"
}
})
return {
statusCode: 200,
body: "OK"
}
}
3 AWS SAM
使用したテンプレートは、以下のとおりです。ACCESS_TOKENとCHANNEL_SECRETをLINE側のチャンネル設定からコピーするだけで、使い回せると思います。
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: line-bot-sample
Globals:
Function:
Timeout: 3
Environment:
Variables:
ACCESS_TOKEN: xxxxxx
CHANNEL_SECRET: xxxxxxx
Resources:
LINEBotSampleFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: dst/
Handler: index.handler
Runtime: nodejs10.x
Events:
LINEBotSample:
Type: Api
Properties:
Path: /
Method: post
Outputs:
LINEBotSampleApi:
Description: "API Gateway endpoint URL for Prod stage for LINE Bot Sample function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
LINEBotSampleFunction:
Description: "LINE Bot Sample Lambda Function ARN"
Value: !GetAtt LINEBotSampleFunction.Arn
LINEBotSampleFunctionIamRole:
Description: "Implicit IAM Role created for LINE Bot Sample function"
Value: !GetAtt LINEBotSampleFunctionRole.Arn
使用したバケットは、aws-sam-template-bucketとなってます。(これは、使いまわせません・・・)
$ aws s3 mb s3://aws-sam-template-bucket
$ sam package --output-template-file packaged.yaml --s3-bucket aws-sam-template-bucket
$ sam deploy --template-file packaged.yaml --stack-name line-bot-sample --capabilities CAPABILITY_IAM
デプロイが完了後、CloudFormationの出力から、LINEBotSampleApiの値をコピーして、LINE側のWebhook URLに設定します。
4 動作確認
動作している様子です。単純にオウム返ししているだけです。
5 最後に
今回は、Lambda+API GatewayによるLINEボットの超簡単なサンプルを試してみましちた。
LINEも色々な機能が満載です。このTypeScriptサンプルとTemplateを使いまわして、頑張って勉強してみたいと思います。