和田祐介(84)59この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。はじめに世の中には多くの便利なアプリやサービスがあり、使いこなせれば日々の生産性がさらにあがること間違いナシですが、いかんせん数が多く、そのすべてのパワーを発揮するのは大変です。便利なサービスには、APIが用意されていることがほとんどです。我々はそういったAPIと、ちょっとしたエンジニアリングを駆使することで、様々な「口」からサービスの恩恵を受けることができるようになります。慣れ親しんだデバイスやアプリから別のサービスを使うことができれば、新しく覚えることも少なく済むはずです。今回は、LINEから受け取ったメッセージに反応して、買い物リストを閲覧・追加するBOTを作ってみます。我が家では消耗品を気づいたベースで補充するようにしているのですが、毎日買うものならばまだしも、買い替え間隔が長いもの(シャンプーやボディソープなど)はついつい忘れがちです。タスク管理ツールを使ってリストで管理はしているのですが、肝心なときに見ず、帰ってから気づいて「やっちまったぜ」と嘆く日々。再度活用してみることにしました。最終的に以下のようなことができるようになりました。例を示すことを目的としています。途中、Herokuのアドオンを使うときにクレジットカードの登録が必要ですが無料です。やること今回はタスク管理ツールとしてToodledoを使います。経由で使ってみたかったという意図があります。これができれば、APIが利用可能な他のサービスで同じようにBOTから使えるようになるはずですね。システム関連図は以下のようになります。Herokuにアプリを登録するまずは実行環境を整えます。ユーザから話しかけられたら固定の文言を返すプログラムを作りましょう。LINEとの疎通確認が目的です。今回のような規模のお試し開発では、Herokuは非常に良いデプロイサーバです。先ほどの図で示したように、GitHubとの連携設定を行うことで、masterブランチにプッシュした場合即座にデプロイしてくれる点が非常に助かりました。AWSに展開することも考えたのですが、すぐ試したいときはHeorkuの方が良いです。ここでは以下の順で作業を進めていきます。Fixie)LINEのコールバック先・ホワイトリストを設定BOTプログラムを作成プッシュ&デプロイGitHubリポジトリとHerokuを連携Herokuの画面に従い、GitHubと連携します。これで、masterブランチにpushされるたびに、Herokuのサーバへデプロイされるようになります。アクセス許可サーバIPを設定するために利用します。どちらも、それほどアクセスが発生しない状況下では無料の範囲内で利用できます。固定したIPアドレスをセットすることに加え、LINEに対してリクエストを送るときにプロキシサーバを経由させる必要があります。LINEのコールバック先、サーバホワイトリストを設定Herokuの画面から得られる情報をLINE側へ設定します。このとき、コールバック予定のパスを予め決めておきます。今回は/lineとしました。IPs」よりIPアドレスを取得し、LINE側へ設定します。買い物リストのことは考えず、固定文言を返すプログラムを作成します。Scalaのクラス構造を大まかに以下のようにしています。対するメッセージのコールバックを扱うコントローラです。BOTへのすべてのメッセージはここに到達します。メッセージの中身を見てどのサービスを呼ぶか決めます。今回はConstantMessageService固定です。メッセージを受け取り、どのような返信をするか決めるレイヤです。いわゆるビジネスロジックをここで決めることになります。今回は固定文言を生成するのみです。serviceレイヤはLINEへの返信のやり方は知りません。「具体的には何をやってるか知らないけれどLINEに返信してくれるLineMessageSenderトレイトを呼ぶ」ことが仕事です。LineMessageSenderトレイトを実装するクラスです。送り先や返信メッセージのフォーマットを知っており、serviceから受け取ったコンテンツをJSONに変換して実際にLINEへ送ります。LineMessageSenderはDIによってMessageSendApiClientという具体的なインスタンスを作ることになります。ConstantMessageServiceをDIします。コールバックで受け取ったリクエストボディJsonを我々のバリューオブジェクトに変換してあげます。Jsonには、誰から送られてきたか、や、どんなメッセージが送られてきたか、が含まれています。"なにいってだこいつ"))}具体的にどうやってLINEに送るのかは知らないけれど、何を送ればよいかは知っているので、固定文言をLineMessageSenderに渡しています。お察しのとおり、このBOTは何を送っても「なにいってだこいつ」としか返さない失礼極まりないBOTと相成ります。LINEのマニュアルから指定されたお決まりの文字列です。IPを固定するFixieサーバのプロキシ設定です。Fixieのページとマニュアルから、これらのコードを生成することができます。Herokuに設定した環境変数を読み込んでいます。取得することができます。serviceで生成したメッセージ情報から、LINEに送るためのオブジェクトを作ります。このオブジェクトをJSONに変換してあげることでLINEへのリクエストボディを生成することができます。プッシュ&デプロイmasterブランチにプッシュすると、自動でHerokuに展開されます。腹が立ちますが無事メッセージを受け取ることができました。次はToodledoからタスクを取得します。PlayアプリからToodledoのAPIを呼び出して、タスク一覧を取得するこれまでの手順でPlayアプリとLINEを連携することができました。原理としては、固定文言を返している部分を買い物リストにしてやればやりたいことが実現できそうです。次は、ToodledoのAPIを呼び出して買い物リストを取得してみましょう。以下の手続きを踏むことでタスク管理ができるようになります。順番に見ていきましょう。アプリケーションの登録http://api.toodledo.com/3/手順に従いアプリケーションを登録します。認証、アクセストークン取得OAuth認証を使っていますので、アプリケーションの認証を経てアクセストークンが発行されます。ここでは発行されたアクセストークンをPostgresqlに保存することがゴールとなるのですが、まずはアプリケーション認証が行われた後のリダイレクト先を用意してあげる必要があります。これもHerokuにデプロイしているアプリを使うこととし、リダイレクト先として/tasks/authエンドポイントを用意します。リダイレクトされ受けとった情報を使って、アクセストークンを取得、Slick経由でPostgresqlに保存します。認証について本家の手順が最もわかりやすいです。取得したアクセストークンを使って、こんどはタスクリストを取得します。Toodledoはいわゆる検索APIほど高機能ではなく、細かいパラメータ指定などがありません。条件にあてはまるタスクは全部返すからあとはクライアント側でよしなにやってね、という程度です。ゆえにリクエストパラメータもそこまで複雑ではありません。保存したアクセストークンを取得します。アクセストークンとともにタスク取得リクエストを行います。Jsonで返ってくるのですが、Arrayの先頭はメタ情報であるため除去しています。その上でアプリが解釈できるオブジェクトに変換しています。私はコンテキストというToodledoの機能を使って買い物リストを管理していますので、買い物リストに相当するコンテキストIDだけをフィルタします。Toodledoから抽出したタスクリストをLINEメッセージにはめこむ1でつくった単純なBOTのメッセージに、2で抽出したタスクリストを埋め込むようなイメージです。「買い物リストを取得する機能」も、「LINEに任意のメッセージを送る機能」も作成しましたので、あとはこれらを統合してやるサービスをひとつ作ってあげれば良さそうです。図では以下のようなイメージ。CallBackControllerから新しいサービスであるShoppingListReplyServiceをよぶようにします。ShoppingListReplyServiceの仕事は、「Toodledoから買い物リストを取得」して、「買い物リストをLINEのメッセージとして送信する」です。トレイトであるShoppingTaskRepositoryをShoppingTaskApiClientが具体化します。トレイトであるLineMessageSenderをMessageSendApiClientが具体化します。固定文言を返すところで示したものと全く同一です。渡すメッセージが変わっているだけです。ShoppingListReplyServiceの実装を見てみます。message)}sendメソッドのfor文に注目してください。記述内容はとてもシンプルで、買い物リストを取得した後、タイトルを取り出して文字列に変換します。それをそのままLINEへ送るメッセージとして指定しているだけです。先ほどは固定文言でしたが、今回は買い物リストにしていますので、これで買い物リストが取得できるようになるはずです。LINEのメッセージを「タスク閲覧」と「タスク追加」に振り分ける先で作ったプログラムは「タスクリストの抽出」ですが、同じようにToodledoのタスク追加APIを呼ぶことで、買い物リストの追加も行えます。XXX」というようにスペースを開けて何かしら文字列が続く場合はXXXを新しい買い物タスクとしてToodledoに登録するよう処理を振り分けてみましょう。OperationFileterというObjectを用意して、LINEから送られてきたメッセージによって処理を決定するヘルパー関数を作ります。{文字列}」というメッセージだった場合、買い物リストを追加するコマンドだと解釈します。「買い物」というメッセージだった場合、買い物リストを取得するコマンドだと解釈します。この関数を呼び出して、これまで実装してきたサービスを呼び分けることによって、送られてきたメッセージに対して適切な処理を行うことができるようになります。新しく買い物リストを追加するサービスとしてShoppingListAppendServiceを実装しました。買い物リスト取得の場合はShoppingListReplyServiceを利用。買い物リスト追加の場合はShoppingListAppendServiceを利用。それ以外の場合は固定文言を返すConstantMessageServiceを利用。masterブランチにプッシュしましょう。デプロイされるのを待ちます。年齢」と打つおわりにサーバサイドアプリを作成することで、LINEから買い物リストを管理できるようになりました。日常で誰かとメッセージのやりとりをしているとき、ついでにBOTに聞いて買い物リストをみることで、記憶だけが頼りだった状況から少し改善できたと感じています。世の中には多くのサービスがあり、それをすべて使いこなすのはとても大変です。マイクロサービスアーキテクチャをはじめ、特定のソリューションに特化したサービスが様々な箇所に散在する状況では、サーバサイドアプリによる統合はひとつの回答といえます。Toodledoも本当に使いこなそうと思うと多くの機能が用意されているのですが、「買い物リスト」と要件を絞ることで、BOTから使えるレベルにはシンプルになっています。必要なドメインに特化(買い物リスト)し、シンプル化(タスクタイトルの取得と追加のみ)、そして統合(LINE上でやりとり)という一連の流れが、今後の世の中では求められる考え方になると思います。847,394AWSを使ったサーバーレスアプリケーション構築が好きです。SPAからサーバーサイドまで設計・実装します。リモート】クラスメソッドの会社説明会を開催しますクラスメソッドでは、AWS・AI・ビッグデータ・モバイルなどの技術職や営業のメンバーとして一緒にお仕事をする仲間を大募集しています。#cmdevio新型コロナウイルスの感染拡大を受け、本イベントを延期させていただくことになりました(開催時期未定)。お申し込みいただいた皆様には大変申し訳ございませんが、何卒ご理解いただけますようよろしくお願いいたします。AWSについてライトに色んな情報交換をしましょう。カフェ店長のオカノです。今日はオフィスに用があるので、通勤ラッシュを避けて出社しました。この子は新メンバーのさめくんです。在宅勤務が推奨されているのでオフィスが閑散としており、すこしさみしそうです。本が出ていたので読んでみたところよかったので紹介させていただきます。使いたいときの注意点を書きました。新井成一64最近Sphinxつかってドキュメントを書いてるのですがなかなかイケています。臼田佳祐295ワークフロー自動化OSSのn8nをAWS環境で建てて検証してみました。非常に期待できるサービスです。Fargateの勉強をしています。使ってみたい方は参考にしてください。洋介255SnowflakeがAWSの東京リージョン上で稼働するようになりました。データを日本に置けます。芳賀健232こんにちは!猫様の忠実なるしもべ、芳賀健です。Tokyoで開催されました。カフェ店長のオカノです。クラスメソッド株式会社が運営するAWS・iOS・HTML5に関する技術情報サイトです。