記事公開時にtsūに自動投稿する

2014.12.11修正
一部コードに間違いがありましたので修正しました。

・http→httpsに
・投稿本文のキー名「message」は「text」の誤りでした。

tsū

先日、tsuという「広告収入の9割をユーザーのネットワークに還元するSNS」がスタートしました。
ユーザーが稼げるか、また流行るかどうかは分かりませんが、Twitterやfacebookのように自身のコンテンツへ誘導するような使い方ではなく、SNSが直接利益を提供するというコンセプトは面白そうです。

現状APIが提供されていないのでtsuへの自動投稿や記事取得はちょっと期待できないかな、と思ったのですが、スクレイピングという手法を使えばできるようなので試してみました。

過去にWordPressで記事を公開した時に自動で画像付きツイートを行う方法という処理を書いたことがありますが、その処理と同様に「WordPressで記事を公開した時に自動で画像を添付してtsuに投稿する」という処理になります。

AD

処理の流れ

tsuに外部から投稿するためには以下の処理を実装しないといけません。

1.tsuにログインする

メールアドレスとパスワードを送信すればログイン処理が完了しそうですが、実際はログイン画面にアクセスした際に発行されるCookieと乱数っぽいもの(ワンタイムトークンだと思われる)も必要です。
そのCookie、ワンタイムトークンを取得してメールアドレス・パスワードと共に送信する処理が必要です。

2.投稿する

ログイン後、普通にブラウザからtsuに投稿してみて、どんな情報が送信されているかを開発者ツールなどで確認して同じ情報を送信します。
後述のスクリプトの「$postparam」が送信される情報にあたります。

なお、今回はリンクが含まれる投稿を送信した際の処理をエミュレートしていますので、動画や画像添付投稿などはまた違った処理になります。実際にtsuより投稿してみてどんな情報が必要か見てみてください。

Snoopyを使う

SnoopyはPHPで書かれたスクレイピング用ライブラリです。HTMLを取得したり、POSTによるデータ送信をエミュレートしたりCookieを取得したりといろいろなことが簡単にできます。

Snoopyに関する参考ページ

Snoopyではてなにログインする
PHP - How To Auto Login And Post In WordPress By Php Snoopy Or Curl ?
htmlSQLを使ってmixiボイスを引っこ抜く

検索して見つかる情報が軒並み2010年なので、もしかしたら今はもっといいのがあるのかもしれない。。。

APIが提供されていなくてもログインや投稿で行っている処理を再現すれば、tsuに限らずどんなサイトでも情報送信や取得ができそうです。
今回はログインしたことにする処理と投稿データを送信する処理で使用しました。

PHP

以下のコードをfunctions.phpに追記します。

実際に投稿してみると以下のように表示されます。
写真はWordPressのアイキャッチに設定した画像です。

tsū (2)

注意点

tsuにリンクを貼るとリンク先のページから画像を取得してその画像をアイキャッチのような感じにして投稿されます。
その画像が上記コード内「link_image_path」にあたるのですが、これはi.embed.lyという画像縮小APIのようなものを使っているようです。このサービスによって圧縮された画像でないと「link_image_path」として認識されないようです。

また、公開時に投稿するのではなく「過去記事をランダムでツイートする処理をプラグインなしで実装する」を応用してbotのごとくtsuに投稿することもできると思いますが、ちょっとモラルに欠ける行為かもしれません。

垢バンされても責任取れませんので、ご利用は計画的に(・∀・)

余談

B0iWkV-IAAA38pJ
日本のニュースでは「スーと発音する」と紹介されてますが、「ツ」なのかもしれません。

もう一つ余談

SnoopyでCookieの扱いについて調べてもチョコチップクッキーばっかり出てくる。。。

AD

Share

Commentsコメント

メールアドレスは公開されません。コメントは必ずご入力ください。

HTMLタグは使用できません。ソースコードを書き込みたい場合はCodetterGistCodePenなどのご利用が便利です。

kenji さんより
ログイン情報の送信した後に
echo $snoopy->results;
を追加してみたのですが、何も表示されませんでした。

まだ、このコードで動作可能ですか?
admin さんより
kenji 様
コメントありがとうございます。

tsuがhttpsを使いはじめたので

http://www.tsu.co....

となっているところ($urlと$posturl)を

https://www.tsu.co...

に変更すれば動作すると思います。

※ 時間ができましたら記事本文も修正します。
takey さんより
この記事、とても参考になりました。
tsū のURLをhttps://~ にすることで、
Wordpressで書いたブログへのリンクを
tsūに自動投稿できるようになりました。
ありがとうございます。

今後、ブログへのリンクではなく、
画像付きの記事自体を投稿できるような
コードを書いていただけると助かります。

よろしくお願いします。
tsu さんより
tsuの自動投稿、参考になります。
snoopyではないのですが、curlを使用して自動ログインはできたのですが、
投稿のところで、「Access token is required」というエラーが返ってきてしまいます。
authenticity_tokenは指定しているのですが、また別のtokenが必要だったりするのでしょうか?

もしお分かりになるようでしたらなにとぞよろしくお願いします。
管理人 さんより
tsu様

コメントありがとうございます。

この記事を書くときにcurlによる投稿も試したのですが、上手く動作させることができず断念しました。
早々にあきらめてしまったので結局何が悪かったのか分からないのですが、今思うと

・tsuがheaderの内容も判定しているのかもしれない
・Cookieの取得とセットがうまくいってなかった
・curlのバージョンを変えたら上手くいったかも

あたりが問題だったかもしれません。

POSTで送信する情報については正規の投稿処理でもauthenticity_token以外のトークンは送られていないようですので、別途トークンが必要ということはないと思います。
※Cookieにはトークンっぽい情報が保存されていました。

きちんとお答えできず申し訳ありません。
tsu さんより
回答ありがとうございます。

>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,
--------

ここが原因で投稿できなかったのでしたら申し訳ありません。
tsu さんより
管理人様 ご丁寧に回答ありがとうございます。

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