解説コードを読んでみよう
このサンプルでわかること
- ライブラリ(TwitterOAuth)を使って外部サービスの API を呼び出す方法
- RSS(ニュースの更新情報)を PHP で読み込んで並べ替える方法
- 前回の結果をファイルに保存して、同じ投稿をくり返さない工夫
コード中の statuses/update などは、旧 API(v1.1)の書き方です。今の X API では使えません。また、API キーはダミー(YOUR_...)に置き換えています。本物のキーをコードに書いて公開しないよう注意してください。
使っているファイル(主なもの)
- twitter/post/*.phpRSS を読んで自動投稿するボット(アカウントごとに1ファイル)
- twitter/post/ACROMEMORY_PR.php宣伝文をランダムに投稿するボット
- twitter/common/index.php全アカウントのフォロー返し
- twitter/retwit/RamuneTW.php自動リツイート
- twitter/delete/ACROMEMORY.php古いツイートの削除
- twitteroauth-master/Twitter の API を呼び出すためのライブラリ(TwitterOAuth)
1. API に接続する
API を使うには、開発者として登録したときにもらう4つのキーが必要です。TwitterOAuth ライブラリにキーを渡して「接続」を作り、あとは $connection->get()(読み込み)や $connection->post()(投稿)を呼ぶだけで API を使えます。
require_once("../twitteroauth-master/autoload.php");
use Abraham\TwitterOAuth\TwitterOAuth;
function dump($s) {
echo '<pre>'; print_r($s); echo '</pre>';
}
$consumerKey = "********";
$consumerSecret = "********";
$accessToken = "********";
$accessTokenSecret = "********";
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);
2. RSS を読み込んで、新しい順に並べる
RSS は、ニュースサイトなどが「新しい記事の一覧」を XML 形式で配信しているものです。simplexml_load_file() で読み込み、各記事の公開日(pubDate)と一緒に配列 $all にためます。複数のサイトの記事が混ざるので、array_multisort() で日付の新しい順に並べ替えます。
//↓RSS取得
$rssList = array(
"https://news.yahoo.co.jp/pickup/science/rss.xml",
"https://headlines.yahoo.co.jp/rss/aptsushinv-c_int.xml",
"https://headlines.yahoo.co.jp/rss/abema-c_ent.xml",
"https://headlines.yahoo.co.jp/rss/mbsnews-bus.xml"
);
date_default_timezone_set('Asia/Tokyo');
$all = []; // PHP8.3対応: RSSが1件も取れないと array_multisort() で TypeError になるため初期化
$id = [];
for($n=0;$n<count($rssList);$n++){
$rssdata = @simplexml_load_file($rssList[$n]);
if ($rssdata === false) { continue; } // 取得できないRSSは飛ばす
$num_of_data = 10; //取得件数
for ($i=0; $i<$num_of_data; $i++){
$info = $rssdata->channel->item[$i];
if ($info === null) { break; }
$all[] = array (
"info" => $info,
"Date" => date("Y-m-d H:i:s", strtotime($info->pubDate)),
);
}
}
if (empty($all)) { echo 'RSSを取得できませんでした。'; exit; }
foreach ($all as $key => $value) {
$id[$key] = $value['Date'];
}
array_multisort($id, SORT_DESC, $all);
$tw = $all[0]['info']->link;
3. 前回と違うときだけ投稿する
同じ記事を何度も投稿しないよう、最後に投稿した URL をテキストファイルに保存しておきます。次に実行したとき、ファイルの URL と今回の URL を比べ、違うときだけ投稿します。データベースを使わない、シンプルな記録方法です。
$file = 'Zic_KANA_log.txt';
$url = is_file($file) ? file_get_contents($file) : ''; //ファイルからsince_idの読み込み
echo $url. "<br>";
if(!empty($url)){
if($tw != $url){
file_put_contents($file, $tw);
$re = $connection->post("statuses/update", array("status" => strval($tw)));
echo "新規にツイートされました。";
}else{
echo "既にツイートされています。";
}
}else{
file_put_contents($file, $tw);
$re = $connection->post("statuses/update", array("status" => strval($tw)));
echo "新規にツイートされました。";
}
4. フォローを返す
「自分をフォローしている人の一覧」と「自分がフォローしている人の一覧」を取得し、前者にいて後者にいない人をフォローします。in_array() は「配列の中にその値があるか」を調べる関数です。
//フォローバック(コーンでのアクセスOR直アクセス)
$followers = $connection->get('followers/ids', array('cursor' => -1));
$friends = $connection->get('friends/ids', array('cursor' => -1));
foreach ((array)($followers->ids ?? []) as $j => $id) {
if (empty($friends->ids) or !in_array($id, (array)($friends->ids ?? []))) {
$connection->post('friendships/create', array('user_id' => $id));
}
}
5. 文章とハッシュタグをランダムに選ぶ
shuffle() で配列の順番をばらばらにし、array_rand() で配列からランダムに1つ選びます。毎回違う組み合わせになるので、同じ文章ばかりの投稿になりません。
shuffle($title);
$n= array_rand($twitter);
shuffle($tag);
$tags ='';
echo $tags;
for ($i = 0 ; $i < 5; $i++) {
$tags .= $tag[$i]. ' ';
}
PHP 8.3 で書き直したポイント
- RSS が1件も取れなかったとき、空の配列で
array_multisort()を呼ぶと PHP 8 ではエラーで止まります。最初に$all = [];で初期化し、取れなかったら終了するようにしました。 - API がエラーを返したときに
$followers->idsが存在しないことがあるため、?? []で「なければ空の配列」として扱うようにしました。 - ライブラリ内の
$str{$i}という古い書き方(PHP 8 で廃止)を$str[$i]に直しました。
今から X の自動投稿を作る場合は、X の開発者サイトで最新の API(v2)と料金を確認してください。「キーで接続 → API を呼ぶ → 結果を確認する」という流れ自体は、このコードと同じです。