2012/04/05

相手のキーフレーズ+定型文で作文

reply_pattern.phpにキーワードが見つからない場合に、相手の発言の中から重要らしい単語を抜き出して、定型文と組み合わせてリプライを作成します。

EasyBotter.phpの改造ですが、改造箇所が複数に亘るのでご注意ください。
また、Yahoo!デベロッパーズネットワークのWEB APIキーフレーズ抽出を使用しますので、前もってアプリケーションIDを取得しておいてください。

class EasyBotter {

  // 最初のプライベート変数宣言群に追加
  private $_api_key_yahoo = '取得したアプリケーションID';
  private $_api_url_yahoo_keyphrase = 'http://jlp.yahooapis.jp/KeyphraseService/V1/extract?appid=';

  // 途中省略

  // キーフレーズを元にした発言を作るメソッドを丸ごと追加
  // $text:キーフレーズ取得対象文字列(つまり相手のツイート)
  private function makeKeyphraseTweet($text) {
    $api_key_yahoo = $this->_api_key_yahoo;
    $api_url_yahoo_keyphrase = $this->_api_url_yahoo_keyphrase;
    $keyphrase = "";
    
    // 文字列から@とハッシュタグとURLを取り去る
    $text = preg_replace('/(#)(\w+)/', '', $text);
    $text = preg_replace('/(@)(\w+)/', '', $text);
    $text = preg_replace('/(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/', '', $text);

    // 文字列をUTF-8でエンコードし、さらにURLエンコード
    $sentence = urlencode(mb_convert_encoding($text, 'utf-8', 'auto'));
    
    //Yahoo!キーフレーズ抽出からXMLを取得
    $keyphrase_url = $api_url_yahoo_keyphrase.$api_key_yahoo."&sentence=".$sentence."&output=xml";
    $keyphrase_xml = simplexml_load_file($keyphrase_url);

    // キーフレーズの個数
    $keyphrase_num = count($keyphrase_xml->Result);
    
    for($i=0; $i<$keyphrase_num; $i++){
      $result = $keyphrase_xml->Result[$i];
      // スコア100のフレーズだけ持って出る
      if(htmlspecialchars($result->Score, ENT_QUOTES) == 100) {
        $keyphrase = htmlspecialchars($result->Keyphrase, ENT_QUOTES);
        break;
      }
    }

    // 返却バリエーションをつける
    $fix_sentence = array(
      "{keyphrase}について興味が湧いた。少し話を聞かせてくれないか。",
      "{keyphrase}……? それはいったい何のことだ?",
      "{keyphrase}がどうかしたのか?",
      "俺は{keyphrase}に興味なんてない。",
      "{keyphrase}については、俺も耳にしたことがある。",
      "{keyphrase}に関するデータ……オールクリア……。",
    );
    if($keyphrase !== "") {
      // 別途使うのでword.csvに保存しておく
      $fp = fopen('word.csv', 'a') or die('ファイルが開けません');
      fwrite($fp, "\"".$keyphrase."\"\n");
      fclose($fp);
      // 定型文をランダム選択
      $key = array_rand($fix_sentence);
      return str_replace("{keyphrase}", $keyphrase, $fix_sentence[$key]);
    } else {
      // キーフレーズがひとつも見つからなかった場合は[[END]]を返す
      return "[[END]]";
    }
    return "[[END]]";
  }

  // 途中省略

  //リプライを作る
  private function makeReplyTweets($replies, $replyFile, $replyPatternFile){
    // 途中省略
    if(empty($status) && !empty($replyFile)){
    //パターンになかった場合はランダムに
      // ここから変更
      if(rand(0,2) == 0){
        $status = $this->makeTweet($replyFile);
      } else {
        $status = $this->makeKeyphraseTweet((string)$reply->text);
        // 救済措置
        if($status == "[[END]]") {
          $status = $this->makeTweet($replyFile);
        }
      }
    // ここまで変更
    }
  }

  // 以降省略

}

よく考えると勝手にfunctionの前にprivateとか足してますね……。

使用関数

  • simplexml_load_file(url)
    指定したURLにアクセスしてXMLデータを取得する。