Perl Hackers Hub

第44回LINE Messaging APIで作るchatbot―LINE::Bot::APIとngrokでお手軽に(3)

(1)こちら⁠2)こちらから。

Message typeを使いこなし表現力豊かなbotにする

Echo botではTextタイプを利用したサンプルコードを紹介しましたが、Messaging APIでは画像や位置情報などのさまざまな種類のメッセージも取り扱えます。送信時の詳細な仕様に関してはドキュメントを参照してください。

メディアファイルの送受信

botから画像や動画などのメディアファイルを送信するためには、インターネット上からHTTPSでアクセス可能なWebサーバ上にメディアファイルをアップロードしておく必要があります。

リスト2はアップロードしたメディアファイルをMessaging APIでユーザーに送信するサンプルです。⁠2)で紹介したとおり、複数のファイルをメソッドチェインで送信しています。画像と動画ファイルに関しては、(1)(3)でトークリスト上に表示するためのサムネイル画像を指定しています。このpreview_urlは動画中から生成したサムネイル画像以外も指定できますが、このメッセージを受信するユーザーが混乱しないように動画中から生成したサムネイル画像を使用することをお勧めします。音声ファイルに関しては(2)で音声の再生時間をミリ秒で指定しています。Perlでは数値リテラルの中に出現する_(アンダースコア)を無視して解釈をする仕様があり、(2)では361,000ミリ秒(=361秒)を表しています。

リスト2 メディアファイルの送信
my $messages = LINE::Bot::API::Builder::SendMessage->new(
)->add_image(
  image_url => 'https://example.com/file.jpg',
  preview_url => 'https://example.com/thumbnail.jpg',    ―(1)
)->add_audio(
  audio_url => 'https://example.com/file.m4a',
  duration => 361_000,    ―(2)
)->add_image(
  video_url => 'https://example.com/video.mp4',
  preview_url => 'https://example.com/thumbnail.jpg',    ―(3)
);

LINEサーバからダウンロードする

ユーザーから画像、音声、動画ファイルを送信されたときには、一時的にLINEサーバ上にメディアファイルが保存されます。botがこれらのメッセージを受け取ったときには、LINEサーバからファイルを速やかに取得して処理を行う必要があります。

リスト3は、メディアファイルを受信したときにローカルへファイルをダウンロードするコードです。(1)ではイベントオブジェクトから受信したメッセージのIDを取得して、それをget_message_contentメソッドを利用してLINEサーバからダウンロードします。(2)では実際にダウンロードされたファイル名を用いてファイルハンドルを開いています。

リスト3 メディアファイルの受信
if ($event->is_image_message || $event->is_audio_message
      || $event->is_video_message) {
  my $ret = $bot->get_message_content(
                    $event->message_id);    ―(1)
  if ($ret->is_success) {
    my $filename = $ret->fh->filename;
    open my $fh, '<', $file or die "$!: $file";    ―(2)
    ... # ファイル処理
  }
}

スタンプの送受信

リスト4はスタンプの送受信を行うコードです。ただし、送信可能なスタンプはドキュメントに記載されているものだけです。受信は(1)のようにすべてのスタンプで行えますが、ドキュメントに記載されたスタンプ以外のpackage_idsticker_idは非公開となっているため、特定の有料スタンプに反応するbotを作成したい場合は、そのスタンプを入手して各種IDを調べる必要があります。

リスト4 スタンプの送受信
# 受信時    ―(1)
if ($event->is_sticker_message) {
  say $event->package_id;
  say $event->sticker_id;
}
# 送信時
my $messages = LINE::Bot::API::Builder::SendMessage->new(
)->add_sticker(
  package_id => '1',
  sticker_id => '2',
);

位置情報の送受信

リスト5は緯度経度情報の送受信のコードです。たとえば(1)の内容を送信すると、図1に示したメッセージが届きます。ユーザーはLINE上から手軽に位置情報の送信が可能で、位置情報を受信したときも地図で簡単に確認できるので、位置情報を取り扱うコンテンツのbotでは対応したいメッセージタイプです。

