始めに
LINE WORKS Botチャット機能とwebアプリケーションを連携し、
webアプリケーション側からの送信機能、コールバック値を取得する機能
機能としては、大きく2つ
1、メッセージ通知(送信)
チャットボットを利用しLINE WORKS上のトークルームにメッセージ送信(ボタン付き)
2、コールバック取得
トークルームのチャット画面にて、送信されたボタン押下後に、
値がwebアプリケーション側にコールバックされる
環境
開発環境 | バージョン |
---|---|
LINE WORKS API | 2.0 |
Laravel | 8.60.0 |
PHP | 7.3.10 |
初期設定
1、LINE WORKS Developer consoleでアプリを作成する
2、アプリの OAuth Scopes を bot に設定する
3、Bot を作成する
4、Bot の API Interface を API 2.0に設定する
5、Bot の Callback URL を追加しておく(Botに送信可能なタイプ:テキスト)
6、チャット画面でトークルームを作成する
7、トークルームに 2、で作成した Bot を招待する
メッセージ通知に必要な情報を取得しておく
パラメータに必要な情報(5つ)
( ↓ Developer consoleのアプリ内 ↓ )
・Client ID
・Client Secret
・Service Account
・Private Key
( ↓ Developer consoleのBot内 ↓ )
・bot ID
( ↓ チャット画面の指定したいトークルームから取得可 ↓ )
・channel ID
取得方法の参考URL
https://qiita.com/kunihiros/items/54853e910ed1dff9ebdc
メッセージ通知(送信)
// LINE WORKSにメッセージ送信
public function sendLineWorks(Request $request)
{
Log::debug(__FUNCTION__)
try {
// 初期設定
$client_id = 'Client ID';
$client_secret = 'Client Secret';
$service_account_id = 'Service Account';
$private_key = 'Private Key'
// ------------------------------------------------------------------------
<<< EOM
-----BEGIN PRIVATE KEY-----
// ... 略
-----END PRIVATE KEY-----
EOM;
// ↑ Laravelの場合は、"<<< EOM", "EOM" をつける必要があった
// 生PHの場合は、"<<< EOM", "EOM" または、ダブルクオーテーション
// keyファイルを直接読み込むことも可能
// ------------------------------------------------------------------------
$bot_id = "bot ID";
$channel_id = "channel ID";
// トークンを取得する
$token = $this->service->lw_get_accesstoken($client_id, $client_secret, $service_account_id, $private_key);
// トークンが存在しない時
if(!$token) {
throw new Exception('トークンを取得できませんでした。');
}
// webhookURLを作成する(LINE WORKS トークルーム向け)
$user_message_api = 'https://www.worksapis.com/v1.0/bots/'.$bot_id.'/channels/'.urlencode($channel_id).'/messages'; // チャンネル用
// ヘッダー情報を配列に格納する
$headers = ['Content-Type' => 'application/json; charset=UTF-8',
'Authorization' => 'Bearer '.$token->access_token
];
// ペイロード情報を配列に格納する
$payload = [
"content"=> [
"type"=> "button_template",
"contentText"=> "あなたは、どちらに旅行したい?",
"actions"=> [[
// ボタン(上部)
"type"=> "message"
"label"=> "北海道"
], [
// ボタン(下部)
"type"=> "message",
"label"=> "沖縄"
]]
]
];
// HTTPリクエストを送信する
$response = \Http::withHeaders($headers)->post($user_message_api, $payload);
// レスポンスが成功した時
if($response->successful()) {
// 送信成功
Log::error(get_class($this).':'.__FUNCTION__);
// レスポンスが失敗した時
} else {
// エラー処理
Log::error(get_class($this).':'.__FUNCTION__);
}
} catch (Exception $e) {
// エラー処理
Log::error(get_class($this).':'.__FUNCTION__);
Log::error($e->getMessage());
}
}
use Firebase\JWT\JWT;
// アクセストークン取得
public function lw_get_accesstoken($client_id, $client_secret, $service_account_id, $private_key)
{
// 初期設定
$lw_auth_url = "https://auth.worksmobile.com/oauth2/v2.0/token";
// トークンを取得する
$token = $this->jwt_encode($client_id, $service_account_id, $private_key);
// ヘッダー情報を配列に格納する
$headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
$params = array(
'assertion' => $token,
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'client_id' => $client_id,
'client_secret' => $client_secret,
'scope' => 'bot',
);
try {
$client = new \GuzzleHttp\Client;
// HTTPリクエストを送信する
// レスポンスを取得する
$response = $client->post($lw_auth_url, [$headers, 'form_params' => $params]);
// ステータスコードを取得する
$status_code = $response->getStatusCode();
// 通信が成功した時
if($status_code == 200) {
return json_decode($response->getBody());
// 通信が失敗した時
} else {
// エラー処理
return false;
}
}
catch (\Exception $e) {
// エラー処理
Log::error(get_class($this).':'.__FUNCTION__);
Log::error($e->getMessage());
}
}
// エンコード処理
private function jwt_encode($client_id, $service_account_id, $private_key)
{
try{
$payload = array(
'iss' => $client_id,
'sub' => $service_account_id,
'iat' => time(),
'exp' => time() + 3600
);
// エンコード
$encodedInfo = JWT::encode($payload, $private_key,'RS256');
// エンコードされた値を返す
return $encodedInfo;
} catch (\Exception $e) {
// ログ出力
Log::error(get_class($this).':'.__FUNCTION__);
Log::error($e->getMessage());
}
}
firebase/php-jwtがないよ、みたいなエラーが出てきたので、下記のコマンドで解決。
(JWT のライブラリとして firebase/php-jwt がLaravelに入っていない場合)
composer require firebase/php-jwt
コールバック取得
// LINE WORKS からのコールバック値を取得
public function update(Request $request)
{
Log::debug(__FUNCTION__);
$callbackInfo = $request->all();
Log::debug($callbackInfo);
}
コールバックが取得できなくてはまりました。
CSRFトークンのチェックが原因でした。💦
VerifyCsrfToken.phpにCSRF保護から除外したいURIを記載するだけ!
参考URL LaravelでCSRF保護からURIを除外する
https://curecode.jp/tech/laravel-csrf-check-except-with-specified-referer-uri/
終わりに
参考URLの作成者様方に助けられて、本当に感謝です。ありがとうございます。
ご指摘、ご意見等ありましたら、メッセージいただけますとありがたいです。
よろしくお願いします。
LINE WORKS 参考資料まとめ
・公式ドキュメント
https://developers.worksmobile.com/jp/document?lang=ja
・API認証情報の取得方法まとめ
https://qiita.com/kunihiros/items/54853e910ed1dff9ebdc
・【Line works API 2.0】LaravelでBotからユーザーにメッセージを送信する
https://qiita.com/flatwhite/items/261b395adea70defe952