22
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-06-23
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なので色々夢が広がります!アイディア色々あるので引き続き色々作ります。

22
16
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?