20
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

本エントリはOSSのノーコード・ローコード開発ツール「プリザンター」 Advent Calendar 2024の9日目の記事です。

はじめに

この記事はプリザンターに独自のエンドポイントを追加するの続編となります。

今回は、前回ご紹介した拡張コントローラを使った例として、プリザンターにLINE BOTのwebhookのエンドポイントを実装してLINEと連携する方法について解説します。

LINEへの通知に必要なLINEのユーザーIDを取得するBOT

プリザンターの通知機能では、通知種別に「LINE」「LINEグループ」を指定することでLINEにPush通知を送信できます。

image.png

通知先のユーザー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」-「トンネルを作成...」を選択します

image.png

  • トンネルの種類:永続的、アクセス:公開用 として「OK」をクリック

image.png

  • デバッグ用のプリザンターをVisual Studioからデバッグ実行すると、下記の様に払い出されたトンネルURLでブラウザが立ち上がります

image.png

この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アカウントを友達登録します。

  1. LINE Developer コンソールでBOTアカウントを開き「Messaging API設定」タブに表示されるQRコードを確認します
  2. LINEアプリでQRコードを読み取り、友達登録します

登録が完了後、トークルームに下記のメッセージが送られて来れば成功です。
image.png

プリザンターから通知を受け取る

受け取ったメッセージに記載されているUserIDを使って、プリザンターから通知を受け取れるようにしてみましょう。

  1. 通知元となるテーブルの「テーブルの管理」画面を開き、「通知」タブで「新規作成」をクリックします
  2. 下記の設定を行います
    • 通知種別: LINE
    • アドレス:取得したLINEのUser ID
    • トークン: BOTアカウントのチャンネルアクセストークン

image.png

ここまで出来たら準備完了です。通知の設定をしたテーブルにレコードを作成してみましょう。
下記の様な通知が届いたら成功です!

image.png

拡張コントローラの実装

拡張コントローラの実装についても少し見てみましょう。

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して動かしてみてください!

20
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?