Skip to content

Instantly share code, notes, and snippets.

@ksz
Created July 2, 2010 04:01
Show Gist options
  • Save ksz/460909 to your computer and use it in GitHub Desktop.
Save ksz/460909 to your computer and use it in GitHub Desktop.
<?php
App::import('Vendor', 'twitteroauth', array('file' => 'twitteroauth'.DS.'twitteroauth'.DS.'twitteroauth.php'));
class HakatasanShell extends Shell
{
var $uses = array('HakatasanTweet', 'HakatasanResponse', 'HakatasanQuestion', 'LastTimeline', 'LastMention');
//Consumer keyの値
var $consumer_key = "";
//Consumer secretの値
var $consumer_secret = "";
//Access Tokenの値
var $access_token = "";
//Access Token Secretの値
var $access_token_secret = "";
function main()
{
}
/*
* 単独ツイート(ランダム)
*/
function tweet()
{
$to = new TwitterOAuth($this->consumer_key, $this->consumer_secret, $this->access_token, $this->access_token_secret);
$tweets = $this->HakatasanTweet->findAll();
$mes = $tweets[rand(0, count($tweets) - 1)]['HakatasanTweet']['tweet'];
//TwitterへPOSTする。パラメーターは配列に格納する
$result = $to->OAuthRequest("http://api.twitter.com/1/statuses/update.xml", "POST", array("status" => $mes));
//echo $result;
}
/*
* タイムラインを解析してリプライ
*/
function timeline()
{
$questions = $this->HakatasanQuestion->findAll();
$last_timeline = $this->LastTimeline->findByName('hakatasan');
$last_status_id = $last_timeline['LastTimeline']['status_id'];
$last_created_at = $last_timeline['LastTimeline']['created_at'];
$to = new TwitterOAuth($this->consumer_key, $this->consumer_secret, $this->access_token, $this->access_token_secret);
$result = $to->OAuthRequest("http://api.twitter.com/1/statuses/friends_timeline.xml", 'GET', array('count' => 10));
if (strstr($result, 'Twitter is over capacity.')) {
exit();
}
$xml = simplexml_load_string($result);
// 1回の実行につき1ユーザ1リプライ
$post_users = array();
foreach($xml->status as $value) {
$status_id = $value->id; //個別発言のステータスID
$created_at = $value->created_at; //発言時刻
$text = $value->text; //発言内容
$screen_name = $value->user->screen_name; //発言者のtwitterID
if (!$status_id) {
exit(0);
}
// 最後に処理した発言IDor発言時刻より前は処理しない
if ($last_status_id == $status_id || $last_created_at > $created_at) {
break;
}
// 今回処理済のユーザは無視
if (in_array($screen_name, $post_users)) {
continue;
}
// 自分の発言は無視
if ($screen_name == 'hakatasan') {
continue;
}
// メンションは無視
if (strstr($text, '@hakatasan')) {
continue;
}
// リプライは無視
if (substr($text, 0, 1) == '@') {
continue;
}
$status = '';
// 伯方語への応答
if (!$status) {
if (mb_ereg("[あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?[あ-ん][ぁ-ぉゃ-ょ]?!", $text, $res)) {
$status = $this->createRT($text, $screen_name, $res[0]);
} else if (mb_ereg("[あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?[あ-ん][ぁ-ぉゃ-ょ]?♪", $text, $res)) {
$status = $this->createRT($text, $screen_name, $res[0]);
}
if ($status) {
if (!$t = $this->HakatasanTweet->find(array('tweet' => $res[0]))) {
$this->HakatasanTweet->create();
$this->HakatasanTweet->save(array('tweet' => $res[0]));
}
}
}
// 特定文字列を含むリプライへの応答
if (!$status) {
foreach ($questions as $question) {
if (strstr($text, $question['HakatasanQuestion']['q'])) {
if ($question['HakatasanQuestion']['type']) {
$status = $this->createRT($text, $screen_name, $question['HakatasanQuestion']['a']);
} else {
$status = $this->createRep($screen_name, $question['HakatasanQuestion']['a']);
}
}
}
}
if (!$status) {
$status = $this->createStatus($text, $screen_name);
if ($status) {
$status = $this->createRep($screen_name, $status);
}
}
if ($status) {
//TwitterへPOSTする。パラメーターは配列に格納する
$r=$to->OAuthRequest("http://api.twitter.com/1/statuses/update.xml", "POST", array("status" => $status,
"in_reply_to_status_id" => "$status_id"));
$post_users[] = (String)$screen_name;
echo $status_id . ' : ' . $status . "\n";
$result .= "\n" . $status_id . ' : ' . $status;
echo $r;
$this->postlog();
}
}
$value = $xml->status[0];
$last_timeline['LastTimeline']['status_id'] = $value->id;
$last_timeline['LastTimeline']['created_at'] = date('Y-m-d H:i:s', strtotime($value->created_at));
$this->LastTimeline->save($last_timeline);
if (strstr($r, 'User is over daily status update limit.')) {
file_put_contents('/var/www/cake/apps/bot/tmp/logs/hakatasan/timeline/' . date('YmdHis'), $r);
}
}
/*
* メンションを解析してリプライ
*/
function mention()
{
$responses = $this->HakatasanResponse->findAll();
$questions = $this->HakatasanQuestion->findAll();
$last_mention = $this->LastMention->findByName('hakatasan');
$last_status_id = $last_mention['LastMention']['status_id'];
$last_created_at = $last_mention['LastMention']['created_at'];
$to = new TwitterOAuth($this->consumer_key, $this->consumer_secret, $this->access_token, $this->access_token_secret);
$result = $to->OAuthRequest("http://api.twitter.com/1/statuses/mentions.xml", "GET", array("count" => 10));
if (strstr($result, 'Twitter is over capacity.')) {
exit();
}
$xml = simplexml_load_string($result);
foreach($xml->status as $value) {
$status_id = $value->id; //個別発言のステータスID
$created_at = $value->created_at; //発言時刻
$text = $value->text; //発言内容
$screen_name = $value->user->screen_name; //発言者のtwitterID
if (!$status_id) {
exit(0);
}
// 最後に処理した発言IDor発言時刻より前は処理しない
if ($last_status_id == $status_id || $last_created_at > $created_at) {
break;
}
if ($screen_name == 'hakatasan') {
continue;
}
// フォロー
if ($value->user->following == 'false') {
$to->OAuthRequest("http://api.twitter.com/1/friendships/create/{$screen_name}.xml", "POST", array());
}
// ふぁぼる
if (strstr($text, 'RT @hakatasan') || strstr($text, 'QT @hakatasan')) {
$to->OAuthRequest("http://api.twitter.com/1/favorites/create/{$status_id}.xml", "POST", array());
}
$status = '';
// 特定文字列を含むリプライへの応答
if (!$status) {
foreach ($questions as $question) {
if (strstr($text, $question['HakatasanQuestion']['q'])) {
if ($question['HakatasanQuestion']['type']) {
$status = $this->createRT($text, $screen_name, $question['HakatasanQuestion']['a']);
} else {
$status = $this->createRep($screen_name, $question['HakatasanQuestion']['a']);
}
}
}
}
// 伯方語への応答
if (!$status) {
if (mb_ereg("[あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?[あ-ん][ぁ-ぉゃ-ょ]?!", $text, $res)) {
$status = $this->createRT($text, $screen_name, $res[0]);
} else if (mb_ereg("[あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?![あ-ん][ぁ-ぉゃ-ょ]?[あ-ん][ぁ-ぉゃ-ょ]?♪", $text, $res)) {
$status = $this->createRT($text, $screen_name, $res[0]);
}
if ($status) {
if (!$t = $this->HakatasanTweet->find(array('tweet' => $res[0]))) {
$this->HakatasanTweet->create();
$this->HakatasanTweet->save(array('tweet' => $res[0]));
}
}
}
// 通常の応答
if (!$status) {
$status = $this->createStatus($text, $screen_name);
if ($status) {
$status = $this->createRep($screen_name, $status);
} else {
$mes = $responses[rand(0, count($responses) - 1)]['HakatasanResponse']['tweet'];
if (strstr($text, 'RT') || strstr($text, 'QT')) {
$status = $this->createRT($text, $screen_name, $mes);
} else {
$status = $this->createRep($screen_name, $mes);
}
}
}
//TwitterへPOSTする。パラメーターは配列に格納する
$to->OAuthRequest("http://api.twitter.com/1/statuses/update.xml", "POST", array("status" => $status,
"in_reply_to_status_id" => "$status_id"));
echo $status . "\n";
$result .= "\n" . $status;
$this->postlog();
}
$value = $xml->status[0];
$last_mention['LastMention']['status_id'] = $value->id;
$last_mention['LastMention']['created_at'] = date('Y-m-d H:i:s', strtotime($value->created_at));
$this->LastMention->save($last_mention);
//file_put_contents('/var/www/cake/apps/bot/tmp/logs/hakatasan/mention/' . date('YmdHis'), $result);
}
/*
* 自動リフォロー
*/
function refollow()
{
$to = new TwitterOAuth($this->consumer_key, $this->consumer_secret, $this->access_token, $this->access_token_secret);
$result = $to->OAuthRequest("http://api.twitter.com/1/statuses/followers.xml", "GET", array());
$xml = simplexml_load_string($result);
//echo $result;
foreach($xml->user as $user) {
if ($user->following == 'false') {
$screen_name = $user->screen_name;
echo $screen_name . " ";
$result = $to->OAuthRequest("http://api.twitter.com/1/friendships/create/{$screen_name}.xml", "POST", array());
$xml = simplexml_load_string($result);
//echo $result;
echo $xml->error . "\n";
}
}
}
/*
* 自動フォロー
*/
function follow()
{
$query = urlencode('伯方');
$url = "http://search.twitter.com/search.atom?q={$query}";
$xml = simplexml_load_file($url);
$results = array();
foreach($xml->entry as $entry) {
$result['screen_name'] = r('http://twitter.com/', '', $entry->author->uri);
$result['text'] = (String)$entry->title;
$results[] = $result;
}
$to = new TwitterOAuth($this->consumer_key, $this->consumer_secret, $this->access_token, $this->access_token_secret);
foreach ($results as $result) {
$screen_name = $result['screen_name'];
echo $screen_name . "\n";
$to->OAuthRequest("http://api.twitter.com/1/friendships/create/{$screen_name}.xml", 'POST', array());
}
}
/*
* Tweet内容を生成する
*/
function createStatus($text, $screen_name = null)
{
// 文字列生成完了フラグ
$complete = false;
// 文字列生成開始フラグ
$start_f = false;
// 文字列格納
$mes = '';
// 文字列(音)の長さ
$len = 0;
// 完成文字列
$status = '';
if ($text != "") {
$xml = $this->maRequest($text);
foreach ($xml->ma_result->word_list->word as $cur) {
// ひらがな以外が含まれているセンテンスは無視
if (!mb_ereg("^[あ-ん]+$", $cur->reading)) {
$mes = '';
$len = 0;
$start_f = false;
continue;
}
// 名詞があったらそこから生成を始める
if (!$start_f && $cur->pos == '名詞') {
$start_f = true;
}
if ($start_f) {
$mes .= $cur->reading;
$len += strlen($cur->reading);
// 小文字は1音に含めないようにする
for ($i = 0; $i < strlen($cur->reading); $i += 3) {
$str = substr($cur->reading, $i, 3);
if (mb_ereg("^[ゃゅょ]+$", $str)) {
$len -= 3;
}
}
// 日本語6文字で完成
if ($len == 18) {
$complete = true;
break;
} else if ($len > 18) {
// 6文字をオーバーした場合は無効
$mes = '';
$len = 0;
$start_f = false;
}
}
}
// 記号を付加
$cnt = 0;
if ($complete) {
for ($i = 0; $i < strlen($mes); $i += 3) {
$status .= substr($mes, $i, 3);
if (!mb_ereg("^[ゃゅょ]+$", substr($mes, $i + 3, 3))) {
if ($cnt < 4) {
$status .= '!';
$cnt ++;
}
}
}
$status .= '♪';
if (strstr($status, 'っ♪')) {
$status = '';
}
return $status;
}
}
return $status;
}
/*
* リプライ文を生成する。
*/
function createRep($screen_name, $tweet)
{
$status = '@' . $screen_name . ' ' . $tweet;
return $status;
}
/*
* RT文を生成する。文字数オーバーならリプライ。
*/
function createRT($text, $screen_name, $tweet)
{
$status = $tweet . ' RT ' . '@' . $screen_name . ' ' . $text;
if (mb_strlen($status) >= 140) {
$status = $this->createRep($screen_name, $tweet);
}
return $status;
}
/*
Yahooの形態日本語解析APIへ問い合わせを行う
*/
function maRequest($sentence)
{
$url = "http://jlp.yahooapis.jp/MAService/V1/parse?";
$url .= "appid=APIキー&";
//$url .= "results=ma&";
//$url .= "filter=9&";
$url .= "sentence=" . urlencode($sentence);
$xml = simplexml_load_file($url);
return $xml;
}
function postlog()
{
@mkdir(LOGS . DS . 'hakatasan' . DS . 'posts');
if ($cnt = @file_get_contents(LOGS . DS . 'hakatasan' . DS . 'posts' . DS . date('Y-m-d-H'))) {
$cnt ++;
} else {
$cnt = 1;
}
file_put_contents(LOGS . DS . 'hakatasan' . DS . 'posts' . DS . date('Y-m-d-H'), $cnt);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment