本エントリはOSSのノーコード・ローコード開発ツール「プリザンター」 Advent Calendar 2024の9日目の記事です。
はじめに
この記事はプリザンターに独自のエンドポイントを追加するの続編となります。
今回は、前回ご紹介した拡張コントローラを使った例として、プリザンターにLINE BOTのwebhookのエンドポイントを実装してLINEと連携する方法について解説します。
LINEへの通知に必要なLINEのユーザーIDを取得するBOT
プリザンターの通知機能では、通知種別に「LINE」「LINEグループ」を指定することでLINEにPush通知を送信できます。
通知先のユーザーIDを取得する方法
アドレス欄にはLINEのユーザーIDを指定する必要がありますが、取得するにはLINE BOT用のサーバーを用意してWebhookからユーザーIDを取得する必要があります。
WebhookはAWS LambdaやAzure Functionsなどのクラウドサービスに用意しても良いですが、ユーザーIDを取得するためだけに使うには少々大袈裟です。
そこで、拡張コントローラを使ってプリザンターにWebhookのエンドポイントを生やしてしまおう!という訳です。
事前準備
LINE Messaging APIを準備する
LINEの公式ドキュメントを参考に、LINE公式アカウントの作成とMessaging APIの利用設定を実施しておきます。
Webhook URLの設定
「ボットを作成する」の手順では、WebhookのURLを指定する必要があります。
ここではサービス(プリザンター)のWebhook用に追加したURLを指定しますが、開発時はVisual Studionの開発トンネルを使うと便利です。
開発者トンネルの利用
- デバッグ用のプリザンターをVisual Studioで開き、デバッグ実行用のドロップダウンボタン(下図参照)で表示されるメニューから「Dev Tunnels」-「トンネルを作成...」を選択します
- トンネルの種類:永続的、アクセス:公開用 として「OK」をクリック
- デバッグ用のプリザンターをVisual Studioからデバッグ実行すると、下記の様に払い出されたトンネルURLでブラウザが立ち上がります
このURLのパスをLINE webhook用のエンドポイント /webhook/line
に変更したものをLINE DeveloperコンソールのWebhook URLに設定します。
- 例:
https://35t2b8b8-59802.asse.devtunnels.ms/webhook/line
サンプルを試してみよう
前回の記事でCloneしてきたPleasanterWebHookのプロジェクトをVisual Studioで開きます。
LINE BOTアカウントのチャンネル情報を設定
プロジェクト内にあるwebhooksettings.json
を開き、作成したLINE BOTアカウントのChannelAccessTokenとChannnelSecretを設定します。
{
"LineChannelSecret": "fda50xxxxxxxxxxxxxxxxxxxxxxxxxx",
"LineChannelAccessToken": "W66U66Idu5UMZTxxxxxxxxxxxxxxxxxxxx"
}
拡張コントローラの再配置
- PleasanterWebHookのプロジェクトをビルドします
- ビルドしたモジュールをデバッグ用プリザンター側に再度「公開」します(公開の手順、公開先などの設定は前回の記事と同様です)
プリザンターの実行
- デバッグ用プリザンターを開発者トンネルを有効にしてデバッグ実行します
LINE BOTアカウントを友達登録する
LINEアプリがインストールされている端末でLINE BOTアカウントを友達登録します。
- LINE Developer コンソールでBOTアカウントを開き「Messaging API設定」タブに表示されるQRコードを確認します
- LINEアプリでQRコードを読み取り、友達登録します
登録が完了後、トークルームに下記のメッセージが送られて来れば成功です。
プリザンターから通知を受け取る
受け取ったメッセージに記載されているUserIDを使って、プリザンターから通知を受け取れるようにしてみましょう。
- 通知元となるテーブルの「テーブルの管理」画面を開き、「通知」タブで「新規作成」をクリックします
- 下記の設定を行います
- 通知種別: LINE
- アドレス:取得したLINEのUser ID
- トークン: BOTアカウントのチャンネルアクセストークン
ここまで出来たら準備完了です。通知の設定をしたテーブルにレコードを作成してみましょう。
下記の様な通知が届いたら成功です!
拡張コントローラの実装
拡張コントローラの実装についても少し見てみましょう。
LINEのWebhookの処理には、LINE Messaging APIのC#ライブラリ LineDC.Messaging を利用しています。
ソースコード
全体のソースコードは下記をご確認ください。
LineBotAppの生成
WebHookController
クラスの静的コンストラクタ内でLINE BOTの処理を行うクラスLineBotApp
を生成しています。
-
webhooksettings.json
ファイルからLINEのチャンネルアクセストークンとチャンネルシークレットの値を取得 - その値を基に、
LineBotApp
のインスタンスを作成し、WebHookController
クラスの静的フィールドに設定
private static readonly LineBotApp _app;
static WebHookController()
{
//webhooksettings.jsonからLINEの設定情報を取得
var dir = Path.GetDirectoryName(typeof(WebHookController).Assembly.Location)
?? AppContext.BaseDirectory;
var netcoreEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")?.ToLower() ?? "";
var settingsPath = Path.Combine(dir, "webhooksettings.json");
var devSettingsPath = Path.Combine(dir, $"webhooksettings.{netcoreEnv}.json");
var confBuilder = new ConfigurationBuilder();
if (System.IO.File.Exists(settingsPath))
{
confBuilder.AddJsonFile(settingsPath);
}
if (System.IO.File.Exists(devSettingsPath))
{
confBuilder.AddJsonFile(devSettingsPath);
}
var config = confBuilder.Build();
var settings = config.Get<WebhookSettings>()
?? new WebhookSettings();
//設定情報を元に、LINE Messaging APIを処理するLineBotAppクラスを生成
var lineClient = LineMessagingClient.Create(new HttpClient(), settings.LineChannelAccessToken);
_app = new LineBotApp(lineClient, settings.LineChannelSecret);
}
コントローラのActionを定義
Webhook用のエンドポイント/webhook/line
用のメソッドをWebHookController
内に定義します。
- ここでは、Webhookの処理を実行する
LineBotApp
のメソッドRunAsync()
を呼び出すだけです - その際、署名検証用のシグネチャをヘッダから取得して渡します
//POST: /webhook/line
[HttpPost("line")]
public async Task<IActionResult> Line()
{
//LINE BOTのイベントを処理する
var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var xLineSignature = Request.Headers["x-line-signature"];
await _app.RunAsync(xLineSignature, body);
return Ok();
}
LineBotApp
の実装
受け取ったメッセージの処理はWebhookApplication
クラスを継承したLineBotApp
に実装しています。
メッセージは発生状況に応じたWebhookのイベントタイプに分類されます。LineBotApp
では、応答を返したいイベントに対応したメソッドをオーバーライドして処理を実装します。
今回は、送信元の情報からユーザーIDやグループIDを取得して、その値を返答する処理となります。
class LineBotApp : WebhookApplication
{
public LineBotApp(ILineMessagingClient client, string channelSecret)
: base(client, channelSecret)
{ }
//BOTアカウントがチャットルームやグループに追加された場合に実行されるイベント
protected async override Task OnJoinAsync(JoinEvent ev)
{
await ReplyIDAsync(ev);
}
//BOTアカウントを友達追加した場合に実行されるイベント
protected async override Task OnFollowAsync(FollowEvent ev)
{
await ReplyIDAsync(ev);
}
//ユーザからのメッセージを受信した際に実行されるイベント
protected override async Task OnMessageAsync(MessageEvent ev)
{
await Client.ReplyMessageAsync(ev.ReplyToken, $"あなたのユーザIDは \"{ev.Source.UserId}\" です。");
}
//送信元に応じてIDをリプライする関数
private async Task ReplyIDAsync(ReplyableEvent ev)
{
await Client.ReplyMessageAsync(ev.ReplyToken, ev.Source.Type switch
{
EventSourceType.Group => $$"""
ようこそ!このグループのIDはこちらです。
Group ID: {{ev.Source.Id}}
""",
EventSourceType.Room => $$"""
ようこそ!このトークルームのIDはこちらです。
Room ID: {{ev.Source.Id}}
""",
_ => $$"""
ようこそ!あなたのIDはこちらです。
User ID: {{ev.Source.UserId}}
"""
});
}
}
おわりに
今回は、LINEのユーザID/グループIDを取得するだけの機能でしたが、プリザンター内のデータと連携したBOTサービスなども作れそうですね。
この記事で取り上げたサンプルコードはGitHub上で公開していますので、ぜひ一度Cloneして動かしてみてください!