上級 PHP 外部API RSS cron 動作停止中

Twitter(X) 自動投稿ボット

ニュースの RSS を読み込んで最新記事を自動でツイートしたり、フォローを返したり、決まった文章をランダムに投稿したりする Twitter(X) のボットです。X の API の仕様と料金が変わったため、現在は動いていません。

このサンプルは2017〜2018年ごろに作成したものです。PHPのバージョンが上がり、そのままでは動かなくなっていたため、2026年に PHP 8.3 で動くように書き直し、解説も新しくしました。

動作停止中

このサンプルは現在動きません。

このボットは Twitter(現在の X)の古い API(v1.1)を使っていました。その後、X の API は新しいバージョン(v2)に切り替わり、料金のしくみも変わりました。2026年2月には、無料プランに代わって「使った分だけ支払う」従量課金が導入されています。そのため、このコードはそのままでは動かず、デモの代わりにしくみだけを解説します。

ボットの種類していたこと
RSS 自動投稿ニュースサイトの RSS を読み、いちばん新しい記事の URL を自動でツイート
ランダム投稿用意した英熟語や宣伝文から1つ選び、ハッシュタグを付けてツイート
フォロー返しフォローしてくれた人のうち、まだフォローしていない人をフォロー
リムーブフォローを返してくれない人を、古い順に1人ずつフォロー解除
リツイート指定したアカウントの新しいツイートを自動でリツイート
古いツイートの削除反応がなかった古いツイートを1件ずつ削除

これらの PHP ファイルを、サーバーの cron(決まった時間に自動でプログラムを動かすしくみ)で数十分おきに実行していました。

解説コードを読んでみよう

このサンプルでわかること

  • ライブラリ(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 を使えます。

Zic_KANA.php(5〜19行目) PHP
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() で日付の新しい順に並べ替えます。

Zic_KANA.php(21〜56行目) PHP
//↓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 を比べ、違うときだけ投稿します。データベースを使わない、シンプルな記録方法です。

Zic_KANA.php(59〜76行目) PHP
$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() は「配列の中にその値があるか」を調べる関数です。

index.php(31〜39行目) PHP
//フォローバック(コーンでのアクセス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つ選びます。毎回違う組み合わせになるので、同じ文章ばかりの投稿になりません。

ACROMEMORY_PR.php(98〜108行目) PHP
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 を呼ぶ → 結果を確認する」という流れ自体は、このコードと同じです。

↑