PHPでTwitterに画像付きメッセージ投稿

(1/1)
PHPでTwitterに画像付きメッセージ投稿
今回は、PHPで「Twitter API」を利用し、画像付きのメッセージを投稿する。リプライ(返信)指定もできる。画像は最大4つまで。動画を投稿することもできる。

(2022年1月9日)Twitter API v2対応,その他大幅改訂

目次

サンプル・プログラム:実行例

PHPでTwitterに画像付きメッセージ投稿
本プログラムは、パラメータをGET渡すことで実行することもできる。
たとえば、"putTweetMedia.php?msg=%E5%B0%8F%E7%94%B0%E5%8E%9F%E5%9F%8E%E3%81%AF%E9%9B%A3%E6%94%BB%E4%B8%8D%E8%90%BD+https%3A%2F%2Fwww.pahoo.org%2Fathome%2Falbum%2F2019%2Fimg20190907-173131e.jpg&reply=https%3A%2F%2Ftwitter.com%2Fpapa_pahoo%2Fstatus%2F123456789" のようにすると、"https://twitter.com/papa_pahoo/status/123456789" にリプライ(返信)する形で、メッセージ「小田原城は難攻不落」と画像ファイル "https://www.pahoo.org/athome/album/2019/img20190907-173131e.jpg" を付けることができる。

サンプル・プログラム

圧縮ファイルの内容
putTweetMedia.phpサンプル・プログラム本体
pahooTwitterAPI.phpTwitter APIを利用するクラス pahooTwitterAPI。
使い方は「PHPでTwitterに投稿(ツイート)する」などを参照。include_path が通ったディレクトリに配置すること。
圧縮ファイルの内容
putTweetMedia.phpサンプル・プログラム本体
pahooTwitterAPI.phpTwitter APIに関わるクラス pahooTwitterAPI。
使い方は「PHPでTwitterに投稿(ツイート)する」などを参照。include_path が通ったディレクトリに配置すること。
putTwitter.php 更新履歴
バージョン 更新日 内容
5.0.0 2023/07/02 Twitter API v2対応
4.1 2022/01/04 PHP8対応,リファラ・チェック改良
4.0 2016/02/11 pahooTwitterAPIクラスを分離
3.1 2014/01/19 https対応
3.0 2013/07/21 API 1.1対応
pahooTwitterAPI.php 更新履歴
バージョン 更新日 内容
5.2.0 2023/07/17 oembed() v2対応
5.1.0 2023/07/16 extractMediaURL() -- file:///形式に対応
5.0.0 2023/07/02 メソッドをTwitter API v2へ移行;v1.1は別名or廃止
4.9.0 2023/04/15 tweet3() 追加
4.8.0 2023/01/28 tweet2(),twitter_strcut2(),extractMediaURL()追加
pahooInputData.php 更新履歴
バージョン 更新日 内容
1.3.0 2023/07/11 roundFloat() 追加
1.2.0 2023/04/22 exitIfLessVersion() 追加
1.1.2 2023/02/05 validString() 修正
1.11 2022/07/03 isCommandLine() 修正
1.1 2022/06/04 getValidString() 修正
OAuth認証 および Twitter API へのアクセスには、TwitterOAuth を利用する。導入方法は公式サイトにあるように composer を使うことを推奨している。

