Edited at

Heroku × LINEBot × Twitterで猫Botを作ってみた

More than 1 year has passed since last update.


最初に


  • ネタ的には多くの猫好きエンジニアがやりそうなこと・・・。

  • 2016年12月頃に作ったものなので色々古いかもです。

  • 当初の構成図ではラズパイとwebカメラを使用してIoT的な監視botを作りたかったのですが運用開始直前に家庭内稟議で否認され実現できませんでした:sob:


    • 電気代の問題

    • 猫のプライバシー問題



  • 各種設定は参考サイトが詳しいのでここでは作成までの道のりを記載します。


構成図


初期

猫Bot初期構成図.jpg


現実

猫Bot妥協構成図.jpg


heroku設定


初期設定

@Arashiさんの記事を参考にさせて頂きました。

参考)http://qiita.com/Arashi/items/b2f2e01259238235e187


fixieインストール

LINE BOT API の呼び出しには Server IP Whitelist に接続元 IP の指定が必要なのでこいつが必要

https://elements.heroku.com/addons/fixie

@yuya_takeyamaさんの記事を参考にさせて頂きました。

参考)https://qiita.com/yuya_takeyama/items/0660a59d13e2cd0b2516


config設定方法

http://dackdive.hateblo.jp/entry/2016/01/26/121900


LINE設定


BOT APIの登録

https://at.line.me/jp/

https://www.panzee.biz/archives/9115


APIリファレンス

https://developers.line.me

https://devdocs.line.me/ja/?php#reply-message


twitter設定


twitterアプリケーション登録

https://dev.twitter.com/apps


twitterSDK

https://github.com/abraham/twitteroauth


PHPでTwitterのツイートを取得・表示する方法

http://2m3g1.com/751.html


heroku上に設定する環境変数

値は各個人の設定に変えてあげてください。


heroku.config

heroku config:set LINE_TOKEN=LINE_TOKEN_HOGE

heroku config:set FIXIE_URL=HEROKU_FIXIE_URL
heroku config:set APP_NAME=HEROKU_APP_NAME
heroku config:set tw_consumer_key=TW_CONSUMER_KEY
heroku config:set tw_consumer_secret=TW_CONSUMER?SECRET
heroku config:set tw_access_token=TW_ACCESS_TOKEN
heroku config:set tw_access_token_secret=TW_ACCESS_SECRET


heroku上にデプロイしたアプリケーションのディレクトリ設定

以下のように配置します。

|--index.php ← LINEとTwitterをごにょごにょするプログラム

|--twitteroauth ← twitterのSDK
| |--.gitignore
| |--.travis.yml
| |--LICENSE.md
| |--README.md
| |--autoload.php
| |--composer.json
| |--phpmd.xml
| |--phpunit.xml
| |--src
| | |--Config.php
| | |--Consumer.php
| | |--HmacSha1.php
| | |--Request.php
| | |--Response.php
| | |--SignatureMethod.php
| | |--Token.php
| | |--TwitterOAuth.php
| | |--TwitterOAuthException.php
| | |--Util
| | |--Util.php
| | | |--JsonDecoder.php
| | |--cacert.pem


プログラム


index.php

<?php

//--------------------------------
// Line Input
//--------------------------------
$php_input = json_decode(file_get_contents('php://input'));
$text = $php_input->{"events"}[0]->{"message"}->{"text"};
$reply_token = $php_input->{"events"}[0]->{"replyToken"};

//--------------------------------
// Create Media By Twitter
//--------------------------------
$response_content = getResponseContent($reply_token,$text);

//--------------------------------
// Line Bot
//--------------------------------
postLineBot($response_content);

function createHttpHeader() {
$header = array(
'Content-Type: application/json; charset=UTF-8',
'Authorization: Bearer '.getenv("LINE_TOKEN")
);
return $header;
}
function getResponseContent($reply_token,$text) {
if((strpos($text, '絹') !== false) || (strpos($text, '鱈') !== false)){
return createImageResponse($reply_token);
}
return createTextResponse($reply_token,"はらへった〜");

}
function createTextResponse($reply_token,$message) {
$response_format_text = [
"type" => "text",
"text" => $message
];

$post_data = array(
"replyToken" => $reply_token,
"messages" => [$response_format_text]
);

return $post_data;
}
function createImageResponse($reply_token) {
$tw_auth = getTwitterAuth();
$req = $tw_auth->get("statuses/user_timeline",array("count"=>"5"));
$media_url = array();
foreach($req as $key => $val){
$media_url[] = [
"type" => "image",
"originalContentUrl" => $val->entities->media[0]->media_url_https.":small",
"previewImageUrl" => $val->entities->media[0]->media_url_https.":thumb"
];
}

if(count($media_url) === 0) return createTextResponse($reply_token,"ねむい〜");

$media_id = mt_rand(0,count($media_url)-1);
$post_data = array(
"replyToken" => $reply_token,
"messages" => [$media_url[$media_id]]
);

return $post_data;
}

function getTwitterAuth() {
require_once("./twitteroauth/autoload.php");
$consumer_key = getenv("tw_consumer_key");
$consumer_secret = getenv("tw_consumer_secret");
$access_token = getenv("tw_access_token");
$access_token_secret = getenv("tw_access_token_secret");
$to = new \Abraham\TwitterOAuth\TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);
return $to;
}

function postLineBot($response_content){
$ch = curl_init("https://api.line.me/v2/bot/message/reply");

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($response_content));
curl_setopt($ch, CURLOPT_HTTPHEADER, createHttpHeader());
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, getenv("FIXIE_URL"));
curl_setopt($ch, CURLOPT_PROXYPORT, 80);
$result = curl_exec($ch);
curl_close($ch);
}



デモ


その他参考サイト

http://qiita.com/chibi929/items/a368fdc3ef3485302302

http://qiita.com/ttskch/items/7c148fcc595cec4aa59a

http://qiita.com/kurouw/items/f00229e51818d80ae643

http://qiita.com/TetsuyaImagawa/items/7517b287e68efe21c0cc

http://qiita.com/Kosuke-Szk/items/eea6457616b6180c82d3


その他参考サイト(qiita以外)

http://m-shige1979.hatenablog.com/entry/2016/10/14/080000

http://ola.kironono.com/entry/2016/04/09/205251

http://iti.hatenablog.jp/entry/2016/04/27/113053

http://furyu.hatenablog.com/entry/20160225/1456353020