PHP
Line
linebot
LINEmessagingAPI

LINE Messaging APIがグループ内でユーザーを認識できるようになったのでトーク管理&アルバム化Bot作ってみた

More than 1 year has passed since last update.

IMG_1341.PNG

LINE Messaging APIがグループ内でユーザーを認識できるようになったので、前から作りたかったグループにBot入れとけばトーク全部保存しといてくれて、後から2016年度とかの区切りでトークをまとめてリアルなアルバムにして郵送してくれるようなサービスのデモを作ってみました。


Botの準備

ググれば情報出てくるので適当に。または拙著「LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例」を見て下さい。

book.png


実装

こんな感じ。暗号化やってないので適宜。


index.php

// Composerでインストールしたライブラリを一括読み込み

require_once __DIR__ . '/vendor/autoload.php';

define('TABLE_NAME_MESSAGES', 'messages');

// アクセストークンを使いCurlHTTPClientをインスタンス化
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
// CurlHTTPClientとシークレットを使いLINEBotをインスタンス化
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);
// LINE Messaging APIがリクエストに付与した署名を取得
$signature = $_SERVER['HTTP_' . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE];

// 署名が正当かチェック。正当であればリクエストをパースし配列へ
// 不正であれば例外の内容を出力
try {
$events = $bot->parseEventRequest(file_get_contents('php://input'), $signature);
} catch(\LINE\LINEBot\Exception\InvalidSignatureException $e) {
error_log('parseEventRequest failed. InvalidSignatureException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\UnknownEventTypeException $e) {
error_log('parseEventRequest failed. UnknownEventTypeException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\UnknownMessageTypeException $e) {
error_log('parseEventRequest failed. UnknownMessageTypeException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\InvalidEventRequestException $e) {
error_log('parseEventRequest failed. InvalidEventRequestException => '.var_export($e, true));
}

// 配列に格納された各イベントをループで処理
foreach ($events as $event) {
// MessageEventクラスのインスタンスでなければ処理をスキップ
if (!($event instanceof \LINE\LINEBot\Event\MessageEvent)) {
error_log('Non message event has come');
continue;
}

if(!$event->isGroupEvent()) {
$bot->replyText($event->getReplyToken(), 'Add this Bot to Group.');
continue;
}

if ($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessage) {

if($event->getText() == 'cmd_album') {
replyMultiMessage($bot, $event->getReplyToken(),
new \LINE\LINEBot\MessageBuilder\TextMessageBuilder("以下のリンクをクリックするとトークのアルバムをプレビューできます。"),
new \LINE\LINEBot\MessageBuilder\TextMessageBuilder("http://" . $_SERVER["HTTP_HOST"] . "/album/" . $event->getGroupId())
);
continue;
}

appendMessage($event->getUserId(), $event->getGroupId(), $event->getTimestamp(), $event->getMessageId(), $event->getMessageType(), $event->getText());
} else if($event instanceof \LINE\LINEBot\Event\MessageEvent\ImageMessage) {

$response = $bot->getMessageContent($event->getMessageId());
$fileUrl = uploadImageToCloudAppThenGetUrl($response->getRawBody());
appendMessage($event->getUserId(), $event->getGroupId(), $event->getTimestamp(), $event->getMessageId(), $event->getMessageType(), $fileUrl);

} else if($event instanceof \LINE\LINEBot\Event\MessageEvent\StickerMessage) {
appendMessage($event->getUserId(), $event->getGroupId(), $event->getTimestamp(), $event->getMessageId(), $event->getMessageType(), json_encode(array('packageID' => $event->getPackageId(), 'stickerId' => $event->getStickerId())));
} else {
$bot->replyText($event->getReplyToken(), '未対応のメッセージ形式');
}
}

function appendMessage($userId, $groupId, $timestamp, $messageid, $messageType, $messageBody) {
$dbh = dbConnection::getConnection();
$sql = 'insert into '. TABLE_NAME_MESSAGES .' (userid, groupid, timestamp, messageid, messagetype, messagebody) values (?, ?, ?, ?, ?, ?) ';
$sth = $dbh->prepare($sql);
$sth->execute(array($userId, $groupId, $timestamp, $messageid, $messageType, $messageBody));

}

function uploadImageToCloudAppThenGetUrl($rawBody) {
\Cloudinary::config(array(
"cloud_name" => "xxxxxxxxx",
"api_key" => "0123456789123",
"api_secret" => "xxxxxxxxxxxxxxxxxx"
));

$im = imagecreatefromstring($rawBody);
$resultString = "";
if ($im !== false) {
$filename = uniqid();
$directory_path = "tmp";
if(!file_exists($directory_path)) {
if(mkdir($directory_path, 0777, true)) {
chmod($directory_path, 0777);
}
}
imagejpeg($im, $directory_path. "/" . $filename . ".jpg", 75);
} else {
error_log("fail to create image.");
}

$path = dirname(__FILE__) . '/' . $directory_path. "/" . $filename . ".jpg";
$result = \Cloudinary\Uploader::upload($path);
error_log('result : ' . var_export($result, true));

return $result['url'];
}



データベース

DBを作ってユーザーID、グループID、タイムスタンプ、メッセージタイプ、メッセージの内容を格納できるテーブル作っときます。


格納

Eventから内容取ってDBに入れてくだけ。スタンプとか絵文字とかの処理は面倒なので後回し。

画像のみアップロードしてURLを格納しとく。


画像のアップロード

Herokuだと普通に保存しといてもデプロイする度に画像消えるのでCloudinaryのアドオン使いました。ある程度は無料でめちゃ簡単。


プレビューページ

グループID受け取ってDBなめてトーク取り出して表示するだけ。


デモ

グループに作って、家族とBotを招待します。Botは管理画面でグループに参加できるよう設定しておきましょう。

IMG_1338.PNG

また、被招待側はグループへの参加と共にBotと友だちになっておく必要があります。ユーザーIDは友達になっていなくても取れるのですが、これがないとユーザー名やプロフィール画像等のProfile取ろうとしてもNot Foundになります。適当にトークします。

IMG_1339.PNG

アルバムのプレビューをしたい時はコマンド送ります。

IMG_1340.PNG

プレビューが表示され、アルバムの注文ボタンが。タップすると印刷されたアルバムが郵送されます。背景とかレイアウトいじれるといいでしょうね。

pureview.png


まとめ

相変わらずとても使いやすいAPIなので色々夢が広がります!アイディア色々あるので引き続き色々作ります。