FlexでTwitterクライアントを作ってみた。

Flexで読み書きできるTwitterクライアントを作ってみました。
#後輩がかなり作り込んでたので、ソースをもらって自分流にちょっと追加してみました。
こんな感じ
http://moeten.info/flex/20080502_twitterFlex/bin-release/main.html
#捨てアカなので書き込みしてみてください。

Twitterの表示用アドレス

http://twitter.com/statuses/friends_timeline/yourid.xml

URLにアクセスすればOK
書き込みはBasic認証が必要とのこと
AS3ではBASE64やらURLRequestHeaderやらでいいとこまでいけたんだけど結局ダメだった。
公式にURLRequestHeaderはAuthorizationのヘッダは送れないよって書いてあるから当たり前なんだけど、自前でもなんかうまくいかなかった。
それで代わりにPHPで認証をしました。

<?php
$twitter_username = $_POST['username'];
$twitter_psw      = $_POST['password'];
if(isset($_POST['msg'])){
    $twitter_message=$_POST['msg'];
    if(strlen($twitter_message)<1){
        $error=1;
    } else {
        echo $twitter_status=postToTwitter($twitter_username, $twitter_psw, $twitter_message);
    }
 }
function postToTwitter($username,$password,$message){
    $host = "http://twitter.com/statuses/update.xml?status=".urlencode(stripslashes(urldecode($message)));
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $host);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_POST, 1);
    $result = curl_exec($ch);
    // Look at the returned header
    $resultArray = curl_getinfo($ch);
    curl_close($ch);
    if($resultArray['http_code'] == "200"){
        $twitter_status='Your message has been sended! <a href="http://twitter.com/'.$username.'">See your profile</a>';
    } else {
        $twitter_status="Error posting to Twitter. Retry";
    }
    return $twitter_status;
}
?>

これでphpにusernameとpasswordと追加したいメッセージをPOSTで送ればphpが代わりに認証やらアップデートをしてくれます。
curlを使って認証をおこなっているので、curlを有効にする必要があります。
php.iniファイルのextensionの項目でcurlをオンにしてapache再起動でOK。
また、コメント一覧を取得する際、ドメイン問題のため、phpでプロキシを用意します。
っていうかドメイン問題が面倒なので、phpでプロキシを作成しておくといろんなアプリで使えるので便利です。

<?php
if( $_GET['u'] != "" ){
    $u = urldecode( $_GET['u'] );
    echo file_get_contents( $u );
}
?>

これで認証とドメイン問題が解決するのであとはFlexでガワを作るだけです。
Flexソースコードはこちら

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    width="612" height="554"
    creationComplete="init()"
    horizontalScrollPolicy="off"
    verticalScrollPolicy="off"
     alpha="1.0" borderColor="#FFFFFF" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #BBB0D8]" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
//初期化関数
private function init():void{
    myLog.visible = false;
    upDate();
}
//XMLデータ更新
private function upDate():void{
    var timer:Timer = new Timer(60000);//1分ごとに実行
    timer.addEventListener(TimerEvent.TIMER , myTimer );
    timer.start();
    getMessage.send();
    dgShow.play();
}
//タイマーイベント
private function myTimer(e:Event):void{
    getMessage.send();
}
//XML読み込み完了イベ0ント
private function onResult():void{
    myImage.source = "" + getMessage.lastResult.status.user[0].profile_image_url;
}
//コメント書き込み
private function sendTo():void{
    if(  usernameText.text != null &&  passwordText.text != null){
        sendMessage.send({
            "username":usernameText.text,
            "password":passwordText.text,
            "msg":msg.text
        });
        myLog.text = "send";
    }
}
private function onSended():void{
    getMessage.send();
    myLog.text = "sended";
    myLog.text += "" + sendMessage.lastResult;
}
]]>
</mx:Script>
<!--############# HTTPService ################-->
<mx:HTTPService id="getMessage" useProxy="false" resultFormat="e4x"
    url="{'http://moeten.info/flex/20080502_twitterAir/myproxy.php?u=http://twitter.com/statuses/friends_timeline/'+usernameText.text+'.xml'}"
    result="onResult()" showBusyCursor="true"/>
<mx:HTTPService id="sendMessage" useProxy="false" resultFormat="text"
    url="http://moeten.info/flex/20080502_twitterAir/insertTwitterMsg.php"
    result="onSended()" showBusyCursor="true" method="POST"/>
<!--############# エフェクト ################-->
<mx:Sequence id="dgShow" target="{dg}">
    <mx:Zoom zoomHeightFrom="0.8" zoomHeightTo="1" zoomWidthFrom="0.8" zoomWidthTo="1.0"/>
    <mx:Glow blurXTo="10" blurYTo="10" color="0xff0000"/>
</mx:Sequence>
<!--############# コンポーネント ################-->
<mx:Image id="myImage" x="10" y="10" width="135" height="133" />
<mx:Label x="168" y="43" text="今何してる?" fontSize="30" fontWeight="bold"/>
<mx:Button y="10" label="ログ取得" right="10"  click="upDate()" width="132" height="23" fontSize="12"/>
<mx:TextInput id="msg" right="150" top="93" left="168" text="test" height="52" fontSize="30"/>
<mx:Button y="91" label="送信" right="10"  click="sendTo()" width="132" height="52" fontSize="27"/>
<mx:DataGrid id="dg" dataProvider="{getMessage.lastResult.status}"
    resizableColumns="false" right="10" bottom="10" top="151" left="10">
    <mx:columns>
        <mx:DataGridColumn width="150" headerText="ID" resizable="false" minWidth="150">
            <mx:itemRenderer>
                <mx:Component>
                    <mx:Label text="{data.user.name}"/>
                </mx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
        <mx:DataGridColumn headerText="コメント" dataField="text"/>
    </mx:columns>
</mx:DataGrid>
<mx:TextInput id="usernameText" x="185" y="12" text="hatenaflexguest" width="76"/>
<mx:TextInput id="passwordText" x="333" y="12" text="flexguest" displayAsPassword="true" width="115"/>
<mx:TextArea id="myLog" x="10" y="271" height="271" width="274"/>
    <mx:Label x="159" y="14" text="ID"/>
    <mx:Label x="269" y="14" text="Password"/>
</mx:Application>