Twitter botを作成してみた


phpでtwitterのbotを作ってみた。
こちらの「日本文学bot」は、CSVに記載された名言をランダムにつぶやき続けている。
https://twitter.com/context2017jp

##Twitter bot のソース
「consumerKey」と「consumerSecret」、「accessToken」、「accessTokenSecret」を書き換えてください。
こちらの認証キーの取得はこちらのサイトを参考にするとわかりやすいです。
http://dotnsf.blog.jp/archives/1044796238.html

```twitter.php
#!/usr/bin/php
<?php
require "amazon/amazon_make_url.php";
require "amazon/google_url_short.php";
// OAuthライブラリの読み込み
require 'twitteroauth/autoload.php';
use Abraham\TwitterOAuth\TwitterOAuth;

//認証情報４つ
$consumerKey = "独自のコンシュマーキー";
$consumerSecret = "独自のコンシュマーシークレットキー";
$accessToken = "twitterトークン";
$accessTokenSecret = "twitterトークンシークレットキー";

//接続
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);

//メッセージの作成
$array = array();
$lines = file('sentence_list.csv');
foreach($lines as $line){
  $data = explode(',',$line);

  $detaName = $data[2].",".$data[3];
  $amazon_url = amazonURLmaker($detaName);
  $amazon_short = googleURLshort($amazon_url);

  $line_text = $data[1]."\n"."#".$data[2]." #".$data[3]." #日本文学　".$amazon_short;


  $twitterletterNum = mb_strlen($line_text);

  if ($twitterletterNum >= 140):
    $sabunNum = $twitterletterNum - 150;
    $dataReplace = mb_substr($data[1], 0 ,$sabunNum,"SJIS");
    $line_text = $dataReplace."...\n"."#".$data[2]." #".$data[3]." #日本文学　".$amazon_short;
  endif;

  array_push($array, $line_text);
}
//shuffle($array); //配列をシャッフル
$i = mt_rand(1, count($array));
//$key = array_rand($array);
$message = $array[$i];

//ツイート
$res = $connection->post("statuses/update", ["status" => $message]);

//レスポンス確認
var_dump($res);
?>
```
### twitterのトークンをもっと手軽に
twitterのトークンを簡単に行うために、TwitterOAuthをダウンロードしてきます。
https://github.com/abraham/twitteroauth

こちらからプログラムを拝借して、このphpにキーを飛ばすと簡単にtwitterにつながります。

##Amazonのアフェリエイト
Twitterのトークンのやりとりがめちゃめちゃ簡単にできて、その後もスムーズにphpを組めたので、勢いづいて、名言の著者と作品でamazonアフェリエイトを設定してみました。
このソースはこちらを参照しました。
http://www.dn-web64.com/archives/web/amazon-api/
https://runble1.com/amazon-api-php-xml/

これもtwitterと同じで、アクセスキーなどを変換してください。

```amazon_make_url.php
#!/usr/bin/php
<?php
function amazonURLmaker($titleName){
$aws_access_key_id = 'アマゾンアクセスキーid';
$aws_secret_key = 'アマゾンシークレットキー';
$AssociateTag='アクションタグ';

//URL生成
$endpoint = 'webservices.amazon.co.jp';
$uri = '/onca/xml';

	//パラメータ群
	$params = array(
		'Service' => 'AWSECommerceService',
		'Operation' => 'ItemSearch',
		'AWSAccessKeyId' => $aws_access_key_id,
		'AssociateTag' => $AssociateTag,
		'SearchIndex' => 'Books',
		'ResponseGroup' => 'Medium',
		'Keywords' => $titleName,
		'ItemPage' => 1
	);

  //timestamp
	if (!isset($params['Timestamp'])) {
		$params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
	}

  //パラメータをソート
	ksort($params);

	$pairs = array();
	foreach ($params as $key => $value) {
		array_push($pairs, rawurlencode($key).'='.rawurlencode($value));
	}

  //リクエストURLを生成
	$canonical_query_string = join('&', $pairs);
	$string_to_sign = "GET\n".$endpoint."\n".$uri."\n".$canonical_query_string;
	$signature = base64_encode(hash_hmac('sha256', $string_to_sign, $aws_secret_key, true));
	$request_url = 'http://'.$endpoint.$uri.'?'.$canonical_query_string.'&Signature='.rawurlencode($signature);

	$amazon_xml=simplexml_load_string(@file_get_contents($request_url));//@はエラー回避

//検索結果からURLを生成
$arryURL = array(); //URL格納配列

	foreach((object)$amazon_xml->Items->Item as $item_a=>$item){
		$detailURL=$item->DetailPageURL;//商品のURL
    $CutdetailURL = explode("/", $detailURL); //文字列をスラッシュで分解
    $CutdetailURLCount =count($CutdetailURL);
    $codedetailURL = explode("&", $CutdetailURL[5]);
    $bookNum = explode("=", $codedetailURL[5]);

    $newURL = "https://www.amazon.co.jp/gp/product/".$bookNum[1]."?ie=UTF8&".$codedetailURL[3]."&".$codedetailURL[4]."&".$codedetailURL[5]."&linkCode=shr&tag=submarinenet-22";

    //配列に新しURLを格納
    array_push($arryURL, $newURL);

		print PHP_EOL;
	}

	//1秒おく
	sleep(1);
  $y = mt_rand(1, count($arryURL));
  $mainURL = $arryURL[$y];

  return $mainURL;
}
?>
```