リスト5 位置情報の送受信
# 受信時
if ($event->is_location_message) {
  say $event->title;
  say $event->address;
  say $event->latitude;
  say $event->longitude;
}
# 送信時    ―(1)
my $messages = LINE::Bot::API::Builder::SendMessage->new(
)->add_location(
  title => 'LINE Corporation.',
  address => 'Hikarie Shibuya-ku Tokyo 151-0002',
  latitude => 35.6591,
  longitude => 139.7040,
);
図1 位置情報メッセージ
図1 位置情報メッセージ

Template messageでリッチな操作体験を提供

ボタンや画像の配置などが定義されたデザインテンプレートを利用して、そこに任意の情報を詰め込んで送信できるTemplate messageというメッセージタイプがあります。ユーザーは、botから送信されたメッセージ中のボタンをタップするだけでbotとの対話を行えるので、使い勝手の良いbotを提供するためには利用したいメッセージタイプです。公式SDKでは、LINE::Bot::API::Builder::TemplateMessageを用いることで簡単にTemplate messageを送信できます。

Buttonsタイプで画像とボタンを組み合わせたUIを作る

図2のButtonsタイプでは、画像、タイトル、テキストを1つずつと、複数のボタンを送信できます。図2では「Open Browser」「Remind me」と記された箇所がボタンになっています。リスト6はButtonsタイプのメッセージを構築するコードになっており、(1)alt_messageにはTemplate message非対応端末で表示されるテキストを設定します。(2)add_message_actionメソッドはユーザーがボタンを押したときにtextの内容を自動的にチャットメッセージとしてユーザーが発言するボタンを表示します。(3)add_uri_actionメソッドはurlで指定したURLをブラウザで開くボタンを表示します。なお、LINE::Bot::API::Builder::TemplateMessageで作成したオブジェクトは$bot->reply_messageなどで直接送信ができないので、必ず(4)のとおりにLINE::Bot::API::Builder::SendMessageを使って送信オブジェクトを構築する必要があります。

図2 Buttonsタイプ
図2 Buttonsタイプ
リスト6 Buttonsタイプのメッセージ構築
my $buttons = LINE::Bot::API::Builder::TemplateMessage
->new_buttons(
  alt_text => 'this is a buttons template',    ―(1)
  image_url => 'https://example.com/bot/image.jpg',
  title => 'buttons',
  text => 'description',
)->add_message_action(    ―(2)
  label => 'message',
  text => 'message',
)->add_uri_action(    ―(3)
  label => 'uri',
  uri => 'http://example.com/',
);

my $messages = LINE::Bot::API::Builder::SendMessage
  ->new()    ―(4)
  ->add_template($buttons->build);
$bot->reply_message($reply_token, $messages->build);

Carouselタイプを使って複数個のテンプレートを横に並べる

図3のCarouselタイプは、基本的にはButtonsタイプのUIUser Interfaceを横に複数個並べたテンプレートになっています。リスト7(1)new_carouselメソッドでCarouselのビルダオブジェクトを作成し、LINE::Bot::API::Builder::TemplateMessage::Columnで作成したCarouselタイプのオブジェクトを(2)add_columnメソッドで登録していきます。

図3 Carouselタイプ
図3 Carouselタイプ
リスト7 Carouselタイプのメッセージ構築
my $carousel = LINE::Bot::API::Builder::TemplateMessage
->new_carousel(    ―(1)
  alt_text => 'this is a carousel template',
);
for my $i (1..5) {
  my $col = LINE::Bot::API::Builder::TemplateMessage::Column
  ->new(
    image_url => 'https://example.com/bot/item.jpg',
    title => "carousel $i",
    text => "description $i",
  )->add_message_action(
    label => 'message',
    text => 'message',
  );
  $carousel->add_column($col->build);    ―(2)
}

Confirmタイプで選択式の確認ダイアログを提供する

図4のConfirmタイプは、一般的に普及しているOK/Cancelを聞くConfirmダイアログの見た目のUIを提供します。リスト8で示すとおり、ほかのTemplate messageのタイプと同じ形でオブジェクトが構築できます。

