LoginSignup
4

More than 3 years have passed since last update.

[LINE] For C#er (ASP.NET Core), Line Botの作成 - Part 1 - メッセージの受信

Last updated at Posted at 2019-09-14

本日はLINE APIを使ってLINE BOTを構築します。

LINEユーザーからのメッセージはWebhook経由で受信します。Azure Functionsを使ってこのWebhookを受け取り、返信をする仕組みを作ってみます。

Azure環境の構築

Azure Functionsを構築します。こちらのドキュメントを参照ください。もしくはこちらの過去記事「Azure Functions - とりあえず立ち上げて公開

Line Channelの準備など

オフィシャルアカウント

次にチャンネル(LINEオフィシャルアカウント)の準備をします。こちらのドキュメントをご参照ください。

アクセストークン、Webhook Url

オフィシャルアカウントを開設したあとは、設定よりアクセストークンとWebhook URLの設定を行います。こちらのドキュメントをご参照ください。

こちらの準備ができたら、オフィシャルアカウントを友達登録し、さっそく構築へと進みます。

メッセージの受信 (Webhookの受信)

Webhookにはリクエストヘッダーとボディーがあり、下記の情報がLINEから送られてきます。

リクエストヘッダー 説明
X-Line-Signature 署名の検証に使う署名
プロパティ タイプ 説明
destination String Webhookイベントを受信すべきボットのユーザーID。ユーザーIDの値は、U[0-9a-f]{32}の正規表現にマッチする文字列です。
events Webhookイベントオブジェクトの配列 イベントの情報

レスポンス例

レスポンス例はこちら

{
  "destination": "xxxxxxxxxx", 
  "events": [
    {
      "replyToken": "0f3779fba3b349968c5d07db31eab56f",
      "type": "message",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world"
      }
    },
    {
      "replyToken": "8cf9239d56244f4197887e939187e19e",
      "type": "follow",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      }
    }
  ]
}

このレスポンスをC#のオブジェクトで受け取るためにはjson2csharpeを使います。JSONレスポンスデータをコピペするだけでC#のモデルを生成してくれます。
http://json2csharp.com/

結果はこちらです。

public class Source
{
    public string type { get; set; }
    public string userId { get; set; }
}

public class Message
{
    public string id { get; set; }
    public string type { get; set; }
    public string text { get; set; }
}

public class Event
{
    public string replyToken { get; set; }
    public string type { get; set; }
    public object timestamp { get; set; }
    public Source source { get; set; }
    public Message message { get; set; }
}

public class RootObject
{
    public string destination { get; set; }
    public List<Event> events { get; set; }
}

RootObjectではわかりずらいので、RootObjectineWebhookMessageObjectに変更します。

このモデルを使って送信されてきたテキストをLogに表示をしてみます。

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using LineApiApp.Models;

namespace LineApiApp
{
   public class LineReply
    {
        [FunctionName("ReplyToMessage")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous,"post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("Req: " + req.Body.ToString());

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

            var data = JsonConvert.DeserializeObject<LineWebhookMessageObject>(requestBody);

            log.LogInformation("Message is : " + data.events[0].message.text);

            return new OkResult();
        }
    }
}

結果

LINEでメッセージを送信
image.png

FunctionsのLogsを確認
image.png

参考ドキュメント
https://developers.line.biz/ja/reference/messaging-api/#anchor-46a7f4db6a6b07848d6f7dd012f053442547ccc5

LINEからのリクエスト!?

公開されてないとは言え、Webhookを受け取るためのAPIはネット上にあるため、先ほど受けとったWebhookが本物かどうか確認をする必要があります。

そのためにすべてのWebhook HeaderにはX-Line-Signatureという値が渡されます。この値を、HMAC-SHA256アルゴリズムを使用してリクエストボディのダイジェスト値を取得し、ダイジェスト値をBase64エンコードした値とリクエストヘッダーにある署名が一致することを確認します。

下記が確認コードになります。

 /// <summary>
 /// Return if signature matches
 /// </summary>
 /// <param name="signature"></param>
 /// <param name="text"></param>
 /// <param name="key"></param>
 /// <returns></returns>
 private bool IsSingatureOk(string signature, string text, string key)
 {
   var textBytes = Encoding.UTF8.GetBytes(text);
   var keyBytes = Encoding.UTF8.GetBytes(key);

   using (HMACSHA256 hmac = new HMACSHA256(keyBytes))
   {
      var hash = hmac.ComputeHash(textBytes, 0, textBytes.Length);
      var hash64 = Convert.ToBase64String(hash);

      return signature == hash64;
   }
}

次は受信したデータに対して返信をする仕組みを作ります。

次→「For C#er (ASP.NET Core), Line Botの作成 - Part 2

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
4