この記事は Akerun Advent Calendar 2019 - Qiita の17日目の記事です。
はじめに
はじめまして、先月Photosynthに入社したばかりのWebエンジニアのBunと申します。主にApp(iOS)開発を担当しています。 最近、Akerun Developersのメンテも行なっていますので、 Akerun API + いろんなサービスと連携して行こうと思います。
まず第一弾として、LINE Botと連携してみました。 LINEを使っている人は多いので、普段使っているLINEだけでAkerunの施錠解錠ができれば、めっちゃ楽になりますね。 以前LINE Botのグループ機能を使ったBot(LINE BOT AWARDS グループトーク部門賞)を作成した経験もあって、グループで使えるAkerun Botにする予定でしたが、内容が長くなってしまうので、2回に分けました。
- LINE Bot単体からAkerunを操作する。(今回の記事)
- LINE Botグループで機能を使って、グループ内のユーザーなら誰でもAkerunを操作できる。(後日公開予定)
※こちらの方が、ユーザーをグループに追加するだけで、簡単にAkerunを施錠解錠できるので、専用アプリが要らなくなるかも?!
その2はこちらです。
ちなみに14日目の記事ではAlexaと連携した内容が書かれていますので、興味がある方はぜひご参照ください。
Akerun APIを活用できれば、いろいろ面白いサービスを提供できそうですね。
事前準備
まず、AkerunProの接続、必要なAPIの利用申請、アカウント作成、サーバーサイトの準備を行います。
Akerun Proを接続
Akerun Remote経由でAkerun Proを操作できるように設定します。詳細についてAkerunサポートページをご参照ください。
Akerun APIを申請
Akerun Developersのお申し込みページからAkerun API利用申請を行います。
※Akerun ProとAkerun 入退室管理システムご利用いただいている場合のみお申込み可能です。
Akerun APIのアクセストークンを作成
Akerun Developersの認証ページの手順に従って、アクセストークンを作成します。
アクセストークンのスコープを設定
Akerun Managerの「連携アプリ」ページでスコープを設定する必要があります。 詳細についてAkerun Developersのスコープ設定ページをご参照ください。
LINE Providerを作成
LINEアカウントがあれば、LINE Developersにログイン(あるいはアカウント作成)可能です。
- Provider作成
LINE DevelopersのコンソールからProviderを作成します。
サーバーサイト(heroku)を準備
LINE Bot用のサーバーが必要ですので、手軽に使えるPaaSのherokuで実装したいと思います。
※無料範囲内の場合、一定時間アクセスが無いとスリープモードに入り、次回アクセス時少し時間が掛かります。
アカウントがない場合、上記herokuからアカウントを作成します。
- Messaging API channel作成
3つのチャンネルの中からBot用のMessaging API channelを作成します。
botアプリを作成
heroku-cliをインストール&ログイン
heroku-cliからダウンロード/インストールするか、以下のコマンドでダウンロード/インストールします。
loginすると、herokuのログインページが表示されるので、ログインします。
※必要な環境変数は後ほど設定します。
brew tap heroku/brew && brew install heroku heroku login
heroku appを作成
mkdir akerun-bot-demo cd akerun-bot-demo git init heroku create akerun-bot-demo Creating ⬢ akerun-bot-demo... done https://akerun-bot-demo.herokuapp.com/ | https://git.heroku.com/akerun-bot-demo.git git remote -v heroku https://git.heroku.com/akerun-bot-demo.git (fetch) heroku https://git.heroku.com/akerun-bot-demo.git (push)
※git initとheroku createの順番が逆になると、remoteにリポジトリが設定されないので、手動で設定します。(git remote add heroku {app url})
SDK/Libsイントール
pythonで実装するので、以下のLINE SDKと必要なlibsをインストールします。
※pythonは事前にインストールします。pyenvなどを使うと楽になります。
pip install line-bot-sdk pip install flask pip install requests pip install gunicorn
botを実装
- ベース部分実装
オウム返しのメインファイルbot.pyを作成します。
from flask import Flask, request, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import ( InvalidSignatureError ) from linebot.models import * app = Flask(__name__) line_channel_id = os.getenv('LINE_CHANNEL_ID') line_channel_secret = os.getenv('LINE_CHANNEL_SECRET') line_channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN') akerun_api_access_token = os.getenv('AKERUN_API_ACCESS_TOKEN') line_bot_api = LineBotApi(line_channel_access_token) handler = WebhookHandler(line_channel_secret) # test @app.route("/") def hello_bot(): return "akerun bot!" @app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: print("Invalid signature. Please check your channel access token/channel secret.") abort(400) return 'OK' @handler.add(MessageEvent, message=TextMessage) def handle_message(event): line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text)) if __name__ == "__main__": port = int(os.getenv("LINE_BOT_PORT", '5000')) app.run(host="0.0.0.0", port=port)
- Procfile作成(プログラムの実行方法を定義)
vi Procfile web: gunicorn bot:app --log-file=-
- Requirements.txt作成(インストールするライブラリの記載)
pip freeze > requirements.txt
- runtime.txt作成(Pythonのバージョンを記載
pythonバージョンは自分の環境に合わせてください。
vi runtime.txt python-3.8.0
- 環境設定
heroku上のbotアプリのSettingsページで環境変数を設定します。
※一旦任意の文字列を設定し、下記手順でAkerun API、LINE関連のトークンが取得できたら、更新します。
以下のherokuコマンドからも設定可能です。
heroku config:set LINE_CHANNEL_SECRET="" --app {app name} heroku config:set LINE_CHANNEL_ACCESS_TOKEN="" --app {app name} heroku config:set LIN_BOT_PORT=5000 --app {app name}
ローカル環境で確認する場合、以下のコマンドで環境変数を登録しておきます。
export LINE_CHANNEL_SECRET=xxx export LINE_CHANNEL_ACCESS_TOKEN=xxx export LIN_BOT_PORT=5000
ターミナルを再度開く時、上記の設定が消えてしまうので、必要な場合、~/.bash_profile(Mac)などに設定します。
vi ~/.bash_profile export LINE_CHANNEL_SECRET=xxx export LINE_CHANNEL_ACCESS_TOKEN=xxx export LIN_BOT_PORT=5000 source ~/.bash_profile
デプロイ
変更内容をコミットし、herokuへpushすると、自動的にherokuへデプロイされます。 https://akerun-bot-demo.herokuapp.com/にアクセスし、テストメッセージ「akerun bot!」が表示されればOKです。
git add . git commit -m "first commit" git push heroku master
ローカル動作確認環境作成
コードを変更する度にherokuへデプロイするのは面倒なので、ngrokを使用して、localhostを外部に公開できるようにします。
- ngrokにログイン(或いはサインイン)し、ngrokをダウンロードする。
- ダウンロードしたngrok(zip)を任意のディレクトリに解答する。
- ngrokにログイン後、トークンをコピーし、以下の実行する
cd ngrok解凍ディレクトリ ./ngrok authtoken xxx
- ローカルでbot.pyを実行し、外部に公開する。
※LINE Botのwebhookに設定するので、外部公開URL(https://xxxx.ngrok.io)をメモしておく。
python bot.py ngrok http 5000 ngrok by @inconshreveable (Ctrl+C to quit) Session Status online Account xxx (Plan: Free) Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://xxx.ngrok.io -> http://localhost:5000 Forwarding https://xxxx.ngrok.io -> http://localhost:5000
Akerun施錠解錠処理を実装
まず、施錠解錠するための最小限の実装を行います。Akerun APIの詳細についてAkerun Developersをご参照ください。
# 組織一覧を取得 def akerun_bot_get_organizations(akerun_token): ak_url = 'https://api.akerun.com/v3/organizations' ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 組織詳細情報を取得 def akerun_bot_get_organization_info(akerun_token, org_id): ak_url = 'https://api.akerun.com/v3/organizations/{}'.format(org_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 組織に属するAkerunの一覧を取得 def akerun_bot_get_akeruns(akerun_token, org_id): ak_url = 'https://api.akerun.com/v3/organizations/{}/akeruns'.format(org_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 施錠リクエストを送信 def akerun_bot_lock(akerun_token, org_id, akerun_id): ak_url = 'https://api.akerun.com/v3/organizations/{}/akeruns/{}/jobs/lock'.format(org_id, akerun_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 施錠結果を取得 def akerun_bot_lock_state(akerun_token, org_id, job_id): ak_url = 'https://api.akerun.com/v3/organizations/{}/jobs/lock/{}'.format(org_id, job_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 解錠リクエストを送信 def akerun_bot_unlock(akerun_token, org_id, akerun_id): ak_url = 'https://api.akerun.com/v3/organizations/{}/akeruns/{}/jobs/unlock'.format(org_id, akerun_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # 解錠結果を取得 def akerun_bot_unlock_state(akerun_token, org_id, job_id): ak_url = 'https://api.akerun.com/v3/organizations/{}/jobs/unlock/{}'.format(org_id, job_id) ak_headers = {'Authorization': 'Bearer ' + akerun_token} return akerun_bot_api(ak_url, ak_headers) # Akerun APIをCall def akerun_bot_api(url, headers): obj_session = Session() obj_request = Request("POST", url, headers=headers ) obj_prepped = obj_session.prepare_request(obj_request) obj_response = obj_session.send(obj_prepped, verify=True, timeout=60 ) print('status_code:' + str(obj_response.status_code)) print('obj_response.text:' + obj_response.text) response_dict = json.loads(obj_response.text) print(response_dict) #return response_dict.job.id return response_dict['job']['id']
LINE Botを設定
Messaging API channelを作成
LINE DevelopersのProviderにアクセスし、channelを作成します。
必須項目を入力し、channelを作成します。
secretとtokenを取得
作成したchannelの設定ページからChannel secretとChannel access tokenを取得します。
webhookを設定
LINEユーザーのメッセージ(Akerun操作コマンド)をbot(herokuアプリ)に送信するために、Messaging API ページでwebhookを設定します。
botの応答設定
ユーザーがメッセージを送信する度に自動的に応答メッセージが返ってくるので、一旦無効にします。
応答メッセージ編集画面に遷移
応答メッセージ編集画面に遷移 応答メッセージをOFF
その他設定はデフォルトのまま(ON)でOKです。
リッチメニュー作成
ユーザーが施錠解錠ボタン(画像)を押して、Akerunを施錠解錠できるようにリッチメニューを作成します。
※詳細についてリッチメニューを新規作成するをご参照ください。
LINE Official Account Managerにログインし、アカウントリストからアカウント(bot)を選択する
LINE Official Account Managerに遷移し、アカウントを選択 リッチメニューを新規作成
- 基本設定を行う
タイトルと表示期間を設定し、テンプレートを選択します。その他設定はデフォルト設定でOKです。
- テンプレートを選択
- 施錠解錠コマンドを設定
アクションBとDのタイプをテキストに設定し、それぞれ「>lock」、「>unlock」コマンドのテキストを入力します。
※Prefix「>」はその他コマンドと区別する為に設定していますが、無くても問題ありません。
- 施錠解錠の画像を作成する
「画像作成」画面で施錠解錠の画像をアップロードし、画像の下にテキストを追加します。位置は設定メニューで簡単に調整可能です。
- 設定を保存し、LINE上で確認する
上記の設定を保存します。LINE Developersに戻って、「Messaging API設定」ページのQRコードからbotを追加します。
以下のメニューが表示されます。
連携する
Akerun APIから施錠解錠の実装とLINE Botの施錠解錠(リッチメニュー)を作成しましたので、LINEから施錠解錠メニュー(画像)を押した時の動作を実装します。
handle_messageに以下の処理を追加します。施錠(>lock)/解錠(>unlock)コマンドを受信したら、それぞれ施錠解錠リクエストを送信します。
※全体コードは別途公開する予定ですが、Akerunの組織ID、AkerunIDはAkerun Developersを参考に取得してください。
※また、リクエストを送信してから施錠解錠結果をポーリングする必要がありますが、簡単にする為、リクエスト直後そのまま結果をユーザーに返しています。
@handler.add(MessageEvent, message=TextMessage) def handle_message(event): reply_msgs = [] akerun_token = akerun_api_access_token org_id = 'xxxx' akerun_id = 'xxxx' if event.message.type == 'text': if event.message.text[0] == cmd_prefix: cmd = event.message.text if cmd == cmd_prefix + 'lock': # 施錠リクエストを送信 akerun_bot_lock(akerun_token, org_id, job_id) reply_msgs.append(TextSendMessage(text=u'施錠')) elif cmd == cmd_prefix + 'unlock': # 解錠リクエストを送信 akerun_bot_unlock(akerun_token, org_id, job_id) reply_msgs.append(TextSendMessage(text=u'解錠')) if len(reply_msgs): line_bot_api.reply_message( event.reply_token, reply_msgs)
施錠
botのメニューからLOCKを押します。少しタイムラグはありますが、施錠できました。
解錠
botのメニューからUNLOCKを押します。こちらも少しタイムラグはありますが、解錠できました。
まとめ
長文になってしまいましたが、無事LINE BotからAkerunを施錠解錠ができました!
- Akerun APIを利用するには、申し込み申請が必要で、アクセストークンを発行するまで結構手間がかかります。これについては改善していきたいと思います。アクセストークンさえ発行できれば、API自体はシンプルで使いやすいのではないかと思います。
- 内容からも分かると思いますが、LINEの設定項目がたくさんあります。ただ、操作しやすいUIになっているので、それ程難しくはないですね。
- その2ではLINE Botグループ機能を入れて、Botアプリを完成させたいと思います。Akerun APIのアクセストークン、組織ID、AkerunIDについて、ハードコーディングではなく、Bot上で選択出来るようにします。
- その2が完了後、ソースコードをgithubに上げる予定です。実際のBotも期間限定で公開してみようかと思います。
株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co
Akerun Proの購入はこちらから akerun.com