twitterのtimelineにさ、音楽が流れると素敵かなと思ってさ


ちっす！まじふわ系(マジでフワフワしてる系)エンジニアのmajihuwaっす！

題名なんすけど、twitterのapiとyoutubeのapi使ってbot作ったって話しっす！

## bot
こちら https://twitter.com/KeyYackman

## 使い方:
botをフォローしてもらって

```
@KeyYackman 音楽名
```
とメンションしてもらうと、youtubeから音楽名で検索して返信してくれる系っすね！

![スクリーンショット 2015-12-31 21.56.13.png](https://qiita-image-store.s3.amazonaws.com/0/107550/6c379892-c30e-f77c-89b4-714efcdd9b38.png "スクリーンショット 2015-12-31 21.56.13.png")



# 作った過程

### 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);
}
```


参考：http://goo.gl/LL3Ry6


### 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?とかいうやつがあるらしいんで、次はそれ試してみる系っすね！