AIRからmixiへ書き込みしてみたよ!\(^o^)/

最近mixiiPhoneへ対応したことから裏APIが評判になっていますが、せっかくなのでAIRでやってみました。
ちょっと動作が不安定かもしれないけどこんな感じに書き込み。

mixiのメールとパスワードとmixiのID(プロフィール表示にURLのところに表示される番号)が必要となります。

AIRなプログラムはこちら
http://moeten.info/flex/20080803_mixiAir/main.air
ソースはこちら
#一応ソフトをインストールすると右クリックでソースが見れます。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
    backgroundGradientAlphas="[1,1]" backgroundGradientColors="[0xffffff,0xffffff]"
    showStatusBar="false"
    layout="absolute" width="536" height="301" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import com.adobe.crypto.*;
import mx.utils.Base64Encoder;
private function send():void{
    //設定パラメータ
    var user:String = userTxt.text;
    var pass:String = passTxt.text;
    var mixiid:String = mixiidTxt.text;
    //URLrequest作成
    var req:URLRequest = new URLRequest();
    req.method = "POST";
    req.contentType = "application/xml";
    req.url = "http://mixi.jp/atom/diary/member_id=" + mixiid;
    //SWSSEを自前で作成
    var d:Date = new Date();
    var seed:String = "" + d.getTime() +""+Math.floor( Math.random()*10000000 );
    var nonce:String  =  SHA1.hash( ( MD5.hash( seed ) ) );
    var nonce2:String =  SHA1.hashToBase64( ( MD5.hash( seed ) ) );
    var mydate:String = generateTimestamp();
    var wsse:String  = "UsernameToken Username=\"" + user +
                        "\", PasswordDigest=\"" + SHA1.hashToBase64( hex2ByteArray(nonce) + mydate + pass) +
                        "\", Nonce=\"" + nonce2 +
                        "\", Created=\""+mydate +
                        "\"";
    //リクエストのヘッダーを追加
    var hdrWsse:URLRequestHeader = new URLRequestHeader("X-WSSE", wsse );
    req.requestHeaders.push(hdrWsse);
    //書き込み用XML作成
    var myxml:XML = new XML( "<?xml version='1.0' encoding='utf-8'?>" +
                    "<entry xmlns='http://www.w3.org/2007/app'>"+
                    "<title>"+titleTxt.text+"</title>"+
                    "<summary>"+commentTxt.text+"</summary>"+
                    "</entry>");
    req.data = myxml;
    //URLLoader作成
    loader = new URLLoader();
    loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,loaderHandler);
    loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,onHTTPResponse);
    loader.addEventListener(IOErrorEvent.IO_ERROR,loaderHandler);
    loader.addEventListener(ProgressEvent.PROGRESS,loaderHandler);
    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loaderHandler);
    loader.addEventListener(Event.COMPLETE,loaderHandler);
    loader.addEventListener(Event.COMPLETE , onComp );
    loader.load(req);
}
private function loaderHandler(e:Event):void{
}
private var loader:URLLoader;
private function onComp(e:Event):void{
    myLog.text = loader.data;
}
private function onHTTPResponse(event:HTTPStatusEvent):void {
}
//日付フォーマット
import mx.formatters.DateFormatter;
private function generateTimestamp():String{
    var timestamp:Date = new Date();
    var dateFormatter:DateFormatter = new DateFormatter();
    dateFormatter.formatString = "YYYY-MM-DDTJJ:NN:SS"
    return dateFormatter.format(timestamp) + "Z";
}
//ストリングをバイトに変換
public function hex2ByteArray(hex: String): ByteArray {
  var ret: ByteArray = new ByteArray();
  if (hex.substr(0, 2) == "0x") hex = hex.substr(2);
  for (var i: uint = 0; i < hex.length; i += 2) {
    ret[i / 2] = parseInt(hex.substr(i, 2), 16)
  }
  return ret;
}
//Base64
private function base64Encode(s:String):String{
    var encoder:Base64Encoder = new Base64Encoder();
    encoder.encodeUTFBytes(s);
    encoder.encode(s);
    return encoder.toString()
}
]]>
</mx:Script>
    <mx:Canvas x="10" y="10" width="286" height="245">
        <mx:Form x="10" y="10">
            <mx:FormItem label="E-mail" required="true">
                <mx:TextInput id="userTxt"/>
            </mx:FormItem>
            <mx:FormItem label="パスワード" required="true">
                <mx:TextInput id="passTxt"/>
            </mx:FormItem>
            <mx:FormItem label="mixiid" required="true">
                <mx:TextInput id="mixiidTxt"/>
            </mx:FormItem>
            <mx:FormItem label="日記タイトル" required="true">
                <mx:TextInput text="AIRから" id="titleTxt"/>
            </mx:FormItem>
            <mx:FormItem label="日記コメント" required="true">
                <mx:TextArea text="AIRから書き込み" id="commentTxt"/>
            </mx:FormItem>
            <mx:FormItem>
                <mx:Button label="書き込み!" click="send()"/>
            </mx:FormItem>
        </mx:Form>
    </mx:Canvas>
    <mx:VBox x="304" y="10" width="222" height="245">
        <mx:Label text="サーバー"/>
        <mx:TextArea id="myLog" width="100%" height="100%"/>
    </mx:VBox>
</mx:WindowedApplication>

as3corelibにはWSSEUsernameTokenっという便利な認証用クラスがあるんだけど、いまいちうまく認証できなかった。もしかしたらWSSEUsernameTokenでもっと簡単になるかも?
参考リンク