Develop LINE BOT
with LogicFlow
2017/11/18
LogicFlow-ja 小尾 智之(Ahf)
事前準備
• LINE アカウント
• LINE Developer アカウント
• Azure サブスクリプションまたは
Flow アカウント(Microsoft アカウント)
https://goo.gl/pxwBH9
からスキーマ定義を DL しておいてください
LINE DEVELOPER アカウント作成
https://developers.line.me/ja/
LINE アカウントでログイン
初ログイン時は端末上で本人
確認あり(LINEアプリ必要)
作成済みの BOT 情報が表示される
初回は何も表示されない
本名である必要はなく
あとで修正も可能
Messaging API をクリック
BOT 用チャンネル情報を設
定する
Developer Trial を選択
一通り設定したら確認をクリック
規約への同意など求められるので
チェックをつけて作成をクリック
LINE DEVELOPER の設定はひとまずここまで
現状では上記のように送受信設定が
行われていない状態でOKです
LogicApps/Flow で受け取る
1.LogicApps の追加をクリック
2.名前を入力
3.利用するサブスクリプションを選択
4.リソースグループを選択または新規入力
5.利用するリージョンを選択
6.作成をクリック
LogicApps の新規作成
Blank Logic App をクリック
Flow の新規作成
1.マイフローをクリック
2.一から作成をクリック
3.多数のコネクタやトリガーを検索するをクリック
この状態になれば
作成可能
Request(要求)
トリガを選択する
LogicApps
Flow
Flow の場合はトリガとアクションがなければ
保存できないので、仮のアクションを選択し
保存を行う必要があります
保存すると
URL が
生成されます
この URL を
LINE 側に
設定します
LINE Developer 上で Webhook を有効にします
利用するを選択して更新をクリックします
「自動応答メッセージ」「友達追加あいさつ」
は「利用しない」に設定します
LINE Developer 上で Webhook URL を設定します
URL に LogicFlow で生成された URL を貼り付け
更新をクリックします(HTTPS:// は不要な点に注意!)
Webhook URL を設定後に接続確認をクリック
正しく設定すれば LogicFlow が呼び出されます
LINE DEVELOPER 側ではエラー表示となるが現時点では問題なし
テキストメッセージのやりとり
全体の流れ
(1) LINE より呼び出し
(2) LINE へテキスト
メッセージを送信
Webhook オブジェクトのスキーマを設定します
補足資料のスキーマ定義を貼り付けでOKです
HTTP アクションの設定(1)
POST https://api.line.me/v2/bot/message/reply
HTTP アクションの設定(2)
Content-Type:application/json
Authorization:Bearer {long life token}
Bearer の後に半角スペース、その後にトークンを張り付けます
HTTP アクションの設定(3)
ReplyToken を指定すると
自動で ForEach が設定される
HTTP アクションの設定(4)
items('Apply_to_each')?['message']?['text']
設定時は function 表示されていますが
保存後に再表示を行うとこのように変わります
現在のダイアログでは孫要素(A.B.C・・・のC以降)
を扱えないための挙動です
このようにオウム返しできていれば成功です
実行確認
それ以外のやりとり
その他に送信できる種類
• スタンプ(独自スタンプは不可)
• 画像(jpg)
• 動画(mp4 プレビューイメージは jpg)
• 音声(m4a形式)
• 位置情報
• イメージマップ
• テンプレート(ボタン/確認/カルーセル)
全体の流れ
単体のやり取りは同じ流れになります
HTTP アクションで戻す内容が異なります
スタンプ
https://developers.line.me/media/messaging-api/sticker_list.pdf
利用可能なスタンプ一覧
{
"type": "sticker",
"packageId": "2",
"stickerId": "145"
}
画像
{
"type": "image",
"originalContentUrl": "",
"previewImageUrl": ""
}
originalContentUrl HTTPS で指定
JPEG
最大画像サイズ:1024×1024
最大ファイルサイズ:1MB
previewImageUrl HTTPS で指定
JPEG
最大画像サイズ:240×240
最大ファイルサイズ:1MB
originalContentUrl
previewImageUrl
画像サイズを指定できるので
サムネイル作らなくとも対応は可能です
Cognitive Services で提供されている
ComputeVision API でサムネイル作成も可能です
動画 {
"type": "video",
"originalContentUrl": "",
"previewImageUrl": ""
}
指定した動画 URL が誤っていた場合
このように再生できないのですが
TL上ではわからない状態になります
音声 {
"type": "audio",
"originalContentUrl": "",
"duration": 10000
}
位置情報 {
"type": "location",
"title": "",
"address": "",
"latitude": 0,
"longitude": 0
}
PC 版の場合はクリックするとブラウザで GoogleMap で表示
スマホ版は内部ビューワーで GoogleMap を表示します
イメージマップ
{
"type": "imagemap",
"baseUrl": "",
"altText": "クラウディアさんとななみ",
"baseSize": {
"height": 1040,
"width": 1040
},
"actions": [
{
"type": "message",
"text": "クラウディアさんお疲れ様でした!",
"area": {
"x": 183,
"y": 5,
"width": 220,
"height": 540
}
}
]
} スマホ版のみで利用できます
"actions": [
{
"type": "message",
"text": "クラウディアさんお疲れ様でした!",
"area": {
"x": 183,
"y": 5,
"width": 220,
"height": 540
}
}
]
画像の指定した領域をクリックすると
Actions で定義した動作を実行します
イメージマップのアクション
{
"type":"uri",
"linkUri":"https://example.com/",
"area":{
"x":0,
"y":0,
"width":520,
"height":1040
}
}
{
"type":"message",
"text":"hello",
"area":{
"x":520,
"y":0,
"width":520,
"height":1040
}
}
Uri アクションは指定したアドレスに
リダイレクトします
Message アクションはメッセージを
代理で入力したかのように動作します
(タップするとすぐにWebhookで呼び出される)
イメージマップの画像サイズ
{
"type": "imagemap",
"baseUrl": "",
"altText": "クラウディアさんとななみ",
"baseSize": {
"height": 520,
"width": 1040
},
画像は
[ baseUrl ] / [ デバイスから要求する画像サイズ ]
でアクセスする仕様なので、サイズにあった画像をあらかじめ
同一ディレクトリに用意しておくのがよいです
利用される画像サイズ 240px / 300px / 460px / 700px / 1040px
テンプレート(確認)
{
"type": "template",
"altText": "確認なのです!",
"template": {
"type": "confirm",
"text": "出撃しますか?",
"actions": [
{
"type": "message",
"label": "電の本気を見るのです!",
"text": "第一艦隊、第一水雷戦隊。出撃です!"
},
{
"type": "message",
"label": "艦隊がお戻りみたいです。",
"text": "ちょっと直してくるのです。"
}
]
}
}
"type": "message",
"label": "電の本気を見るのです!",
"text": "第一艦隊、第一水雷戦隊。出撃です!"
"type": "message",
"label": "艦隊がお戻りみたいです。",
"text": "ちょっと直してくるのです。"
スマホの画面サイズにより
label の文字は欠けることが多いので
注意が必要です
テンプレート(ボタン)
{
"type": "template",
“altText”: “テンプレートのサンプル",
"template": {
"type": "buttons",
"thumbnailImageUrl": "
https://lfjabot.blob.core.windows.net/images
/logicflowja_logo.png",
"title": "Menu",
"text": "LogicFlow といえば",
"actions": [
{"type": "postback",
"label": "LogicApps",
"data": "action=buy&itemid=123" },
{"type": "postback",
"label": "MS Flow",
"data": "action=add&itemid=123" },
{"type": "uri",
"label": "WF",
"uri": "http://blogahf.blogspot.jp/" }
]
Type:button で postback した場合は
TL にメッセージが表示されないまま
Webhook が呼び出されます
Postback.data で
指定した値が連携されます
テンプレート(カルーセル)
{"type": "template",
"altText": "カルーセルのサンプルです",
"template": {"type": "carousel",
"columns": [
{"thumbnailImageUrl":
"https://lfjabot.blob.core.windows.net/images/rabbit.jpg",
"title": "メニュー1",
"text": "はむはむむしゃむしゃ",
"actions": [
{"type": "postback",
"label": "飼う",
"data": "action=keep&itemid=1" },
{"type": "postback",
"label": "野に放つ",
"data": "action=remove&itemid=1" }
]
},
{ (別カラムの設定)}
]
}
}
{"thumbnailImageUrl":
"https://lfjabot.blob.core.windows.net/images/rabbit.J
PG",
"title": "メニュー1",
"text": “description",
"actions": [
{"type": "postback",
"label": "飼う",
"data": "action=keep&itemid=1" },
{"type": "postback",
"label": "野に放つ",
"data": "action=remove&itemid=1" }
]
},
カルーセルのカラムは 10 個まで
カラムのアクションは 3 個まで
(すべてのカラムでアクション個数は統一)
テンプレート(画像カルーセル)
{
"type": "template",
"altText": "画像カルーセルのサンプル",
"template": {
"type": "image_carousel",
"columns": [
{ "imageUrl": "https://lfjabot.blob.core.windows.net/images/fox.jpg",
"action": { "type": "postback",
"label": "こんこん",
"data": "action=sings" }
},
{ "imageUrl":
"https://lfjabot.blob.core.windows.net/images/raccoon.jpg",
"action": { "type": "postback",
"label": "ぽんぽこぽん",
"data": "action=drum" }
}
]
}
}
{ "imageUrl":
"https://lfjabot.blob.core.windows.net/images
/fox.jpg",
"action": { "type": "postback",
"label": "こんこん",
"data": "action=sings" }
},
{ "imageUrl":
"https://lfjabot.blob.core.windows.net/images
/raccoon.jpg",
"action": { "type": "postback",
"label": "ぽんぽこぽん",
"data": "action=drum" }
}
選択肢がないだけで
カルーセルとほぼ同じになります
コンテンツの取得
https://api.line.me/v2/bot/message/{messageId}/content
concat('https://api.line.me/v2/bot/message/’,
items('For_each')?['message']?['id’],
'/content')
取得用の URI 作成
シナリオのある BOT 対応
必要な対応
1. メッセージ種類による処理分岐
2. やりとりの状態管理
(誰からか、何が送られたか等)
最低限として上記への対応が必要になります。
今回のハンズオンでは
「メッセージ種類による処理分岐」への対応を行い
「やりとりの状態管理」は簡易な方法を採用します。
今回作ろうとしているもの
質問1
質問2-A
質問3-A 質問3-B
質問2-B
質問3-C 質問3-D
YesNo クイズ
シナリオのサンプル
ID メッセージ 選択肢1 移動先1 選択肢2 移動先2
1最新の技術を使うのが好き はい 2 いいえ 3
2プログラムを書いてなんぼという気持ちがある はい 10 いいえ 11
3専門職じゃなくても開発したい はい 12 いいえ 13
10C# がいいんでないかな
11LogicFlow でつなげる開発たーのしー
12VBA・・おっと誰か来たようだ
13独立すればいいんでね?
設問は2問と非常に簡単な形です
実行結果のサンプル
正しく状態に沿った動きを
しているように見えます
実際には選択肢に含ませた情報で
次に出す内容を特定しています
言い換えると状態を持っているのを
LINE の TL 側とすることで
LogicFlow の処理を軽減させます
メッセージ種類による処理分岐
イベント種類
message
follow
unfollow
join
leave
beacon
postback
メッセージ種類
text
image
video
audio
file
location
sticker
メッセージだけでも 7 種類について考慮が必要です
まともにやると条件判断を繰り返し行うので
非常に読みにくい LogicFlow となってしまいます
今回はプログラム的な
発想で対処します
本来は LogicFlow ではなく
外部処理で行うのが適して
いる箇所です
indexof('messagefollowunfollowjoinleavebeaconpostback’,
items('For_each')?['type'])
indexof(
'messagefollowunfollowjoinleavebeaconpostback’,
items('For_each')?['type'])
ある文字列の中から指定した文字列が
何桁目から始まっているかを取得する関数
LINE から渡されるイベント種別を
結合した文字列
実際に LINE から
渡されるイベント種別
Indexof による取得結果
イベント種類
message
follow
unfollow
join
leave
beacon
postback
この結果をもとに「スイッチ」で横に分岐します
0
7
13
21
25
30
36
今回のハンズオンでは message と postback のみ利用しますので
他イベントに対応できる必要はありません
Indexof による取得結果(2)
メッセージ種類
text
image
video
audio
file
location
sticker
メッセージ種類も同様の方法で対応可能です
0
4
9
14
19
23
31
今回のハンズオンでは text のみ利用しますので
他メッセージに対応できる必要はありません
LogicFlow 完成イメージ
非常に横に長い LogicFlow となります
Bearer トークンを変数に設定
利用する機会が多いので変数が便利です
indexof('messagepostback’,
items('For_each')?['type'])
items(‘For_each')?['message']?[‘type']
何かテキストを送信した場合に
占いを開始します
replace(
string(items('For_each')?['postback']?['data’]),
‘itemid=‘,
'')
一つにまとめても大丈夫です
Itemid の値で処理を分けてください
シナリオでのID値
まとめ
ハンズオンまとめ
• LogicFlow だけでも簡単な BOT は作成可能です
• ただし複雑な処理には向いていません
その場合は処理を外出し、LogicFlow から呼ぶのがアーキテクチャ的
に素直です
• LogicFlow は流れの制御を行うのが得意です
おおまかな流れを LogicFlow で、細かい処理を Function App や API
Apps で行うのがよいです
• すべてを LogicFlow で処理するのは自己満足にしかなりません
Happy LogicFlow Develop!
補足
{"type": "object", "properties": { "events": { "type": "array",
"items": { "type": "object",
"properties": { "replyToken": { "type": "string" },
"type": { "type": "string" },
"timestamp": { "type": "number" },
"source": { "type": "object",
"properties": { "type": { "type": "string" },
"userId": { "type": "string" },
"groupId": { "type": "string" }
}
}
},
"message": {"type": "object",
"properties": { "id": { "type": "string" },
"type": { "type": "string" },
"text": { "type": "string" },
"fileName": { "type": "string" },
"fileSize": { "type": "number" },
"title": { "type": "string" },
"address": { "type": "string" },
"latitude": { "type": "number" },
"longitude": { "type": "number" },
"packageId": { "type": "string" },
"stickerId": { "type": "string" }
}
},
"postback": {"type": "object",
"properties": { "data": { "type": "string" } }
}
}
} }
}
Webhook オブジェクト
スキーマ定義
(Beacon未定義)
https://goo.gl/pxwBH9
プラン APIリクエスト回数の制限 メッセージ受信者数の制限
Developer Trial 1,000/分 20,000/分
その他のプラン 10,000/分 200,000/分
ステータスコード 説明
200 OK リクエストが成功しました。
400 Bad Request リクエストに問題があります。
401 Unauthorized 有効なチャネルアクセストークンが指定されていません。
403 Forbidden APIを使用する権限がありません。ご契約中のプランやアカウントに付与され
ている権限を確認してください。
429 Too Many Requests APIコールのレート制限を超過しました。
500 Internal Server Error 内部サーバーのエラーです。
メッセージ 説明
The request body has X error(s) リクエストボディのJSONデータにエラーがありました。Xの部分に
エラーの数が表示されます。詳細はdetails[].messageおよび
details[].propertyフィールドに含まれます。
Invalid reply token 応答メッセージで使用された応答トークンが無効です。
The property, XXX, in the request body is
invalid (line: XXX, column: XXX)
リクエストボディに無効なプロパティが指定されていました。XXX
の部分に具体的な行と列が表示されます。
The request body could not be parsed
as JSON (line: XXX, column: XXX)
リクエストボディのJSONデータを解析できませんでした。XXXの部
分に具体的な行と列が表示されます。
The content type, XXX, is not supported APIでサポートされていないコンテンツタイプがリクエストされま
した。
Authentication failed due to the
following reason: XXX
APIが呼び出されたときに認証に失敗しました。XXXの部分に理由が
表示されます。
Access to this API is not available for
your account
実行権限がないAPIを呼び出しました。
Failed to send messages メッセージの送信に失敗しました。指定したユーザーIDが存在しな
い場合などにこのエラーが発生します。

Develop LINE_BOT with LogicFlow