Hatena::ブログ(Diary)

ものおき@はてな

2009-06-02

キャラクタ系Twitterbotをつくってみた初心者向けまとめ そのいち

| 22:45 | キャラクタ系Twitterbotをつくってみた初心者向けまとめ そのいちを含むブックマーク

【2011/12】TwitterAPIのBasic認証が廃止されたため、このページそのままでは殆ど参考になりません。

比較的新しい情報は下記エントリにまとめてありますので、こちらをご参照ください。

Twitterbotを作る時に便利なリソースとかまとめてみた(2010/5/28更新) - ものおき@はてな

ついでにこっちも見て頂けるとうれしいです。

キャラクタ系TwitterBotを作る時に気をつけたい事つらつらと - ものおき@はてな

キャラクタ系botを作ってみたところ、意外と「作り方わからんけど作ってみたい!!」な人が多かったので、軽くまとめてみる試みです。

もとにしてるのが「動けばいいや!」でささーっと書いたものなので色々適当なのはごめんなさい。さして珍しい事書いてないので識者の人は読む価値ないです。

※想定する人

 bot作ってみたいけど何から始めたらいいか右も左も分かんない!な人。

 (ただし、自分で配布されているフリーのCGIなどを設置する事ができることを前提とします。)

※使用する言語

 超初心者でもとっつきやすいだろうという事でPHP。勝手にエラーも出るし。

※どのようなものをつくるか

 二次キャラクタ系bot

 ・基本的に特定のキャラの台詞を淡々とpost

 ・朝は眠り夜は起きる(今回はここまでやります)

 ・「おはよう」と「おやすみ」に対してリプライする

※はじめに

 文字コードutf-8がつかえるテキストエディタとPHP4.3以上が動くサーバ(cronがあるとなおよし)を用意してください。エディタwindowsならterapadmacならmiあたり。

 ローカル環境でのテストはXAMPPがあると便利です。

 PHP言語リファレンスに必ず目を通しておいてください。最低でも変数配列、比較演算子、if/else/elseif構文のあたりは確実に。

 文中、使用している関数やら構文やらのマニュアルへのリンク貼ってあります。合わせて参考にしていただければ。

1.メッセージの設定

 array()を利用して配列で設定するのが楽です。

		$mes['rand'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//通常のランダムpost
		$mes['morning'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//起床
		$mes['night'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );		//就寝前

 もっと細かく時間帯別に発言を変えたい時はこんな具合。

		$mes['rand'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//通常のランダムpost
		$mes['morning'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//起床
		$mes['day'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//午前中
		$mes['lunch'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//昼時
		$mes['noon'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//午後
		$mes['evening'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );	//夜
		$mes['night'] = array("台詞1" , "台詞2" , "台詞3" , "台詞4" );		//就寝前

2.時間判定

 date()関数を使って現在時刻を取得して、寝ている時間帯はpreg_match関数フラグを立ててやります。

	$now_g = date('G');
	$now_i = date('i');
	if (preg_match("/^[1-6]{0,1}$/",$now_g)){
		$now_g = 'sleep';
	};

 正規表現あまり得意じゃないです。ここでは0時におやすみpostをさせて7時におはようpostをさせたいので、「現在時刻の時間が1から6までの1桁の数字」であるかどうか判定して、そうだったら「寝てる」ことにしてます。

あと、ここは就寝してる時間帯が1桁台だったからpreg_matchつかっただけで、こんな具合でもいいわけです。というか、こっちでやった方がいいよ。

//深夜3時から昼10時が睡眠時間の時
if(($now_g > '3') && ($now_g < '10') ){
	$now_g = 'sleep';
}

 次にswitch構文で時間を判定して、どのメッセージ配列を使うか決定します。単純におはよう・ランダム・おやすみと機能させたいならこういう感じ。

switch(true){
	case $now_g == 'sleep' :	//寝ている時間帯だったら空の配列を指定
		$plist = array();
	break;
	case ($now_g == '0')&&($now_i >= '30') : //0時台かつ30分以降だったらおやすみメッセージの配列を指定
		$plist = $mes['night'];
	break;	
	case ($now_g == '7')&&($now_i <= '30') : //7時台かつ30分以前だったらおやすみメッセージの配列を指定
		$plist = $mes['morning'];
	break;	
	default :	//それ以外の場合はランダムメッセージ配列を指定
		$plist = $mes['rand'];
	break;
};

 30分置きに動かす事を想定してるので「30分以降だったら」とか書いてますけど、まあ気休め的なもんです。そこまで細かくやろうとは実はおもっていない。

 時間帯別にどうにかしたい時はこういう感じでcase文を書き足していきます。これは午前中を設定する例。

	case ($now_g == '8') or ($now_g == '9') or ($now_g == '10') or ($now_g == '11') : 
		$plist = $mes['day'];
	break;		

3.投稿するメッセージを決定

 さっきのswitch文で、変数$plistに送信するメッセージの候補が入った配列を代入してあるので、これをarray_rand関数で1つだけ取り出します。そのまえに、寝ていたら何もしないようにする事をお忘れなく。

 メッセージ配列が空かどうかの判定はempty関数をつかいます。こんな感じ。

	if(! empty($plist)){	//演算子「!」は否定なので、「$plistが空配列じゃなかったら」という意味ですよ
		$key = array_rand($mes_list);
		$post = $plist[$key];
	}

4.Twitterへの投稿

 一番簡単なのはService_Twitter(日本語版)を使う事。PHP4.3以上の環境なら動きます。

 サーバーにはこんな感じでアップすると動かしやすいです。あと、ダウンロードして使う場合、Twittter.phpの23行目をConnector.phpをインクルードできるように書き直す必要があります。Connector.phpのフルパスを書いてあげれば問題ないはずです。フルパスの調べ方はお使いになっているサーバに聞いてください。

ルート

bot本体.php

Twitter.php

Twitter(DIR)

  ┣ Connector.php

  ┣ Jsphon(DIR)

  ┣  ┗ Exception.php

  ┗ Jsphon.php

 postするだけならこんな具合。メッセージ配列が空の場合(=寝ている場合)は何もしたくないので、設定以外はさっきのif構文の中に書いていきます。

	//Service_Twitter設定
	require_once "Twitter.phpまでのフルパス"; 
		//別にフルパスじゃなくてもいいんですが、フルパスの方が確実かと思います。
	$user = 'twitterのユーザ名';
	$pass = 'twitterのパスワード';
	$st =& new Services_Twitter($user,$pass);

	if(! empty($plist)){
		$key = array_rand($mes_list);
		$post = $plist[$key];

		//ここから送信。Service_TwitterのsetUpdateメソッドを使います。
		try{
			$st->setUpdate($post);
		}catch (Exception $e) { 
			die('ERROR: ' . $e->getMessage());
		}
	};

 try〜catchはPHP5じゃないと動かないはずなので、PHP4の場合はこう書きかえたらいいのかな。

	if(! $st->setUpdate($post) ){
		die('ERROR');
	}

 リプライとかcroneの設定なんかの続きは、またいずれ。

halhal 2009/07/04 21:30 初めまして。
PHPでのbotのサンプルはあまりないので参考にさせていただいております。
続き楽しみにしております^^