準備:pahooTwitterAPI クラス

  11: //TwitterOAuth クラスをロードする.
  12: $version = explode('.', phpversion());
  13: if ($version[0>8) {
  14:     require __DIR__ . '/vendor/autoload.php';
  15: }
  16: use Abraham\TwitterOAuth\TwitterOAuth;
  17: 

前述の TwitterOAuth クラスをロードする。composer でインストールされたフォルダ "\vendor" を "pahooTwitterAPI.php" と同じフォルダへコピーすること。

  27:     //OAuth用パラメータ
  28:     // https://apps.twitter.com/
  29:     var $TWTR_CONSUMER_KEY    = '***************';  //Cunsumer key
  30:     var $TWTR_CONSUMER_SECRET = '***************';  //Consumer secret
  31:     var $TWTR_ACCESS_KEY      = '***************';  //Access Token (oauth_token)
  32:     var $TWTR_ACCESS_SECRET   = '***************';  //Access Token Secret (oauth_token_secret)
  33: 

TwitterAPI を利用するために、クラスファイル "pahooTwitterAPI.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。

事前にプログラムを登録しておく必要があり、その方法は「Twitter API - WebAPIの登録方法」を参照されたい。入手したパラメータを、上述の変数に代入しておくこと。

PHP の https対応

Twitter APIの呼び出しはhttps通信で行うため、PHPにOpenSSLモジュールが組み込まれている必要がある。
関数  phpinfo  を使って、下図のように表示されればOK。
OpenSSL - PHP
そうでない場合は、次の手順に従ってOpenSSLを有効化し、PHPを再起動させる必要がある。

Windowsでは、phop.iniの下記の行を有効化する。
extension=php_openssl.dll


Linuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順

これで準備は完了だ。

Twitter API:POST /2/tweets

ツイートするには、「Twitter API:POST /2/tweets」を用いる。
WebAPIのURL
URL
https://api.twitter.com/2/tweets

入力パラメータ
フィールド名 要否 内  容
text 必須 投稿文。UTF-8でエンコードされたテキストで、140文字以下。
media media_ids 任意 メディアID。最大4つ。
reply in_reply_to_tweet_id> 任意 リプライID。
応答データ(json) id 投稿ID text 投稿文

Twitter API:POST media/upload

画像を含むメディア・ファイルをアップロードするAPIはv.1.1のままで、「Twitter API:POST media/upload」を用いる。
Twitter API (POST)
URL
https://upload.twitter.com/1.1/media/upload.json

入力パラメータ
フィールド名 要否 内  容
media mediaまたはmedia_dataが必須 media:メディアデータ(バイナリ)
media_data mediaまたはmedia_dataが必須 media_data:メディアデータ(base64形式)
応答データ(json) media_id メディアID media_id_string メディアID(文字列) size データサイズ image w 幅(ピクセル) h 高さ(ピクセル) image_type 形式

解説:メディア付きツイート

メディア付きツイート
まず、リプライ先のIDとスクリーンネームを取り出す。
続いて、メッセージの中からユーザー関数 extractMediaURL( を使ってメディアURLを取り出す。
メディアURLが1つでもあれば、「Twitter API:POST media/upload」を使ってアップロードする。
アップロードに成功すると、メディアIDを返す。これはツイートの時に必要になるので、配列 $media_ids に格納しておく。
1つのツイートに含めることができる画像の数は4つなので、この作業を最大4回繰り返す。

次に、「PHPでTwitterに投稿(ツイート)する」と同じ要領で、「Twitter API:POST /2/tweets」を使ってツイートする。オプションに配列 $media_ids を追加することで、先ほどアップロードした画像が付いたメッセージとなる。

 811: /**
 812:  * 指定したテキストをツイートする.
 813:  * リプライ(返信)先を指定したり,メディアを投稿できる.
 814:  * Tweetet API v2 を使用する.
 815:  * @param   string $message 投稿メッセージ(UTF-8限定);メディアを指定するときは 'http(s)://' または 'file:///' を含める
 816:  * @param   string $reply   リプライ先のURL(省略可能)
 817:  * @return  bool TRUE:リクエスト成功/FALSE:失敗
 818: */
 819: function tweet3($message, $reply=NULL) {
 820:     $id    = NULL;
 821:     $name  = NULL;
 822: 
 823:     //リプライ先のidを取り出す.
 824:     if ($reply !NULL) {
 825:         if (preg_match('/\/([0-9]+$)/i', $reply, $arr> 0) {
 826:             $id = (string)$arr[1];
 827:         } else {
 828:             $this->error  = TRUE;
 829:             $this->errmsg = 'リプライ先のURLが間違っています';
 830:             return FALSE;
 831:         }
 832:     }
 833:     //スクリーンネームを取り出す
 834:     if ($reply !NULL) {
 835:         if (preg_match('/https\:\/\/twitter\.com\/([^\/]+)\//i', $reply, $arr> 0) {
 836:             $name = (string)$arr[1];
 837:         } else {
 838:             $this->error  = TRUE;
 839:             $this->errmsg = 'リプライ先のURLが間違っています';
 840:             return FALSE;
 841:         }
 842:     }
 843: 
 844:     //メディアURLを取り出す.
 845:     $mediaURLs = array();
 846:     $str = $this->extractMediaURL($message, $mediaURLs);
 847: 
 848:     //スクリーンネームを追加する.
 849:     if ($id !NULL) {
 850:         $str = '@' . $name . ' ' . $str;
 851:     }
 852: 
 853:     //メディア付きリプライを行う.(Tweetet API v2 を使用する)
 854:     if (count($mediaURLs> 0) {
 855:         $media_ids = array();
 856:         $cnt = 0;
 857:         //メディアのアップロード.
 858:         //Tweetet API v1.1 を使用する(v2にメディアアップロードが未実装のため)
 859:         $this->connection->setApiVersion('1.1'); 
 860:         foreach ($mediaURLs as $fname) {
 861:             $tmpname = $this->media2temp($fname);
 862:             if ($tmpname == FALSE) {
 863:                 echo 'failure';
 864:                 exit(1);
 865:             }
 866:             $media = $this->connection->upload('media/upload', ['media' => $tmpname]);
 867:             unlink($tmpname);
 868:             if (! isset($media->media_id_string))       break;
 869:             $media_ids[] = (string)$media->media_id_string;
 870:             $cnt++;
 871:             if ($cnt > 3)   break;      //最大4つまで
 872:         }
 873: 
 874:         //メディア付きリプライ
 875:         $this->connection->setApiVersion('2'); 
 876:         $option = [
 877:             'text' => $str,
 878:             'media' => [
 879:                 'media_ids' => $media_ids
 880:             ]
 881:         ];
 882:         if ($id !NULL) {
 883:             $option = array_merge($option, [
 884:                 'reply' => [
 885:                     'in_reply_to_tweet_id' => $id
 886:                 ]
 887:             ]);
 888:         }
 889: 
 890:     //メディアなしリプライを行う.
 891:     } else {
 892:         $option['text'] = $str;
 893:         if ($id !NULL) {
 894:             $option = array_merge($option, [
 895:                 'reply' => [
 896:                     'in_reply_to_tweet_id' => $id
 897:                 ]
 898:             ]);
 899:         }
 900:     }
 901:     $status = $this->connection->post('tweets', $option, TRUE);
 902:     $this->webapi = 'https://api.twitter.com/2/tweets';
 903: 
 904:     //処理に成功した.
 905:     if ($this->isSuccess()) {
 906:         $this->responses = $status->data;
 907:         $this->errcode   = NULL;
 908:         $this->errmsg    = '';
 909:         $this->error     = FALSE;
 910:         $res = TRUE;
 911:     //処理に失敗した.
 912:     } else {
 913:         if ($this->isAuthError() == FALSE) {
 914:             $this->errmsg = $status->detail;
 915:             $this->error  = TRUE;
 916:         }
 917:         $res = FALSE;
 918:     }
 919:     return $res;
 920: }

参考サイト

(この項おわり)
header