・http→httpsに
・投稿本文のキー名「message」は「text」の誤りでした。
先日、tsuという「広告収入の9割をユーザーのネットワークに還元するSNS」がスタートしました。
ユーザーが稼げるか、また流行るかどうかは分かりませんが、Twitterやfacebookのように自身のコンテンツへ誘導するような使い方ではなく、SNSが直接利益を提供するというコンセプトは面白そうです。
現状APIが提供されていないのでtsuへの自動投稿や記事取得はちょっと期待できないかな、と思ったのですが、スクレイピングという手法を使えばできるようなので試してみました。
過去にWordPressで記事を公開した時に自動で画像付きツイートを行う方法という処理を書いたことがありますが、その処理と同様に「WordPressで記事を公開した時に自動で画像を添付してtsuに投稿する」という処理になります。
ADs
tsuに外部から投稿するためには以下の処理を実装しないといけません。
メールアドレスとパスワードを送信すればログイン処理が完了しそうですが、実際はログイン画面にアクセスした際に発行されるCookieと乱数っぽいもの(ワンタイムトークンだと思われる)も必要です。
そのCookie、ワンタイムトークンを取得してメールアドレス・パスワードと共に送信する処理が必要です。
ログイン後、普通にブラウザからtsuに投稿してみて、どんな情報が送信されているかを開発者ツールなどで確認して同じ情報を送信します。
後述のスクリプトの「$postparam」が送信される情報にあたります。
なお、今回はリンクが含まれる投稿を送信した際の処理をエミュレートしていますので、動画や画像添付投稿などはまた違った処理になります。実際にtsuより投稿してみてどんな情報が必要か見てみてください。
SnoopyはPHPで書かれたスクレイピング用ライブラリです。HTMLを取得したり、POSTによるデータ送信をエミュレートしたりCookieを取得したりといろいろなことが簡単にできます。
Snoopyではてなにログインする
PHP – How To Auto Login And Post In WordPress By Php Snoopy Or Curl ?
htmlSQLを使ってmixiボイスを引っこ抜く
検索して見つかる情報が軒並み2010年なので、もしかしたら今はもっといいのがあるのかもしれない。。。
APIが提供されていなくてもログインや投稿で行っている処理を再現すれば、tsuに限らずどんなサイトでも情報送信や取得ができそうです。
今回はログインしたことにする処理と投稿データを送信する処理で使用しました。
以下のコードをfunctions.phpに追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
function publishTsu($new_status, $old_status, $post){ if($new_status == 'publish' && $old_status != 'publish'){ //Snoopyは http://sourceforge.net/projects/snoopy/ よりダウンロード require_once TEMPLATEPATH.'/Snoopy.class.php'; //ログイン情報の送信先 $url = 'https://www.tsu.co/users/sign_in'; //投稿の送信先 $posturl = 'https://www.tsu.co/posts'; $snoopy = new Snoopy; //ログインページのCookieを取得 $snoopy->fetch($url); $snoopy->setcookies(); //ログインページのワンタイムトークンっぽいものを取得 preg_match('/name=\"authenticity_token\" type="hidden" value=\"(.*)\"/',$snoopy->results,$matches); //送信する情報 $param = array( 'authenticity_token' => $matches[1], 'commit' => 'Sign In', 'user[login]' => 'tsu@example.com', //メールアドレス 'user[password]' => 'password', //パスワード 'user[remember_me]' => '1', 'utf8' => '✓' ); //ログイン情報の送信 $snoopy->submit($url,$param); //ここから投稿用処理---------------------------------------- //画像圧縮用キー(現状全員共通っぽい) $imgkey = '57776cc6bb5843779c7ac5ab178e9881'; //投稿ページのCookie取得と保持(ログインと共用でいいかも…) $snoopy->fetch($posturl); $snoopy->setcookies(); //投稿ページのワンタイムトークンぽいものを取得(ログインと共用でいいかも…) preg_match('/name=\"authenticity_token\" type="hidden" value=\"(.*)\"/',$snoopy->results,$matches); //アイキャッチ画像(tsuに送信するために取得) if($tsuimg = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'full' )){ $tsuimgSrc = 'https://i.embed.ly/1/image/resize?url='. $tsuimg[0] . '&key='.$imgkey.'&grow=true&width=540&height=540'; } else { $tsuimgSrc = ''; } //投稿用データの生成 $postparam = array( 'authenticity_token' => $matches[1], 'utf8' => '✓', 'title' => $post->post_title,//tsu上のタイトル 'text' => $post->post_excerpt, //tsu上の本文(#ではじまる単語はハッシュタグになる 'edit_picture_url' => '', 'has_link' => 'true', 'link' => get_permalink($post->ID), //リンク先 'link_title' => $post->post_title, //リンク先のタイトル 'link_description' => $post->post_excerpt, //リンク先の概要 'link_image_path' => $tsuimgSrc,//画像 'provider_domain' => get_bloginfo('url'),//ドメイン 'privacy' => 0,//全体公開か友達のみ公開か(0で全体) 'commit' => 'Post' ); //投稿処理 $snoopy->submit($posturl,$postparam); } } add_action('transition_post_status', 'publishTsu',10,3); |
実際に投稿してみると以下のように表示されます。
写真はWordPressのアイキャッチに設定した画像です。
tsuにリンクを貼るとリンク先のページから画像を取得してその画像をアイキャッチのような感じにして投稿されます。
その画像が上記コード内「link_image_path」にあたるのですが、これはi.embed.lyという画像縮小APIのようなものを使っているようです。このサービスによって圧縮された画像でないと「link_image_path」として認識されないようです。
また、公開時に投稿するのではなく「過去記事をランダムでツイートする処理をプラグインなしで実装する」を応用してbotのごとくtsuに投稿することもできると思いますが、ちょっとモラルに欠ける行為かもしれません。
垢バンされても責任取れませんので、ご利用は計画的に(・∀・)
SnoopyでCookieの扱いについて調べてもチョコチップクッキーばっかり出てくる。。。
ADs
ログイン情報の送信した後に
echo $snoopy->results;
を追加してみたのですが、何も表示されませんでした。
まだ、このコードで動作可能ですか?
kenji 様
コメントありがとうございます。
tsuがhttpsを使いはじめたので
となっているところ($urlと$posturl)を
に変更すれば動作すると思います。
※ 時間ができましたら記事本文も修正します。
この記事、とても参考になりました。
tsū のURLをhttps://~ にすることで、
Wordpressで書いたブログへのリンクを
tsūに自動投稿できるようになりました。
ありがとうございます。
今後、ブログへのリンクではなく、
画像付きの記事自体を投稿できるような
コードを書いていただけると助かります。
よろしくお願いします。
tsuの自動投稿、参考になります。
snoopyではないのですが、curlを使用して自動ログインはできたのですが、
投稿のところで、「Access token is required」というエラーが返ってきてしまいます。
authenticity_tokenは指定しているのですが、また別のtokenが必要だったりするのでしょうか?
もしお分かりになるようでしたらなにとぞよろしくお願いします。
tsu様
コメントありがとうございます。
この記事を書くときにcurlによる投稿も試したのですが、上手く動作させることができず断念しました。
早々にあきらめてしまったので結局何が悪かったのか分からないのですが、今思うと
・tsuがheaderの内容も判定しているのかもしれない
・Cookieの取得とセットがうまくいってなかった
・curlのバージョンを変えたら上手くいったかも
あたりが問題だったかもしれません。
POSTで送信する情報については正規の投稿処理でもauthenticity_token以外のトークンは送られていないようですので、別途トークンが必要ということはないと思います。
※Cookieにはトークンっぽい情報が保存されていました。
きちんとお答えできず申し訳ありません。
回答ありがとうございます。
>POSTで送信する情報については正規の投稿処理でもauthenticity_token以外のトークンは送られていないようですので、別途トークンが必要ということはないと思います。
そうなんですよね、それが不思議なんです。
仕様が変わったということはないですよね?
(今でも自動投稿はできておりますか?)
試しに「access_token」という値に適当なものを入れて送ると、
「Access token is wrong」とメッセージが変わるので、
この値を見ているのは間違いないと思うのですが、
snoopyとの違いが分からず困っております。。
ちなみにurlはpostsに送るとなぜかログイン画面にログアウト状態でリダイレクトされるので、別のURLに向けて送っております(実際JSでサブミットイベントをキャッチして別のURLに送っていましたので、そちらを指定しています)。
tsu様
記事のコードを改めて動作させてみましたが、問題なく動作しました。
試しに投稿URLである$posturlを
https://www.tsu.co/api/v1/posts/create
に変更したところ、「Access token is required」のJSONが返ってきました。
このURL(投稿APIの公開予定がある?)についてはアクセストークンが必要なものの、現状は全員共通か内部で生成するトークンを使用していると思われます。
http://www.tsu.co/posts
に向けてのPOST送信は正常に動作しますので、このURLへの送信がログアウトとリダイレクトされるという問題を解消するほうが近道かもしれません。
改めて見なおしていると、記事のコードが一箇所間違っておりました。
投稿内容の「本文」部分のキー名は「message」ではなく「text」でした。
——–
‘message’ => $post->post_excerpt,
ではなく
‘text’ => $post->post_excerpt,
——–
ここが原因で投稿できなかったのでしたら申し訳ありません。
管理人様 ご丁寧に回答ありがとうございます。
snoopyを使わずにやろうとしたのですが、
おとなしくsnoopyでやることにしました。
上記のコードで動作しており、大変参考になりました。
ありがとうございます。
PHPのCurl機能だけでやろうとすると、
ご指摘のようにおそらくheaderが足りなくて
うまくいかないのかなと思います。
(違いはそれくらいしかないかなと)
APIを公開してくれたらこんな苦労もなくて済むんですけどね。
情報が少ない中、とても助かりました。ありがとうございました。
素人ですいません。このコードをfunctions.phpに入れたら、Fatal error: Call to undefined function add_action() in wp-includes/functions.php on line 4710
となってしまいました。何が間違ってしまったのでしょうか?コピペで貼り付けただけなんですが(涙)もちろん、Snoopyはダウンロードして入れてます。
素人様
コメントありがとうございます。
Call to undefined function add_action… は括弧が足りてないなどの大きなエラーの際に発生するケースが多いです。
考えられる点としては
・functions.phpの文字コードがテーマ本体と違う
・目に見えないスペースが入っている
などでしょうか。
もしよろしければ関数内を空にして
※つまり
function publishTsu($new_status, $old_status, $post){
}
add_action(‘transition_post_status’, ‘publishTsu’,10,3);
として
記述してみるとどうでしょうか。これでエラーがなくなれば関数内部のどこかに問題があり、引き続きエラーになるなら上記関数以外のところで問題が起きています。
『記事公開時にtsūに自動投稿する』を試してみたところ、
『Warning: require_once(/home/sokohaka/sokohaka.wp.xdomain.jp/public_html/wp-content/themes/twentyfifteen/Snoopy.class.php): failed to open stream: No such file or directory in /home/sokohaka/sokohaka.wp.xdomain.jp/public_html/wp-content/themes/twentyfifteen/functions.php on line 6
Fatal error: require_once(): Failed opening required ‘/home/sokohaka/sokohaka.wp.xdomain.jp/public_html/wp-content/themes/twentyfifteen/Snoopy.class.php’ (include_path=’.’) in /home/sokohaka/sokohaka.wp.xdomain.jp/public_html/wp-content/themes/twentyfifteen/functions.php on line 6』
と言う文が出てしまいました。
原因が分かれば教えていただけますか?
宜しくお願いします。
m(_ _)m