ちっす!まじふわ系(マジでフワフワしてる系)エンジニアのmajihuwaっす!
題名なんすけど、twitterのapiとyoutubeのapi使ってbot作ったって話しっす!
bot
こちら https://twitter.com/KeyYackman
使い方:
botをフォローしてもらって
@KeyYackman 音楽名
とメンションしてもらうと、youtubeから音楽名で検索して返信してくれる系っすね!
作った過程
streaming api
https://dev.twitter.com/streaming/overview
こちらからtwiiter?に対してapi叩いてデータ取りにいくんじゃなくて、エンドポイントに対して接続をつなぎっぱにして、twitter側でイベントが発生した時にpushしてくれる系みたいっす。
でstreaming apiから得たidとかtextとかをエスケープしてDBに放りこんでます。
<?php
function saveMention($id_str,$text,$screen_name){
$user = 'xxx';
$password = 'xxx';
$isPost = false;
try{
$pdo = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8',$user,$password);
}catch (PDOException $e){
print('DB Connect Error:'.$e->getMessage());
die();
}
// hoge....
}
$consumer_key = '....';
$consumer_secret = '....';
$oauth_token = '....';
$oauth_token_secret = '....';
$url = 'https://userstream.twitter.com/1.1/user.json';
$method = 'GET';
// パラメータ
$oauth_parameters = array(
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => microtime(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_token' => $oauth_token,
'oauth_version' => '1.0',
);
//パラメータ
$get_parameters = array(
'track' => 'screen_name'//ここを取得したいscreen_nameに変更
);
// 署名を作る
$a = array_merge($oauth_parameters, $get_parameters);
ksort($a);
$base_string = implode('&', array(
rawurlencode($method),
rawurlencode($url),
rawurlencode(http_build_query($a, '', '&', PHP_QUERY_RFC3986))
));
$key = implode('&', array(rawurlencode($consumer_secret), rawurlencode($oauth_token_secret)));
$oauth_parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $key, true));
// 接続&データ取得
$fp = fsockopen("ssl://userstream.twitter.com", 443);
if ($fp) {
fwrite($fp, "GET " . $url . ($get_parameters ? '?' . http_build_query($get_parameters) : '') . " HTTP/1.1\r\n"
. "Host: userstream.twitter.com\r\n"
. 'Authorization: OAuth ' . http_build_query($oauth_parameters, '', ',', PHP_QUERY_RFC3986) . "\r\n"
. "\r\n");
while (!feof($fp)) {
$res = fgets($fp);
$res = json_decode($res, true);
if(gettype($res) == "array"){
if( isset($res["entities"]["user_mentions"]) ){
saveMention($res["id_str"],$res["text"],$res["user"]["screen_name"]);//DBに保存
}
}
}
fclose($fp);
}
twitter api
こちらのapi https://dev.twitter.com/rest/reference/post/statuses/update を使ってpostっすね
<?php
// OAuthライブラリの読み込み
require "twitterOAuth/vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
$dir=dirname(__FILE__);
require_once("$dir/config.php");
//tweetHandlerクラス
class tweetHandler{
private $twObj;
public $mentionsArray;
function __construct(){
$consumerKey = API_KEY;
$consumerSecret = API_SECRET;
$accessToken = ACCESS_TOKEN;
$accessTokenSecret = ACCESS_SECRET;
$this->twObj = new TwitteroAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);
$this->mentionsArray = array();
}
//メンション取得のデバッグ表示
function displayMentions(){
echo "mentions are = \n";
var_dump($this->mentionsArray);
echo "--------------------------- \n";
}
//メンション取得
function getMentionsDB(){
$user = USER;
$password = PASSWORD;
try{
$pdo = new PDO('mysql:host=localhost;dbname=dbname;',$user,$password);
}catch (PDOException $e){
print('DB Connect Error:'.$e->getMessage());
die();
}
$isPost = false;
$stmt = $pdo -> prepare("SELECT * FROM mentions WHERE isPost=:isPost");
$stmt -> bindValue(':isPost', $isPost, PDO::PARAM_BOOL);
$stmt->execute();
while($rows = $stmt -> fetch()){
$tmpArray = array("screen_name"=>"","music_name"=>"","reply_id"=>"");
preg_match("/^@KeyYackman (.*)$/",$rows["text"],$music_name);
$tmpArray["screen_name"] = $rows["screen_name"];
$tmpArray["reply_id"] = $rows["tweet_id"];
if($music_name){
$tmpArray["music_name"] = $music_name[1];
array_push($this->mentionsArray,$tmpArray);
}
}
$pdo = null;
return $this->mentionsArray;
}
//postする機能
function post($mes,$rep_id,$screen_name){
$jsonRes;
//リプライ用IDとscreen_nameが存在する場合はメンションで返信する
if(!empty($rep_id) and !empty($screen_name)){
$jsonRes=$this->twObj->post("statuses/update", array("status" => "@".$screen_name." ".$mes, 'in_reply_to_status_id'=>(int)$rep_id));
$this->updateIsPost((string)$rep_id);
}
}
function updateIsPost($tweet_id){
$user = USER;
$password = PASSWORD;
try{
$pdo = new PDO('mysql:host=localhost;dbname=dbname;',$user,$password);
}catch (PDOException $e){
print('DB Connect Error:'.$e->getMessage());
die();
}
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$is = true;
$stmt = $pdo -> prepare("update mentions set isPost=:is WHERE tweet_id=:tweet_id");
$stmt -> bindParam(':is', $is, PDO::PARAM_BOOL);
$stmt -> bindParam(':tweet_id', $tweet_id, PDO::PARAM_STR);
$stmt -> execute();
$pdo = null;
}
}
?>
youtube api
search api : https://developers.google.com/youtube/v3/guides/implementation/search?hl=ja
search apiを使ってエスケープした音楽名を検索っす!
<?php
$dir = dirname(__FILE__);
require_once "$dir/google-api-php-client/vendor/autoload.php";
require_once "$dir/config_youtube.php";
class searchMusic
{
public function search($name)
{
// Call set_include_path() as needed to point to your client library.
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* Google Developers Console <https://console.developers.google.com/>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = DEVELOPER_KEY;
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $name,
'type' => 'video',
'videoCategoryId' => 10,
'maxResults' => 1,
));
$videos = '';
$channels = '';
$playlists = '';
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach ($searchResponse['items'] as $searchResult) {
switch ($searchResult['id']['kind']) {
case 'youtube#video':
$videos .= sprintf('https://www.youtube.com/watch?v=%s %s',
$searchResult['id']['videoId'], $searchResult['snippet']['title']);
break;
}
}
} catch (Google_Service_Exception $e) {
echo sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
echo sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
return $videos;
}
}
?>
'videoCategoryId' => 10を見つけるのに戸惑ったっすね!
参考にしたサンプルっす
https://developers.google.com/youtube/v3/code_samples/php?hl=ja#search_by_keyword
今後
特に工夫なく検索しているので、そこっすね!
あと、hubot?とかいうやつがあるらしいんで、次はそれ試してみる系っすね!