Twitterのbotを作ってみた

number_bot(http://twitter.com/number_bot)は投稿数が何かの数に達すると通知するbotです。基本的には素数ですが、たまに変なものも通知します。

稼動:2009.09.27〜

素数以外に実装されている数列と、最初にそのreplyを受けた人を発見者として記録しておきます。
「〜数とか全然わかんねぇよ!」という方は解説記事へどうぞ。→number_bot解説 - math, programming, and little something to laugh

数列名 発見者 実装 出現日
2^n dhileilu 2009.09.27 2009.09.28
5^n cachetteholic 2009.09.27 2009.09.30
7^n azmny 2009.09.27 2009.09.27
11^n ossty 2009.09.27 2009.09.29
13^n ossty 2009.09.27 2009.10.04
17^n xlis 2009.09.27 2009.10.02
19^n Eagh 2009.09.27 2009.09.29
完全数 yniimi 2009.09.27 2009.09.30
レピュニット ayakashi_oyadi 2009.09.27 2009.10.02
メルセンヌ数 bardothodol 2009.09.27 2009.10.01
フィボナッチ数 cachetteholic 2009.09.27 2009.09.28
トリボナッチ数 aomoriringo 2009.09.27 2009.09.28
テトラナッチ数 yananan_ 2009.09.27 2009.09.28
回文平方数 Grabacr07 2009.09.27 2009.09.29
カタラン数 Grabacr07 2009.09.27 2009.09.28
完全トーティエント数 akaari 2009.09.27 2009.09.28
リュカ数 tasogarenastan 2009.09.27 2009.09.27
カーマイケル数 p_lost 2009.09.27 2009.09.28
カプレカ数 violante306 2009.09.27 2009.09.28
タンジェント Azr_pp 2009.09.27 2009.10.07
回文素数 akaari 2009.09.27 2009.09.28
??? 2009.10.02
アキレス数(10) Eagh 2009.10.02 2009.10.02
エマープ(100) falsie 2009.10.02 2009.10.02
スミス数(100) akazora 2009.10.02 2009.10.02
ハーシャッド数(1000) magtam 2009.10.03 2009.10.04
ナルシスト数 execr 2009.10.03 2009.10.04
ズッカーマン数(10) yananan_ 2009.10.03 2009.10.04
???(10000) 2009.10.03
???(10) 2009.10.20
???(10000) 2009.10.20
超過剰数 varenatires 2009.10.20 2009.10.20


ver 1.03 / 2009.10.20
数列を3つ追加しました(???・???・超過剰数)。

ver 1.02 / 2009.10.03
数列を4つ追加しました(ハーシャッド数・ナルシスト数・ズッカーマン数・???)。

ver 1.01 / 2009.10.02
数列を4つ追加しました(???・アキレス数・エマープ・スミス数)。

                                                                                                                          • -


以下ソースコード
今回はPHPで書きました。
大きく分けて、IDnumberを読み取ってTwitterに投稿する部分と、followerとfriendsを同期させる部分の2つにわかれています。
正直前半は誰得ですが、follower - friends同期は流用が効く、かもね

<?php
/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
        //数列
        //完全数
        $perfect = array(6, 28, 496, 8128, 33550336);
        //フィボナッチ数
        $fibonacci = array(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040);

        //以降適当に数列などを追加


        require_once 'Services/Twitter.php';
        require_once 'HTTP/Client.php';
        $username = 'ゆーざーねーむ';
        $password = 'ぱすわーど';


        $url = "http://twitter.com/statuses/update.xml?";

        $basic = array('Authorization'=>'Basic '.base64_encode($username.':'.$password));
        $client = new HTTP_Client(null, $basic);

        $filename = "c:/xampp/htdocs/newid.txt";
        $fp = @fopen($filename , "r");
        $loadid = fgets($fp);
        fclose($fp);

        $apiurl = "http://twitter.com/statuses/friends_timeline.xml?since_id=".$loadid."";


        //$apiurl = "http://twitter.com/statuses/friends_timeline.xml";
        $client->get($apiurl);
        $response = $client->currentResponse();
        $body = mb_convert_encoding($response['body'], "UTF-8","JIS,UTF-8,SJIS,EUC-JP");

        $sxe = new SimpleXMLElement($body);

        //print_r($sxe);

        // 一番新しい発言者のidを取得
        // if分は、新規更新がなかったときにnullを書き込まれると、次回の読み込みでまずいことになるので。
        $newid = $sxe->status[0]->id;
        if($newid > 10000){
            $fp = fopen($filename,"w");
            fwrite($fp, $newid);
            fclose($fp);
        }


        //新規発言userの名前を配列arr_screen_nameに入れる。
        //取得した中で一番古い発言が0番目に入る。
        $arr_screen_name = array();
        for($i = 0 ; $i < count($sxe->status) ; $i++){
            $tmp = $sxe->status[$i]->user->screen_name;
            array_unshift($arr_screen_name, $tmp);
        }

        //新規発言userのpost数を配列arr_statuses_countに入れる。
        //取得した中で一番古い発言が0番目に入る。
        $arr_statuses_count = array();
        for($i = 0 ; $i < count($sxe->status) ; $i++){
            $tmp = $sxe->status[$i]->user->statuses_count;
            array_unshift($arr_statuses_count, $tmp);
        }



        $arrmes = array();

        for($i = 0 ; $i < count($sxe->status) ; $i++){
            $num = $arr_statuses_count[$i];

            $th = 0;
            $word = null;
            $type = 0;

          if($num >= 100){
            if(in_array($num, $perfect)){
                $th = sequenceSearch($num,$perfect);
                $word = "完全数";
                $type = 1;
            }
            else if(in_array($num, $fibonacci)){
                $th = sequenceSearch($num,$fibonacci);
                $word = "フィボナッチ数";
                $type = 1;
            }


            if($word!=null && $type==1 && $arr_screen_name[$i]!="number_bot"){
                array_push($arrmes, "@".$arr_screen_name[$i]." さんの投稿数が".$th."番目の".$word.$num."に達しました" );
            }


          }

        }

        print_r($arrmes);

        // $arrmesの中身を順に投稿
        for($i = 0 ; $i < count($arrmes) ; $i++){
        $params = "status=". rawurlencode($arrmes[$i]);
        $result = file_get_contents($url.$params , false, stream_context_create(array(
                "http" => array(
                        "method" => "POST",
                        "header" => "Authorization: Basic ". base64_encode($username. ":". $password)
                )
        )));
        }

/******************************************************************/

        // friendsとfollowerを同期させる
        // followerにあってfriendにない人をフォロー
        // friendにあってfollowerにない人をremove
        //$basic = array('Authorization'=>'Basic '.base64_encode($username.':'.$password));


        // friendsのidを取得
        $client = new HTTP_Client(null, $basic);
        $apiurl = "http://twitter.com/friends/ids.xml";
        $client->get($apiurl);
        $response = $client->currentResponse();
        $body = mb_convert_encoding($response['body'], "UTF-8","JIS,UTF-8,SJIS,EUC-JP");

        $sxe2 = new SimpleXMLElement($body);

        //friendsのid全てを arr_friendsにいれる
        $arr_friends = array();
        for($i = 0 ; $i < count($sxe2->id) ; $i++){
            $tmp = $sxe2->id[$i];
            array_push($arr_friends, (int)$tmp);
        }

        //followersのidを取得
        $client = new HTTP_Client(null, $basic);
        $apiurl = "http://twitter.com/followers/ids.xml";

        $client->get($apiurl);
        $response = $client->currentResponse();
        $body = mb_convert_encoding($response['body'], "UTF-8","JIS,UTF-8,SJIS,EUC-JP");

        $sxe3 = new SimpleXMLElement($body);

        //followersのid全てを arr_followersにいれる
        $arr_followers = array();
        for($i = 0 ; $i < count($sxe3->id) ; $i++){
            $tmp = $sxe3->id[$i];
            array_push($arr_followers, (int)$tmp);
        }


        // followersがfriendsになかった場合、followをする
        for($i=0 ; $i < count($arr_followers) ; $i++){
            $id_num = $arr_followers[$i];
            if(  in_array( (int)$id_num, $arr_friends, false )==FALSE  ){
                echo "follower". $arr_followers[$i] ." not found in friends\n";
                $client = new HTTP_Client(null, $basic);
                $follow_url = "http://twitter.com/friendships/create/".$arr_followers[$i].".xml";
                $client->post($follow_url, $post_param);
            }
        }
         

        // friendsがfollowersになかった場合、removeをする
        $post_param = array();
        for($i=0 ; $i < count($arr_friends) ; $i++){
            $id_num = $arr_friends[$i];
            if(  in_array( (int)$id_num, $arr_followers, false )==FALSE  ){
                echo "friend". $arr_friends[$i] ." not found in followers\n";
                
                $client = new HTTP_Client(null, $basic);
                $follow_url = "http://twitter.com/friendships/destroy/".$arr_friends[$i].".xml";
                $client->post($follow_url, $post_param);
                 
                 
            }
        }



function sequenceSearch($num, $array){
    for($j=0 ; $j<count($array) ; $j++){
        if($num==$array[$j]) break;
    }
    return $j+1;
}


?>