LoginSignup
6
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-31

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

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

bot

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

使い方:

botをフォローしてもらって

@KeyYackman 音楽名

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

スクリーンショット 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?とかいうやつがあるらしいんで、次はそれ試してみる系っすね!

6
5
0

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
6
5