php-twientを使って問いかけに返答するTwitter botを50行でつくる

飲み会のネタでとあるつぶやき対して、ある返信をするくだらないTwitter botを作ったらえらく好評だった。以前作成したphp-twientというライブラリを数年ぶりに更新して作成したので似たようなbotを作るためのサンプルプログラムを紹介。

レシピ

  • PHP 5.3以上が実行できるマシン→今回は自宅サーバでコンソールから実行、時計をあわせておかないと401 Unauthorizedになる件
  • Twitterアプリケーション登録→https://dev.twitter.com/appsX30Xから作成する。投稿するのでAccess levelをRead and writeにしておく
  • bot用のTwitterアカウント
  • phpとかgitとかcomposerを使うための知識
  • やる気とbotのアイディア

php-twientのインストール

プログラムは github 上で 公開している ( php-twient )。composerパッケージとしてpushしたのでcomposerから簡単にインストールできる。プロジェクトに以下のようなcomposer.jsonを作成しておく。

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/makotokw/php-twient"
        }
    ],
    "require": {
        "makotokw/twient": "dev-master"
    }
}
curl -s http://getcomposer.org/installer | php
php composer.phar install

を実行するとするとvendorディレクトリにライブラリが配置される。

つぶやきに返信するbotの作成

今回はbotに対してつぶやかれた内容に返信するというものを作った。例えば定期的にmentionを拾いにいって返信する方法もあるが、userのタイムラインをウォッチするStreaming APIを見つけたのでそれを使う。

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Twient\Twitter\V1dot1 as Twitter;

try {
    $twitter = new Twitter();
    $twitter->oAuth(
        TWITTER_CUNSUMER_KEY,
        TWITTER_CUNSUMER_SECRET,
        TWITTER_BOT_TOKEN,
        TWITTER_BOT_SECRET
    );
    $twitter->streamingUser(
        array(),
        function (Twitter $twitter, $status) {
            if ($status) {
                if (isset($status['text'])) {
                    $t = $status['text'];
                    if (strpos($t, '@' . TWITTER_BOT_SCREEN_NAME) !== false) {
                        $twitter->statusesUpdate(
                            array(
                                'status'                => createResponseStatus($status),
                                'in_reply_to_status_id' => $status['id_str']
                            )
                        );
                    }
                }
            }
            return true;
        }
    );
} catch (Exception $e) {
    echo $e;
}

function createResponseStatus($status)
{
    $user = $status['user'];
    $text = $status['text'];
    $text = preg_replace('/\s?@' . TWITTER_BOT_SCREEN_NAME . '\s?/', '', $text);
    $text = preg_replace('/はありますか/', '', $text);
    $text = preg_replace('/(?|\?)\s*/', '', $text);
    return '@' . $user['screen_name'] . ' む!' . $text . '!!';
}

以上が簡単なサンプルプログラム。「他に頼みたい仕事はありますか?」と問いかけられると「む!他に頼みたい仕事!!」と返答する。ちなみに終了のルーチンを入れていないのでkillさせないといけない。

投稿するときにin_reply_to_status_idを入れて呟いても返信にならず、一応相手のscreen_nameを内容に入れないといけない仕様らしい。

Streaming APIとclosureを使って45行ととてもシンプルなプログラムになっている。createResponseStatus関数をわけなければもっと短くできるが、これはcreateResponseStatusを置き換えるだけで流用が可能ということであえてこういうサンプルにしている。このサンプルコードはネタなので他の人から見れば意味が無いbotだが、アイディアしだいでいろいろできると思う。

TWITTER_CUNSUMER_KEY, TWITTER_CUNSUMER_SECRETはアプリケーション登録でもらえるもの。TWITTER_BOT_TOKEN, TWITTER_BOT_SECRETは以下のおまけを参照。

おまけ: OAuthTokenの取得方法

php-twientでは以下のようなプログラムをコンソールから実行して、ブラウザでピン番号を取得してまたコンソールに入力すればOAuthTokenの取得ができる。

$twitter = new Twitter();
$oauth = $twitter->oAuth(TWITTER_CUNSUMER_KEY, TWITTER_CUNSUMER_SECRET);
$requestToken = $oauth->getRequestToken();
$url = $oauth->getAuthorizeUrl($requestToken);
echo 'ブラウザでこれを開く'.$url.PHP_EOL;
echo 'Input PIN: ';
$pin = trim(fgets(STDIN,4096));
if (empty($pin)) exit;
$token = $oauth->getAccessToken($pin);
echo 'Your token is "'.$token['oauth_token'].'"'.PHP_EOL;
echo 'Your secret token is "'.$token['oauth_token_secret'].'"'.PHP_EOL;