プログ

’14修了無内定理系院卒の活動雑記||プー太郎ログ||プログラミング雑記

OAuthに帰ってきたよー(^O^)/

WebIntentについて色々見て回ったけど望む結果を得られなさそうだと思ったのと,UltimateOAuthと言うのを発見したため.


前置き

前にも書きましたが,まだファイル化していない画像を添付してツイートを行いたいため

  1. 画像データを渡せる形に
  2. 渡された画像をpic.twitterにアップロード
  3. 画像のURLを本文に載せてツイート

の3段階が必要と考えられます.3に関しては2の結果としてURLが得られれば本文に追加するだけなのでさほど問題ないのですが,問題は1と2です.まず2について, WebIntent は Android 周りでの利用が多く見られるので Java に依る記述が多く中々有益な情報が得られない.いやJavaアプレットとかで導入できるのかもしれない(?)けど,そもそも Android アプリ向けの記述見てもギャラリーからファイルを選択するようなのがあれば良い方であまりうまく行ってなさそう.2がうまくできないとそれにマッチするための画像を用意する1もどうすれば良いのか分からないので,挑戦するのはリスクが高い.一方でOAuth周りの方ではうまく行きそうなtmhOAuthと言うのを見かけたのと,先人もOAuthを利用しているため一先ず従うことにしようと思う.きっとWebIntentはサイトURLやゲームのハイスコアみたいなテキストだけで価値あるものをサクッとやるためのものなんだと思う.

懸念

OAuth認証にする懸念としてユーザから書き込み権限の認証が必要というのが当然ながらあり,そこから派生して

  • 信用されるようなサイトでないといけない
  • 権限を抜き取られないようしっかり管理しないといけない

UltimateOAuth

twitteroauthもよいのですが、画像付きツイートができなさそう。multipart/form-dataなPOSTができないようだ。

tmhOAuthは大丈夫。multipart/form-dataのPOSTに対応していて、画像付きツイートができる。
【php】twitterのREST APIで画像付きツイートをする at softelメモ

ふむふむ,じゃあtmhOAuthを使うか.

tmhOAuthはcURLを利用しています。cURLでバイナリデータを直接渡してマルチパートリクエストにさせる方法が調べても分からなかったので、自作ライブラリUltimateOAuthを用いた方法の紹介とさせていただきますがご了承下さい。
canvasで作成した画像をTwitterに投稿できるツールを作りたいのですが、dataURL()... - Yahoo!知恵袋

ん,そうなの?じゃあ僕もありがたく使わせて頂きます.と言うかこの質問まんま僕のやりたいことなので多分この質問者も画像コラジェネレータ作ってたんでしょうね.

進捗

f:id:triplog:20140522233600p:plain
さっそく利用してみたところ,

  • 認証済みのアカウントで画像付きツイート
  • twitter認証を行って通常のツイート

はすぐにできたけど,

  • twitter認証を行って画像付きツイート

で詰まる.というのも,
認証画面→twitterにログイン→コールバック→ツイート画面
と遷移するため,twitter を挟む過程で dataurl の受け渡しができなくなってしまうためです.これを解決するために親ウィンドウの値を持ってくるという処理をコールバックとツイートの間に挟みました.

//出力する用の変数をグローバル変数で用意
var dataurl;
var text;
//即時関数でロード時に実行
(getDataUrl = function(){
  //親ウィンドウの存在をチェック
  if(!window.opener||window.opener.closed){
    window.alert('no parent window');
    return 'no parent window';
  }else{
    //親ウィンドウのキャンバスを取得
    var srcImg = window.opener.document.getElementById("srcImg");
    dataurl = srcImg.toDataURL();
    //子ウィンドウに表示
    document.getElementById("dstImg").src = dataurl;
    console.log(dataurl);
  }
})();
//ツイートするための関数
function submitTweet(text){
  //テキストボックスの値を取得
  text = $("#text").val();
  console.log(text);
  //main.php に投げた text と dataurl がツイート本文と画像になる
  $.post("main.php",  //url
    { dataurl: dataurl, text:text },  //data
    function(data){ //callback関数
      //チェック用,今後改善していく
      alert(data);
    }
  );
}
<?php
// ライブラリ読み込み
require_once('UltimateOAuth.php');
// セッション開始
session_start();
// セッションタイムアウトチェック
if (!isset($_SESSION['uo'])) {
    die('Error[-1]: Session timeout.');
}
$uo = $_SESSION['uo'];

// ツイートのためのデータ
$text = htmlspecialchars($_POST['text']);
$dataurl = htmlspecialchars($_POST['dataurl']);
// 先頭のMIME情報を削除してBASE64デコード
$dataurl = base64_decode(preg_replace('@^data:image/[^;]*+;base64,@', '', $dataurl));

// データをTwitterに送信
$uo->postMultipart('statuses/update_with_media', array(
  'status' => $text,
  'media[]' => $dataurl,
));
?>

ほかは大体UltimateOAuthの設定通り.注意する点としては,先ほどのJavaScriptを実行するページ(僕は tweet.php とした)を callback.php の遷移先に指定すること.ポップアップ内の画面遷移は,
prepare.phptwitter api → callback.phptweet.php (→ main.php (データ送信のみ))
となっている.とりあえず現状一連の流れが整ったので,使いやすい&見た目が良くなるようにこれから整地していく.ちなみに進捗画像を見てもわかるようにhashtagやreplyの設定は特にしなくても反映された.twitter からのセッション管理のため各画面の php ファイルはローカルでなくサーバにあげておく必要があることや,認証画面の動作確認のために毎度アプリ連携を切るのが面倒くさい.

参考
【php】twitterのREST APIで画像付きツイートをする at softelメモ
canvasで作成した画像をTwitterに投稿できるツールを作りたいのですが、dataURL()... - Yahoo!知恵袋
UltimateOAuth/README-Japanese.md at master · Certainist/UltimateOAuth · GitHub
blog: Formを作らずにJSでPOST送信
PHPでWebサービスを開発する際、複数ページにまたがったウィザー.. - 人力検索はてな
Javascript 子ウィンドウからwindow.openerを使って親ウィンドウを操作する | WEB作業メモ
php←→JavaScriptで値を渡しあいたい [PHP,JavaScriptで変数の連携をする] - 書いたり 動かしたり ぬるぽったり
$.post() | jQuery 1.9 日本語リファレンス | js STUDIO
toDataURL() メソッド - Canvasリファレンス - HTML5.JP