Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Develop LINE_BOT with LogicFlow

560 views

Published on

2017/11/18 LogicFlow-ja offline で実施した、LogicFlow で LINE BOT をノーコーディングで作成するハンズオン資料

Published in: Technology
  • Be the first to comment

Develop LINE_BOT with LogicFlow

  1. 1. Develop LINE BOT with LogicFlow 2017/11/18 LogicFlow-ja 小尾 智之(Ahf)
  2. 2. 事前準備 • LINE アカウント • LINE Developer アカウント • Azure サブスクリプションまたは Flow アカウント(Microsoft アカウント) https://goo.gl/pxwBH9 からスキーマ定義を DL しておいてください
  3. 3. LINE DEVELOPER アカウント作成
  4. 4. https://developers.line.me/ja/
  5. 5. LINE アカウントでログイン 初ログイン時は端末上で本人 確認あり(LINEアプリ必要)
  6. 6. 作成済みの BOT 情報が表示される 初回は何も表示されない
  7. 7. 本名である必要はなく あとで修正も可能
  8. 8. Messaging API をクリック BOT 用チャンネル情報を設 定する
  9. 9. Developer Trial を選択 一通り設定したら確認をクリック 規約への同意など求められるので チェックをつけて作成をクリック
  10. 10. LINE DEVELOPER の設定はひとまずここまで
  11. 11. 現状では上記のように送受信設定が 行われていない状態でOKです
  12. 12. LogicApps/Flow で受け取る
  13. 13. 1.LogicApps の追加をクリック 2.名前を入力 3.利用するサブスクリプションを選択 4.リソースグループを選択または新規入力 5.利用するリージョンを選択 6.作成をクリック LogicApps の新規作成
  14. 14. Blank Logic App をクリック
  15. 15. Flow の新規作成 1.マイフローをクリック 2.一から作成をクリック 3.多数のコネクタやトリガーを検索するをクリック
  16. 16. この状態になれば 作成可能
  17. 17. Request(要求) トリガを選択する LogicApps Flow
  18. 18. Flow の場合はトリガとアクションがなければ 保存できないので、仮のアクションを選択し 保存を行う必要があります
  19. 19. 保存すると URL が 生成されます この URL を LINE 側に 設定します
  20. 20. LINE Developer 上で Webhook を有効にします 利用するを選択して更新をクリックします
  21. 21. 「自動応答メッセージ」「友達追加あいさつ」 は「利用しない」に設定します
  22. 22. LINE Developer 上で Webhook URL を設定します URL に LogicFlow で生成された URL を貼り付け 更新をクリックします(HTTPS:// は不要な点に注意!)
  23. 23. Webhook URL を設定後に接続確認をクリック 正しく設定すれば LogicFlow が呼び出されます LINE DEVELOPER 側ではエラー表示となるが現時点では問題なし
  24. 24. テキストメッセージのやりとり
  25. 25. 全体の流れ (1) LINE より呼び出し (2) LINE へテキスト メッセージを送信
  26. 26. Webhook オブジェクトのスキーマを設定します 補足資料のスキーマ定義を貼り付けでOKです
  27. 27. HTTP アクションの設定(1) POST https://api.line.me/v2/bot/message/reply
  28. 28. HTTP アクションの設定(2) Content-Type:application/json Authorization:Bearer {long life token} Bearer の後に半角スペース、その後にトークンを張り付けます
  29. 29. HTTP アクションの設定(3) ReplyToken を指定すると 自動で ForEach が設定される
  30. 30. HTTP アクションの設定(4) items('Apply_to_each')?['message']?['text']
  31. 31. 設定時は function 表示されていますが 保存後に再表示を行うとこのように変わります 現在のダイアログでは孫要素(A.B.C・・・のC以降) を扱えないための挙動です
  32. 32. このようにオウム返しできていれば成功です 実行確認
  33. 33. それ以外のやりとり
  34. 34. その他に送信できる種類 • スタンプ(独自スタンプは不可) • 画像(jpg) • 動画(mp4 プレビューイメージは jpg) • 音声(m4a形式) • 位置情報 • イメージマップ • テンプレート(ボタン/確認/カルーセル)
  35. 35. 全体の流れ 単体のやり取りは同じ流れになります
  36. 36. HTTP アクションで戻す内容が異なります
  37. 37. スタンプ https://developers.line.me/media/messaging-api/sticker_list.pdf 利用可能なスタンプ一覧 { "type": "sticker", "packageId": "2", "stickerId": "145" }
  38. 38. 画像 { "type": "image", "originalContentUrl": "", "previewImageUrl": "" } originalContentUrl HTTPS で指定 JPEG 最大画像サイズ:1024×1024 最大ファイルサイズ:1MB previewImageUrl HTTPS で指定 JPEG 最大画像サイズ:240×240 最大ファイルサイズ:1MB
  39. 39. originalContentUrl previewImageUrl
  40. 40. 画像サイズを指定できるので サムネイル作らなくとも対応は可能です
  41. 41. Cognitive Services で提供されている ComputeVision API でサムネイル作成も可能です
  42. 42. 動画 { "type": "video", "originalContentUrl": "", "previewImageUrl": "" }
  43. 43. 指定した動画 URL が誤っていた場合 このように再生できないのですが TL上ではわからない状態になります
  44. 44. 音声 { "type": "audio", "originalContentUrl": "", "duration": 10000 }
  45. 45. 位置情報 { "type": "location", "title": "", "address": "", "latitude": 0, "longitude": 0 }
  46. 46. PC 版の場合はクリックするとブラウザで GoogleMap で表示 スマホ版は内部ビューワーで GoogleMap を表示します
  47. 47. イメージマップ { "type": "imagemap", "baseUrl": "", "altText": "クラウディアさんとななみ", "baseSize": { "height": 1040, "width": 1040 }, "actions": [ { "type": "message", "text": "クラウディアさんお疲れ様でした!", "area": { "x": 183, "y": 5, "width": 220, "height": 540 } } ] } スマホ版のみで利用できます
  48. 48. "actions": [ { "type": "message", "text": "クラウディアさんお疲れ様でした!", "area": { "x": 183, "y": 5, "width": 220, "height": 540 } } ] 画像の指定した領域をクリックすると Actions で定義した動作を実行します
  49. 49. イメージマップのアクション { "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で呼び出される)
  50. 50. イメージマップの画像サイズ { "type": "imagemap", "baseUrl": "", "altText": "クラウディアさんとななみ", "baseSize": { "height": 520, "width": 1040 }, 画像は [ baseUrl ] / [ デバイスから要求する画像サイズ ] でアクセスする仕様なので、サイズにあった画像をあらかじめ 同一ディレクトリに用意しておくのがよいです 利用される画像サイズ 240px / 300px / 460px / 700px / 1040px
  51. 51. テンプレート(確認) { "type": "template", "altText": "確認なのです!", "template": { "type": "confirm", "text": "出撃しますか?", "actions": [ { "type": "message", "label": "電の本気を見るのです!", "text": "第一艦隊、第一水雷戦隊。出撃です!" }, { "type": "message", "label": "艦隊がお戻りみたいです。", "text": "ちょっと直してくるのです。" } ] } }
  52. 52. "type": "message", "label": "電の本気を見るのです!", "text": "第一艦隊、第一水雷戦隊。出撃です!" "type": "message", "label": "艦隊がお戻りみたいです。", "text": "ちょっと直してくるのです。" スマホの画面サイズにより label の文字は欠けることが多いので 注意が必要です
  53. 53. テンプレート(ボタン) { "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/" } ]
  54. 54. Type:button で postback した場合は TL にメッセージが表示されないまま Webhook が呼び出されます Postback.data で 指定した値が連携されます
  55. 55. テンプレート(カルーセル) {"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" } ] }, { (別カラムの設定)} ] } }
  56. 56. {"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 個まで (すべてのカラムでアクション個数は統一)
  57. 57. テンプレート(画像カルーセル) { "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" } } ] } }
  58. 58. { "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" } } 選択肢がないだけで カルーセルとほぼ同じになります
  59. 59. コンテンツの取得
  60. 60. https://api.line.me/v2/bot/message/{messageId}/content
  61. 61. concat('https://api.line.me/v2/bot/message/’, items('For_each')?['message']?['id’], '/content') 取得用の URI 作成
  62. 62. シナリオのある BOT 対応
  63. 63. 必要な対応 1. メッセージ種類による処理分岐 2. やりとりの状態管理 (誰からか、何が送られたか等) 最低限として上記への対応が必要になります。 今回のハンズオンでは 「メッセージ種類による処理分岐」への対応を行い 「やりとりの状態管理」は簡易な方法を採用します。
  64. 64. 今回作ろうとしているもの 質問1 質問2-A 質問3-A 質問3-B 質問2-B 質問3-C 質問3-D YesNo クイズ
  65. 65. シナリオのサンプル ID メッセージ 選択肢1 移動先1 選択肢2 移動先2 1最新の技術を使うのが好き はい 2 いいえ 3 2プログラムを書いてなんぼという気持ちがある はい 10 いいえ 11 3専門職じゃなくても開発したい はい 12 いいえ 13 10C# がいいんでないかな 11LogicFlow でつなげる開発たーのしー 12VBA・・おっと誰か来たようだ 13独立すればいいんでね? 設問は2問と非常に簡単な形です
  66. 66. 実行結果のサンプル 正しく状態に沿った動きを しているように見えます 実際には選択肢に含ませた情報で 次に出す内容を特定しています 言い換えると状態を持っているのを LINE の TL 側とすることで LogicFlow の処理を軽減させます
  67. 67. メッセージ種類による処理分岐 イベント種類 message follow unfollow join leave beacon postback メッセージ種類 text image video audio file location sticker メッセージだけでも 7 種類について考慮が必要です
  68. 68. まともにやると条件判断を繰り返し行うので 非常に読みにくい LogicFlow となってしまいます
  69. 69. 今回はプログラム的な 発想で対処します 本来は LogicFlow ではなく 外部処理で行うのが適して いる箇所です indexof('messagefollowunfollowjoinleavebeaconpostback’, items('For_each')?['type'])
  70. 70. indexof( 'messagefollowunfollowjoinleavebeaconpostback’, items('For_each')?['type']) ある文字列の中から指定した文字列が 何桁目から始まっているかを取得する関数 LINE から渡されるイベント種別を 結合した文字列 実際に LINE から 渡されるイベント種別
  71. 71. Indexof による取得結果 イベント種類 message follow unfollow join leave beacon postback この結果をもとに「スイッチ」で横に分岐します 0 7 13 21 25 30 36 今回のハンズオンでは message と postback のみ利用しますので 他イベントに対応できる必要はありません
  72. 72. Indexof による取得結果(2) メッセージ種類 text image video audio file location sticker メッセージ種類も同様の方法で対応可能です 0 4 9 14 19 23 31 今回のハンズオンでは text のみ利用しますので 他メッセージに対応できる必要はありません
  73. 73. LogicFlow 完成イメージ
  74. 74. 非常に横に長い LogicFlow となります
  75. 75. Bearer トークンを変数に設定 利用する機会が多いので変数が便利です
  76. 76. indexof('messagepostback’, items('For_each')?['type'])
  77. 77. items(‘For_each')?['message']?[‘type']
  78. 78. 何かテキストを送信した場合に 占いを開始します
  79. 79. replace( string(items('For_each')?['postback']?['data’]), ‘itemid=‘, '') 一つにまとめても大丈夫です
  80. 80. Itemid の値で処理を分けてください シナリオでのID値
  81. 81. まとめ
  82. 82. ハンズオンまとめ • LogicFlow だけでも簡単な BOT は作成可能です • ただし複雑な処理には向いていません その場合は処理を外出し、LogicFlow から呼ぶのがアーキテクチャ的 に素直です • LogicFlow は流れの制御を行うのが得意です おおまかな流れを LogicFlow で、細かい処理を Function App や API Apps で行うのがよいです • すべてを LogicFlow で処理するのは自己満足にしかなりません
  83. 83. Happy LogicFlow Develop!
  84. 84. 補足
  85. 85. {"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
  86. 86. プラン 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 内部サーバーのエラーです。
  87. 87. メッセージ 説明 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が存在しな い場合などにこのエラーが発生します。

×