himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

XAML Rich Menu Maker を活かして C# で効率的な LINE Bot 開発

はじめに

LINE Bot を作る場合、コミュニティ製 の SDKC# で作ることができますが、「リッチメニュー」も C# で作ることができます。

XAML Rich Menu Maker

下記の記事にあるとおり、Visual Studio拡張機能でリッチメニューを XAML で組めます。

pierre3.hatenablog.com

Bot のバックエンドと同じソリューション内に作れば、リッチメニューの定義も Bot 本体と一緒に管理できるのでおすすめです。

アクションを C# で定義する

XAML Rich Menu Maker は C#XAML で構成されているため、Bot 本体とコードの共有ができます。

たとえば、リッチメニューではタップ時に Bot のバックエンドに Postback イベントとして data を送信することができますが、このデータを Bot 側で使用するモデルクラスと共通化することができ、かなり便利です。

サンプル

リッチメニューで動物の絵を並べ、それぞれ押すとその情報を送るような Bot を考えます。

動物のメニューをタップすると、その動物から鳴き声が返ってくるものです。

モデルクラス

Bot 本体、リッチメニューのプロジェクトのほか、Shared プロジェクトで C# のモデルクラスを用意します。

namespace RichMenuIntegrationSample.Models
{
    public class Animal
    {
        public string Name { get; set; }
        public string Sound { get; set; }
        public string IconFileName { get; set; }
    }
}

動物の名前、鳴き声、イラストのファイル名を持つことができるクラスですが、これを Bot 本体とリッチメニューのアクションでの data で共有します。

data の定義

XAML Rich Menu Maker のプロジェクト内で、共有のモデルクラスを使って JSON 化する静的なプロパティを持つクラスを定義します。

using Newtonsoft.Json;
using RichMenuIntegrationSample.Models;

namespace XamlRichMenuMaker.ActionData
{
    public static class AnimalAction
    {
        public static string Cat { get; } = JsonConvert.SerializeObject(new Animal
        {
            Name = "ねこ",
            Sound = "にゃーん",
            IconFileName = "cat.png"           
        });

        public static string Dog { get; } = JsonConvert.SerializeObject(new Animal
        {
            Name = "いぬ",
            Sound = "わんわん",
            IconFileName = "dog.png"
        });
    }
}

リッチメニューの定義

リッチメニューの定義で、この静的プロパティを x:Static でバインドします。

<Rectangle x:Name="area_1"
            Stroke="DarkGray" StrokeThickness="4">
    <local:RichMenuProperties.Action>
        <local:RichMenuAction Type="Postback"
            Label="ねこ"
            Data="{x:Static data:AnimalAction.Cat}"
            Text="ねこさん" />
        </local:RichMenuProperties.Action>
</Rectangle>

Bot のバックエンド

同じモデルクラスを使って、LINE Bot のバックエンドで処理させます。

今回、バックエンドは Azure Functions です(DI で Messaging API SDK を使うテンプレ構成)。

動物とその鳴き声ということで、新機能の icon / nickname switch も使ってみます。

C# SDK の対応と使い方については以下の記事参照↓
qiita.com

Postbackイベントを処理する部分(LineBotApp.cs)

protected override async Task OnPostbackAsync(PostbackEvent ev)
{
    // Postback で送信されたデータを共通のモデルクラスに変換
    var animal = JsonConvert.DeserializeObject<Animal>(ev.Postback.Data);

    // icon / nickname switch を使用して返信
    await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken, new List<ISendMessage>
    {
        new TextMessage(
            animal.Sound, null,
            new Sender(animal.Name, $"{Environment.GetEnvironmentVariable("ImageBaseUrl")}/{animal.IconFileName}"))
    });
}

送られてきたコードをモデルクラスにデシリアライズして、後続の処理を行います。
元々このクラスで定義しているので、C# の型に正しく変換される保証があり、安心です。

動作結果

こんなかんじ!

サンプルコード

動かすときは Azure Functions にデプロイして、環境変数の設定(ChannelAccessToken、ChannelSecret、ImageBaseUrl)をしてください。

github.com

Sender のアイコン画像は Blob Storage にでも置けばOK(公開URLのルートを ImageBaseUrl に設定する)。

また、事前にリッチメニューの登録も済ませておいてください。

まとめ

C# SDK を使えばいろいろ統一できてとても楽です!