これで、名言に関連する書籍がamazonで検索されて、twitterで呟かれることになります。
結局、アクセスするURLにパラメーターをつけて、飛ばすだけなんですよね。
それで、結果が返ってくるんだからすごく簡単。
ただ、この時点では、140文字を超えてしまうので、URLを圧縮する必要があります。
そのために、googleの短縮URLで短縮させます。

##googleの短縮URL
この辺を参考にさせてもらいました。
https://syncer.jp/how-to-make-shoten-url
例のごとくAPIのキーを取得して変更してください。

```google_url_short.php
#!/usr/bin/php
<?php
function googleURLshort($urlData){

  // APIキーの設定
  $api_key = 'APIキー' ;

  // 元のURL
  $before_url = $urlData;

  // GETメソッドで指定がある場合は上書き
  if( isset( $_GET['url'] ) && !empty( $_GET['url'] ) ) {
    $before_url = $_GET['url'] ;
  }

  // cURLを利用してリクエスト
  $curl = curl_init() ;
  curl_setopt( $curl, CURLOPT_URL , 'https://www.googleapis.com/urlshortener/v1/url?key=' . $api_key ) ;
  curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Content-type: application/json' ) ) ;	// JSONの送信
  curl_setopt( $curl, CURLOPT_CUSTOMREQUEST , 'POST' ) ;			// POSTメソッド
  curl_setopt( $curl, CURLOPT_POSTFIELDS, json_encode( array( 'longUrl' => $before_url ) ) ) ;		// 送信するJSONデータ
  curl_setopt( $curl, CURLOPT_HEADER, 1 ) ;						// ヘッダーを取得する
  curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false ) ;			// 証明書の検証を行わない
  curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ) ;			// curl_execの結果を文字列で返す
  curl_setopt( $curl, CURLOPT_TIMEOUT, 15 ) ;						// タイムアウトの秒数
  curl_setopt( $curl, CURLOPT_FOLLOWLOCATION , true ) ;			// リダイレクト先を追跡するか？
  curl_setopt( $curl, CURLOPT_MAXREDIRS, 5 ) ;					// 追跡する回数
  $res1 = curl_exec( $curl ) ;
  $res2 = curl_getinfo( $curl ) ;
  curl_close( $curl ) ;

  // 取得したデータ
  $json = substr( $res1, $res2['header_size'] ) ;		// 取得したデータ(JSONなど)
  $header = substr( $res1, 0, $res2['header_size'] ) ;	// レスポンスヘッダー (検証に利用したい場合にどうぞ)

  // 取得したJSONをオブジェクトに変換
  $obj = json_decode( $json ) ;

  // URLを表示用に整形 (検証用)
  foreach( array( 'before_url', ) as $variable_name ) {
    ${ $variable_name } = htmlspecialchars( ${ $variable_name } , ENT_QUOTES , 'UTF-8' ) ;
  }

  // 成功時
  if( isset( $obj->id ) && !empty( $obj->id ) ) {
    // 取得した短縮URL
    $shorten_url = $obj->id ;
  // 失敗時
  } else {
    $shorten_url = '';
  }

  return $shorten_url;

}
?>
```

これで、定期的につぶやくようにすれば良い。
しかし、参ったのは、twitterのつぶやきも数十分ほど自動で続けていると、不正なアカウントだと判断されてしまい、ブロックがかかってしまうことがわかりました。