図3 Confirmタイプ
図4 Confirmタイプ
リスト8 Confirmタイプのメッセージ構築
my $confirm = LINE::Bot::API::Builder::TemplateMessage
->new_confirm(
  alt_text => 'this is a confirm template',
  text => 'confirm',
)->add_postback_action(    ―(1)
  label => 'postback',
  data => 'postback data',
)->add_message_action(
  label => 'message',
  text => 'message',
);

Postbackを使ってチャットのログを汚さずにbotにメッセージを送る

リスト8では、ほかの2個のTemplate messageとは違い(1)add_postback_actionメソッドを使いました。これはadd_message_actionと似た機能を提供するのですが、add_message_actionとは違いチャットメッセージに発言のログを残さずにWebhook URLにイベントを通知できるボタンを表示します。このボタンをユーザーが押したときに、裏側でPostback eventがWebhook URLに送信します。このときdataをイベントオブジェクトに含めており、Postback eventの内容は次に示したコードで利用できます。

if ($event->is_postback_event) {
  say $event->postback_data;
}

そのほかのお勧め機能

本節では、前節までで紹介しきれなかったお勧めのAPIを紹介します。

LINE Beaconによる現実世界との連携

Messaging APIには、LINE Beaconと呼ばれる専用のビーコンデバイスを用いることで、ビーコンの電波を受信したタイミングでBeacon eventをWebhook URLへ送信するしくみがあります。これを利用することで、ユーザーの現実世界での行動をイベントトリガとしたLINE BOTを開発できます。

LINE Simple Beacon Specを実装することにより、Raspberry Pi 3などで手軽にビーコンが作成できます。将来的にはハードウェアで計測した数値などをDevice MessageとしてWebhook URLに送信できる予定[7]ですので、リアル世界と密接に連携したbotを簡単に作成できます。

Social REST APIを使ったWebサイト連携

Social REST APIを利用することで、みなさんのWebサイトに図5に示したLINEログイン機能を追加できます。ログイン後にはPush Messageで利用可能なuserIdも取得できるので、通常はbotとの会話でサービスを提供しつつ、チャットのUIに適さない複雑な設定画面はWebサイトで提供するハイブリッドなbotが作成できます。

図5 LINEログイン
図5 LINEログイン

LINE Notifyで簡単な通知の送信

LINE Notifyとは、GitHubやMackerelなどのWebサービス上で発生したイベントをLINEに送信するサービスです。このサービスにログインしてパーソナルアクセストークンを取得すると、LINE上の自分のアカウントやグループ宛に好きな通知を送信できます。気軽にcurlなどのコマンドから送信することを考慮して作られており、たとえば次に示したコマンドで簡単にLINE宛へ通知できます。

Furl->new->post(
    'https://notify-api.line.me/api/notify',
[ 'Authorization' => "Bearer $TOKEN" ],
[ 'message' => 'こんにちは!' ]
);

すべてのLINE連携をMessaging APIで作ろうとすると開発コストが増大するので、手を抜ける場合にはLINE Notifyを利用して気軽にLINEに通知をするとよいでしょう。

まとめ

本稿では、LINE Messaging APIの公式SDKを利用したLINE BOTを開発する方法について紹介しました。一度環境を整えてしまえば、LINEで動作するbotが簡単に開発できることが伝わりましたら幸いです。

さて、次回の執筆者はふしはらかんさんで、テーマは「Perlで書くコマンドラインツール」です。お楽しみに。

WEB+DB PRESS

本誌最新号をチェック!
WEB+DB PRESS Vol.130

2022年8月24日発売
B5判/168ページ
定価1,628円
(本体1,480円+税10%)
ISBN978-4-297-13000-8

  • 特集1
    イミュータブルデータモデルで始める
    実践データモデリング

    業務の複雑さをシンプルに表現!
  • 特集2
    いまはじめるFlutter
    iOS/Android両対応アプリを開発してみよう
  • 特集3
    作って学ぶWeb3
    ブロックチェーン、スマートコントラクト、NFT

おすすめ記事

記事・ニュース一覧