お世話になります、目下、サンプルコードからTwitterの投稿アプリを製作中であります。
下記のようなドキュメントクラスと付随クラスで行っておりますが
実際に実行するとTwitterAPIの利用にはIDとパスワードが必要です
という入力ダイアログが出て現在利用中のものを入力するのですが
再度、入力を促されるように同じダイアログがまた出てくる状況です。
仕方なくキャンセルすると出力ウィンドウには「投稿失敗on"投稿失敗onAuthTokenFaultFault」となり
AuthTokenの方のエラーイベントが発生していることが分かります。
ID、パス、consumer_key、consumer_secretはすべて現在、
PHPで製作した稼動しているBOTで使っているものです。
(
http://dev.twitter.com/apps/ このページで確認)問題の原因がAS3.0のコーディングにあるのか
TwitterAPIの認証コード等のユーザのリソースの
利用方法自体に問題があるのかはっきりしないため
見当違いな場所での質問かもしれませんが
よろしくお願いします。
package{
import flash.display.MovieClip;
import flash.net.navigateToURL;
import flash.net.URLVariables;
import flash.utils.ByteArray;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequestMethod;
import flash.net.URLRequest;
import com.adobe.serialization.json.JSON;
import com.hurlant.crypto.Crypto;
import com.hurlant.crypto.hash.HMAC;
import com.hurlant.util.Base64;
import com.hurlant.util.Hex;
import mx.utils.UIDUtil;
public class TwitterManager extends MovieClip{
private var _model:XAuthModel;
public function TwitterManager()
{
_model = new XAuthModel();
Tweet("投稿します");
}
public function Tweet(message:String):void {
if (!_model.isAuthorized) {
getAuthToken(message);
}
else {
setStatus(message);
}
}
private function getAuthToken(status:String):void {
_model.Status = status;
var _loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, onAuthTokenResult);
_loader.addEventListener(IOErrorEvent.IO_ERROR, onAuthTokenFault);
var requestTokenService:URLRequest = new URLRequest();
requestTokenService.url = _model.AccessTokenUrl;
requestTokenService.method = URLRequestMethod.POST;
var forms:URLVariables = new URLVariables();
forms.x_auth_mode = "client_auth";
forms.x_auth_password = "myPass"; //実際には現在使用中で有効のものをいれています。
forms.x_auth_username = "myUserName";
forms.oauth_signature = getSignature(requestTokenService.method, requestTokenService.url, forms);
requestTokenService.data = forms;
_loader.load(requestTokenService);
}
private function getSignature(method:String, url:String, forms:URLVariables):String {
var now:Date = new Date();
forms.oauth_consumer_key = _model.ConsumerKey;
forms.oauth_nonce = UIDUtil.getUID(now); //一意の文字列
forms.oauth_signature_method = "HMAC-SHA1";
forms.oauth_timestamp = now.time.toString().substring(0, 10);
forms.oauth_version = "1.0";
if (_model.OAuthToken.length) {
forms.oauth_token = _model.OAuthToken;
}
var sortArr:Array = UrlVariableToArray(forms);
var sigBase:String = URLEncoding.encode(method) + "&" + URLEncoding.encode(url) + "&" + URLEncoding.encode(sortArr.join("&"));
var sigkeybase:String = URLEncoding.encode(_model.ConsumerSecret) + "&";
if (_model.OAuthTokenSecret.length){
sigkeybase += URLEncoding.encode(_model.OAuthTokenSecret);
}
var hmac:HMAC = Crypto.getHMAC("sha1");
var sig_key:ByteArray = Hex.toArray(Hex.fromString(sigkeybase));
var data:ByteArray = Hex.toArray(Hex.fromString(sigBase));
var signature:String = Base64.encodeByteArray(hmac.compute(sig_key, data));
return signature;
}
private function UrlVariableToArray(variables:URLVariables):Array{
var arr:Array = new Array();
for(var key:String in variables){
arr.push(key + "=" + URLEncoding.encode(variables[key]));
}
arr.sort();
return arr;
}
private function onAuthTokenResult(e:Event):void {
var results:Array = e.target.toString().split("&");
for each (var token:String in results) {
if (_model.OAuthToken == "" || _model.OAuthTokenSecret == "") {
var values:Array = token.split("=");
if (values.length == 2) {
if (values[0] == "oauth_token") {
_model.OAuthToken = values[1];
}
else if (values[0] == "oauth_token_secret") {
_model.OAuthTokenSecret = values[1];
}
}
}
else {
break;
}
}
_model.isAuthorized = true;
setStatus(_model.Status);
}
private function onAuthTokenFault(ioe:IOErrorEvent):void {
trace("投稿失敗onAuthTokenFault...\n" + ioe.target.toString());
}
private function setStatus(status:String):void {
var updateService:URLRequest = new URLRequest();
updateService.method = URLRequestMethod.POST;
updateService.url = "http://twitter.com/statuses/update.json";
updateService.contentType = "text";
var _loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, onMyResult);
_loader.addEventListener(IOErrorEvent.IO_ERROR, onMyFault);
var forms:URLVariables = new URLVariables();
forms.status = status;
forms.oauth_signature = getSignature(updateService.method, updateService.url, forms);
updateService.data = forms;
_loader.load(updateService);
}
private function onMyResult(e:Event):void {
var json:Object = JSON.decode(e.target.toString());
trace(json.text);
}
private function onMyFault(e:IOErrorEvent):void {
trace("投稿失敗IOErrorEvent...\n" + e.target.toString());
}
}
}
以下、XAuthModel.asの内容
package
{
public class XAuthModel
{
private static var access_token_url:String = "https://api.twitter.com/oauth/access_token";
private static var consumer_key:String = "myCustomerKey"; //ここも実際には既にBOTで稼働中のものをセットしています
private static var consumer_secret:String = "myConsumerSecret";
private var _status:String;
private var oauth_token:String;
private var oauth_token_secret:String;
private var oauth_signature:String;
private var _authorized:Boolean;
public function XAuthModel()
{
_status = "";
oauth_token = "";
oauth_token_secret = "";
oauth_signature = "";
_authorized = false;
}
public function get AccessTokenUrl():String {
return access_token_url;
}
public function set Status(status:String):void {
_status = status;
}
public function get Status():String {
return _status;
}
public function set OAuthSignature(signature:String):void {
oauth_signature = signature;
}
public function get OAuthSignature():String {
return oauth_signature;
}
public function set OAuthToken(token:String):void {
oauth_token = token;
}
public function get OAuthToken():String {
return oauth_token;
}
public function set OAuthTokenSecret(secret:String):void {
oauth_token_secret = secret;
}
public function get OAuthTokenSecret():String {
return oauth_token_secret;
}
public function get ConsumerKey():String {
return consumer_key;
}
public function get ConsumerSecret():String {
return consumer_secret;
}
public function set isAuthorized(authorized:Boolean):void {
_authorized = authorized;
}
public function get isAuthorized():Boolean {
return _authorized;
}
}
}