このプロジェクトは、LINE Notifyの代わりに利用できるボットを提供します。Node.jsを使用してLINE Messaging APIを利用してメッセージを送信します。
AWS LambdaまたはAzure Functionsをデプロイ先として使用します。
- エントリポイント
src/lambdahandler.ts: AWS Lambdaのエントリポイント。src/functions/HttpTrigger.ts: Azure Functionsのエントリポイント。src/cloudflareworker.ts: cloudflare workerのエントリポイント。
- メインロジック
src/core/LineNotifyMessengerApp.ts: LINE Messaging APIからのイベントやHTTPリクエストを処理するロジックを実装しています。src/services/groupService.ts: グループIDを管理するサービスクラスを定義しています。グループIDの保存や取得を行うメソッドが含まれています。src/services/httpResponseService.ts: HTTPレスポンスを生成するサービスクラスを定義しています。HTTPステータスコードやメッセージを指定してレスポンスを生成するメソッドが含まれています。src/services/messageService.ts: メッセージ送信のサービスクラスを定義しています。実際のメッセージの生成や送信を行うメソッドはlineServiceクラスに含まれます。src/handlers/requestHandler.ts: HTTPリクエストを処理するクラスを定義しています。
- 実行環境特有のロジック
src/handlers/lambdaHttpRequestHandler.ts: IHttpRequestHandlerを実装したクラス。AWS Lambda固有のロジックを実装しています。src/handlers/functionsHttpRequestHandler.ts: IHttpRequestHandlerを実装したクラス。Azure Functions固有のロジックを実装しています。src/handlers/cloudflareHttpRequestHandler.ts: IHttpRequestHandlerを実装したクラス。cloudflare worker固有のロジックを実装しています。
- LINE Messaging API関連
src/services/lineService.ts: LINE Messaging APIとのインタラクションを管理するサービスクラスを定義しています。メッセージの送信や受信を行うメソッドが含まれています。
- 画像保存
src/repositories/s3ImageStorage.ts: IImageStorageを実装したクラス。Amazon S3に画像をアップロードするサービスクラスを定義しています。src/repositories/blobStorage.ts: IImageStorageを実装したクラス。Azure Blob Storageに画像をアップロードするサービスクラスを定義しています。src/repositories/r2Storage.ts: IImageStorageを実装したクラス。cloudflare R2に画像をアップロードするサービスクラスを定義しています。
- 画像サイズ変更
src/utils/jimpImageProcessor.ts: IImageProcessorを実装したクラス。Jimpを使用して画像を処理するサービスクラスを定義しています。
- グループID保存
src/repositories/dynamoGroupRepository.ts: IGroupRepositoryを実装したクラス。Amazon DynamoDBにグループIDを保存するリポジトリクラスを定義しています。src/repositories/tableStorageGroupRepository.ts: IGroupRepositoryを実装したクラス。Azure Table StorageにグループIDを保存するリポジトリクラスを定義しています。
- 認証トークン
src/strategies/checkAuthorizationTokenStrategy.ts: ICheckAuthorizationTokenを実装したクラス。認証トークンの検証方法を提供するストラテジークラスを定義しています。環境変数から取得するDefaultCheckAuthorizationTokenStrategyが実装されていて、これがデフォルトで利用されます。他の手段で取得する場合はここで実装し、LineNotifyMessengerAppクラスのコンストラクタでDIします。
- 送信モード
src/strategies/sendModeStrategy.ts: ISendModeStrategyを実装したクラス。送信モードを取得する手段を提供するストラテジークラスを定義しています。環境変数から取得するEnvironmentSendModeStrategyが実装されていて、これがデフォルトで利用されます。他の手段で取得する場合はここで実装し、LineNotifyMessengerAppクラスのコンストラクタでDIします。
- IaC
bin/line-notify-messenger.ts: AWS CDKアプリケーションのエントリポイント。スタックを作成し、デプロイするための設定を行います。lib/lambda-stack.ts: AWSリソースを定義するCDKスタック。AWS Lambda関数の設定が記述されています。cdk.json: CDKアプリケーションの設定ファイル。アプリケーションのエントリポイントやスタックの設定を記述します。bicep/: Azureリソースを定義するBicepファイルを格納するディレクトリ。terraform/: cloudflareリソースを定義するTerraformファイルを格納するディレクトリ。
- その他
src/interfaces: インターフェースを定義するディレクトリ。functions/: Azure Functionsのプロジェクトファイルを格納するディレクトリ。tests/: テストファイルを格納するディレクトリ。Jestを使用してテストを実行します。tsconfig.json: TypeScriptのコンパイル設定を含むファイル。コンパイラオプションやコンパイル対象のファイルを指定します。package.json: npmの設定ファイル。プロジェクトの依存関係やスクリプトをリストしています。jest.config.js: Jestの設定ファイル。テストの設定を記述します。
-
LINE Messaging APIの設定を行い、チャンネルアクセストークン(長期)を取得してください
-
リポジトリをクローンします。
-
必要な依存関係をインストールします。
npm install
-
ビルドします
npm run build
AWS CloudShellで作業すると楽です。独自の環境で実施される場合は、Node.js(>=20)とAWS Cloud Development Kitをインストールしておいてください。
-
環境変数
LINE_CHANNEL_ACCESS_TOKENに、LINE Messaging APIのチャンネルアクセストークンを設定します。bashの場合
export LINE_CHANNEL_ACCESS_TOKEN='YOUR_CHANNEL_ACCESS_TOKEN'
PowerShellの場合
$Env:LINE_CHANNEL_ACCESS_TOKEN = 'YOUR_CHANNEL_ACCESS_TOKEN'
-
環境変数
AUTHORIZATION_TOKENに、これまで使っていたLINE NotifyのAuthorizationヘッダの値を設定します。bashの場合
export AUTHORIZATION_TOKEN='YOUR_AUTHORIZATION_TOKEN'
PowerShellの場合
$Env:AUTHORIZATION_TOKEN = 'YOUR_AUTHORIZATION_TOKEN'
-
AWS CDKを使用してスタックをデプロイします。
npm run deploy
-
複数のアプリケーションをデプロイする際は、CDKのスタック名にサフィックスをつけることができます。環境変数
APP_SUFFIXを設定できます。 bashの場合export APP_SUFFIX='xxxx'
PowerShellの場合
$Env:APP_SUFFIX = 'xxxx'
この場合、
npm run deployを実行すると、スタック名がLineNotifyMessengerS3Stack-xxxxとLineNotifyMessengerLambdaStack-xxxxになります。
GitHub Actionsでデプロイする場合は、以下のようにします。
cdk bootstrapコマンドを実行し、cdkの初期化を行います。- こちらを参考にデプロイに利用するIAMロールを作成して、そのARNを取得します。IAMロールには、以下のインラインポリシーをアタッチして下さい。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::{アカウントID}:role/cdk-hnb659fds-deploy-role-{アカウントID}-{リージョン名}",
"arn:aws:iam::{アカウントID}:role/cdk-hnb659fds-file-publishing-role-{アカウントID}-{リージョン名}",
"arn:aws:iam::{アカウントID}:role/cdk-hnb659fds-image-publishing-role-{アカウントID}-{リージョン名}",
"arn:aws:iam::{アカウントID}:role/cdk-hnb659fds-lookup-role-{アカウントID}-{リージョン名}"
]
}
]
}- AWS CDKのデプロイに必要な環境変数をリポジトリのSecretに設定します。
LINE_CHANNEL_ACCESS_TOKEN: LINE Messaging APIのチャンネルアクセストークンAUTHORIZATION_TOKEN: LINE NotifyのAuthorizationヘッダの値AWS_ROLE_ARN: 前の手順で作成した、デプロイ時に使用するIAMロールのARN。
- AWS CDKのデプロイに必要な環境変数をリポジトリの環境変数に設定します。
AWS_REGION: AWSリージョンSEND_MODE: 送信モードとしてgroupを設定しますAPP_SUFFIX: スタック名にサフィックスをつける場合は、任意のサフィックスを設定します
Deploy AWS LambdaワークフローをGitHubのページから手動で実行します。GitHubの公式ドキュメントを参照して下さい。
-
以下のボタンを押して環境を構築します。LINE_CHANNEL_ACCESS_TOKENとAUTHORIZATION_TOKENには、LINE Messaging APIのチャンネルアクセストークンと、これまで使っていたLINE NotifyのAuthorizationヘッダの値を設定します。
-
Azure Functions Core Toolsをインストールします
-
以下のコマンドを実行します
% cd functions
% func azure functionapp publish {作成したFunctions名}GitHub Actionsでデプロイする場合は、環境を構築したら以下を実行します。
-
本リポジトリをForkします。
-
構築した環境のAzure Functionsから発行プロファイルを取得して、ForkしたリポジトリのGitHub ActionsのSecret
AZURE_FUNCTIONAPP_PUBLISH_PROFILEに登録します。 -
同じくForkしたリポジトリのActionsのVariables
FUNCTION_NAMEに、Azure Functionsの関数名を登録します。 -
Build and deploy Node.js project to Azure Function AppワークフローをGitHubのページから手動で実行します。
Visual Studio Codeを使用している場合は、Azure Functionsの拡張機能でのデプロイも可能です。
-
Azure Functionsの拡張機能をインストールします
-
Azure Functionsの拡張機能を開き、Functionsを右クリックして「Deploy to Function App」を選択します
-
コマンドパレットから「Azure Functions: Deploy to Function App」を選択します
-
デプロイターゲットのディレクトリの指定で、
functionsディレクトリを選択します -
デプロイ先のサブスクリプションを選択します
-
先ほど作成したFunction Appを選択します
- LINE_CHANNEL_ACCESS_TOKENとAUTHORIZATION_TOKENとSEND_MODを環境変数に設定します。
- cloudflareのダッシュボードから、cloudflare R2を使えるようにします
- cloudflareのダッシュボードから、デプロイ用のAPIトークンを作成します
cd terraformでterraformディレクトリに移動します。terraform.tfvars.templateをコピーしてterraform.tfvarsを作成し、cloudflare_api_tokenとcloudflare_account_idを設定します。terraform initで初期化します。terraform applyでデプロイします。cd ../で元のディレクトリに戻ります。npm run update-configで設定ファイルを更新します。npm run cloudflare-buildでビルドします。npm run cloudflare-deployでデプロイします。- cloudflareのダッシュボードからシークレットにLINE_CHANNEL_ACCESS_TOKENとAUTHORIZATION_TOKENを設定します。
GitHub Actionsでデプロイする場合は、terraformでインフラを準備したら以下を実行します。
- KVのnamespace idとR2のバケット名をそれぞれリポジトリ変数
KV_NAMESPACE_IDとR2_BUCKET_NAMEに設定します。また、リポジトリ変数SEND_MODEに送信モードとしてgroupを設定します - リポジトリのシークレット
CLOUDFLARE_API_TOKENにAPI Tokenを設定します Deploy Cloudflare WorkerワークフローをGitHubのページから手動で実行します。
- デプロイしたボットのエンドポイント(AWS Lambdaの場合はcdkのOutputsで出てきたLambda関数URL、Azure Functionsの場合は {Funcitonsのホスト名}/api/HttpTrigger)を、LINE公式アカウントのWebhook URLに設定します。
- ボット自体は、何を受け付けても固定のメッセージを返します。
- {エンドポイントURL}/notify に対して、LINE Notifyと同じPOSTリクエストを送信すると、ボットのLINEアカウントのブロードキャストメッセージまたは所属グループへのメッセージとして送信されますので、LINE Notifyで使っていたURLを差し替えてそのまま動きます。この動作にはAuthorizationヘッダが必要です。
- デフォルトではBOTは友達全員に対してメッセージをブロードキャストします。ボットをグループに所属させても、そのグループに向かってメッセージは送信されません。これまでのLINE Notifyのようにグループに向かってメッセージを送信するには、AWS/Azureにデプロイしたバックエンドの環境変数「SEND_MODE」を「group」にします。
- グループ送信モードで使う場合は、ボットアカウントをグループに招待してください。既にボットがグループに入っている場合は、そのグループ内で適当なメッセージを送信してください。これにより、ボットが所属グループを記録し、そこにのメッセージを送信できるようになります。
- 公式アカウントを作成し、LINE Messaging APIのチャンネルアクセストークンを取得する
- 本ドキュメントに従ってデプロイし、Lambda/Functionsのエンドポイントを取得する
- Lambda/Functionsの環境変数「SEND_MODE」を「group」に設定する
- 公式アカウントにエンドポイントを設定する
- これまで使っていたLINE Notifyのグループに、作成した公式アカウントを招待する
- これまでLINE Notifyへ送っていたプログラムのURLを、
作成したエンドポイント/notifyに変更する