twitterでフォローのお礼&フォロー返し

ご注意!

ここでご紹介しているスクリプトは、Twitter API の仕様変更により現在は動作しません!(2010/09/06)

twitter apiでフォローされたらそのメールをsmtpサーバーでキックして、フォロー返し&お礼を送信するbotを作成した。

当初は、cronでやっていたのだが、フォロワー一覧を取得するためのAPIがとても不安定だったのと、複数アカウントに対応するのに負荷を軽減したかったので、メールでキックする方法に変更した。

ちなみに、昨日の時点ではGoogle app engineを使おうと思ったのだが、あっさり気が変わった。

smtpサーバーの設定

今回はpostfixを使用した。
/etc/postfix/main.cfなどで正規表現を使ったエイリアスを設定するのがポイント。

詳細は省きます。

ソース(Perl)

標準入力から渡されたメールをパースして、ユーザー名、フォロワーなどを取得して、フォロー返し&お礼を送信する。

今回はフォローメール以外は何もしていないが、標準入力で渡されたメールをsendmailにパイプで渡せば転送できるような気がする。(スパムフィルターには引っかかるかも。)

複数アカウントに対応していますので、user01という記述がある当たりを修正してください。

あと、スパマーをフォローしないようにタイムゾーンでチェックしていますが、これでは不十分だと思いますので、今後工夫が必要ではないかと思います。

#!/usr/bin/perl -wT

binmode(STDOUT, ":utf8");

use strict;
use warnings;
use Encode;
use Net::Twitter;
use MIME::Parser;

# Config
my %user;
$user{'user01'} = 'pass';
$user{'user02'} = 'pass';
$user{'user03'} = 'pass';

my $tmp = '/tmp';
my $msg = '@%s フォローありがとうございます!よろしくお願いいたします。';
my $twt_clientname  = 'thanksbot';
my $twt_clientver   = '0.1';
my $twt_clienturl   = 'http://www.theta.ne.jp/';
# end config

my @mail = <STDIN>;
my $parser = new MIME::Parser;
$parser->output_dir($tmp);
my $entity = $parser->parse_data(join("", @mail));
my $header = $entity->head;

# get the $uid
my $uid = $header->get("X-Twitterrecipientscreenname");
chomp $uid;

# get the mail type
my $type = $header->get('X-TwitterEmailType');
chomp $type;
if ($type ne 'is_following') {
  exit;
}

# get the sender
my $sender = $header->get('X-Twittersenderscreenname');
chomp $sender;

my $twt = Net::Twitter->new(
   username    => $uid,
   password    => $user{$uid},
   clientname  => $twt_clientname,
   clienturl   => $twt_clienturl,
   useragent   => $twt_clientname,
   source   => $twt_clientname,
   clientver   => $twt_clientver,
);

my $stat = $twt->show_user($sender);
my %st = %$stat;
if ($st{'time_zone'} eq 'Tokyo' || $st{'time_zone'} eq 'Osaka') {
   my $exts = $twt->friendship_exists($uid, $sender);
   if (!$exts) {
       my $post = sprintf($msg, $sender);
       $post = decode_utf8($post);
       if ($twt->create_friend($sender)) {
           $twt->update($post);
       }
   }
}

exit;

もう少しエラー処理とかした方がいいんでしょうけどね。ご愛嬌です。

テキストをひらがなに変換する(Perl)

以前の記事でtwitterのタイムラインを取得して音声出力するという記事を書いただが、音声出力させるまでの過程の中で、ひらがなに変換する必要があり、Yahoo日本語形態素解析を利用して変換していた。

よくかんがえたら、このYahoo日本語形態素解析は他にも使うことがあるかもしれないということで、標準入力(STDIN)からうけとったテキストをひらがなに変換するだけのPerlスクリプトを、覚え書きがわりにつくった。

#!/usr/bin/perl -wT

undef %ENV;

use strict;
use Encode;
use LWP::Simple;
use XML::DOM;

my $yahoo_id = '';
my $api_url = 'http://jlp.yahooapis.jp/MAService/V1/parse?appid=%s&sentence=%s&results=ma';

my $txt = <STDIN>;

my $url = sprintf($api_url, $yahoo_id, &enc($txt));
my $xml = get($url);
my $kana = &xml2kana($xml);
print $kana."\n";

sub enc($) {
 my $str = shift;
 $str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;
 $str =~ tr/ /+/;
 return $str;
}

sub xml2kana($) {
 my $xml = shift @_;
 my $parser = new XML::DOM::Parser;
 my $doc = $parser->parse ($xml);
 my $list = $doc->getElementsByTagName('reading');
 my @kana;
 for (my $i=0; $i<$list->getLength; $i++) {
 my $text = $list->item($i)->getFirstChild->getNodeValue;
 push @kana, $text;
 }
 return encode_utf8(join("/", @kana));
}

使い方

  1. 任意の文章が記述されたテキストファイルを用意する。ここでは、test.txtというファイル名で「日本語文を形態素に分割します」という文章が保存されている。
  2. 上記のソースを任意のファイル名で保存して実行権限をつける。今回はtext2kana.plというファイル名にした。
  3. YahooアプリケーションIDを取得して10行目に記入する。
  4. 必要な各種Perlモジュールをインストールする。
  5. 以下のようなコマンドを実行。パスは環境に合わせて変更すること。

実行例

$ cat test.txt | ./text2kana.pl
にほんご/ぶん/を/けいたいそ/に/ぶんかつ/し/ます/。/

Yahoo日本語形態素解析では、単純に分かち書きをすることも可能なので、ブログのタグクラウドを自動的に生成したりなど、いろいろと使い途があるかもしれない。

ところで

先日ご紹介した弊社サービスに関するプレスリリースが、いくつかのメディアに掲載されました。

EC2 CloudWatchをグラフ化

Amazon EC2上のサーバーにMRTGをインストールしようかどうか迷っていたら、CloudWatchというサービスがあるのに気がついてしまいました。(おそっ)

このサービスはEC2インスタンスのCPU負荷やディスクIO、ネットワーク使用量などをXMLなどのデータで返してくれるコマンドで、かなり柔軟に様々なデータを提供してくれるので、さっそくこのAPIツールで得られた結果を元にグラフを作成するパッケージを作成しました。

デモページはこちら

CloudWatch APIを使用するために、あらかじめJDKのセットアップが必要だったりして、セットアップは若干めんどくさいのですが、MRTGを構築するよりははるかに簡単だと思います。

ダウンロード

ダウンロードはこちらからどうぞ。

動作環境

ライセンス

  • 本パッケージそのものはMITライセンスとしますが、システムの動作にはAmazon社のCloudWatch API及びGoogle社のChart APIが必要です。
    従って、それらの利用規約を遵守願います。

ちなみに。。。

このパッケージ内のgchart.class.jsは、XMLデータをGoogle Chart API用のURLに変換する、自分でいうのも何ですがナイスなJavaScriptです。

単品で配布できるほどの汎用性はないのですが、それでもほとんどのGoogle Chart APIの機能はカバーできていますので、ご興味のある方は試してやってください。

寄付大歓迎

気に入っていただいた方からの、ご褒美をお待ちしています。

Flickr APIを使う

すぐに忘れてしまうので、ソースをメモ

実際のデモ

以下の画像は実際にFlickr APIを利用して、natureで検索してヒットした画像を人気順に8件表示するという処理を行っています。
JavaScriptなので、このBloggerでも動きます。

設置方法

以下は、flickr_photosという値のID属性をもつDIV要素内に写真をだーっと並べるだけのサンプルです。

Flickr APIでJSONデータを取得する

JSON Response Formatのページなどを参考にしてJSONを取得する。

以下のソースを適当に設置する

JSONを取得するためのコードより前に記述しておく必要があります。

function jsonFlickrApi( obj ){
  if( obj.stat != 'ok' ){
    return false;
  }

  document.getElementById('flickr_photos').innerHTML = '';
  document.getElementById('flickr_photos').style.textAlign = 'center';
  var p = obj.photos;

  for( var i=0; i<p.photo.length; i++ ){
    var id = p.photo[i].id;
    var owner = p.photo[i].owner;
    var secret = p.photo[i].secret;
    var server = p.photo[i].server;
    var farm = p.photo[i].farm;
    var title = p.photo[i].title;
    var ispublic = p.photo[i].ispublic;
    var isfriend = p.photo[i].isfriend;
    var isfamily = p.photo[i].isfamily;

    var url = 'http://www.flickr.com/photos/'+owner+'/'+id+'/';
    var oimg = 'http://static.flickr.com/'+server+'/'+id+'_'+secret+'.jpg';
    var simg = 'http://static.flickr.com/'+server+'/'+id+'_'+secret+'_s.jpg';

    var img = document.createElement('IMG');
    img.src = simg;

    var link = document.createElement('A');
    link.title = title;
    link.href = url;
    link.insertBefore(img, null);

    document.getElementById('flickr_photos').insertBefore(link, null);
  }
}

弊社が運営するエコ生活でも使ってます。

IEでGoogleMapのアイコンが表示されない

Googleマップを使ったアプリケーションの開発をしていて、ieでのみ地図上のカスタムアイコンがうまく表示されなかったので、若干はまってしまった。

結局、原因はiconSizeに指定した数値が、実際の画像のサイズより小さかったため。

icon.iconSize = new GSize(51, 51);

実際の画像のサイズがいつの間にか52pxになっていたので、51pxに修正したら直った。

これは予想外

住所からGoogle MAPに変換する(JavaScript編)

このサイトでは、PHPのSmartyプラグインで、住所からGoogle MAPに変換するプラグインを作成して公開しています。

あちらこちらで宣伝させていただいたら、なかなか好評で、ちょっと自己満足に浸ってたのですが、よく考えたらこのプログラムって、やってることのほとんどはJavaScriptじゃんということに気がついてしまいました。

そういうわけで、JavaScriptのみで同様の機能を提供するクラスを作成したので公開します。

ダウンロード

このクラスを使用すると、以下のようにid属性にaddrが指定された要素内のテキストを住所と見なして、id属性がgmapの要素内にGoogle Mapを挿入します。

<div id="addr">東京都千代田区永田町1-7</div>
<div id="gmap"></div>

JavaScript側の記述は、<head>〜</head>内で、「Google Maps API」、「Google Ajax Search API」、「prototype.js」と、このクラスファイルを<script src=”…”></script>して、bodyの下の方に以下の記述を入れれば完了です。

<script type="text/javascript">//<![CDATA[
var gmap = new addr2gmap();
gmap.display();
//]]></script>

PHP+Smarty版と比較すると若干めんどくさいのですが、ほとんどの環境で手軽に利用できるのがメリットです。

先に紹介した、PHP+Smarty版も同じくですが、CMSなどの会社概要のページに地図を表示させたい際に手軽にGoogle MAPが利用可能なように作成していますので、あえて低機能です。

マッシュアップなんて大それた用途ではなく軽い感じで使いたいという方にご利用いただけると嬉しい限りです。

ライセンス

MITライセンスとします。
ただし、気に入っていただけた方からの寄付は歓迎します。

住所からGoogleMapに変換するSmartyプラグイン

テンプレートタグ内に記述された住所を元にGoogle MAPを埋め込むSmartyプラグインを作成しましたので公開します。

ダウンロード

このプラグインを利用すると以下のような簡単なコードをSmartyテンプレート内に記述するだけでGoogleMapが表示されます。

{addr2gmap addr=東京都千代田区永田町1-7 height=400 width=500 zoom=18}

バグやご質問等があれば、コメントに投稿していただけば、なるべく早くご回答します。

Smartyについて勉強したい方は、以下の書籍がとてもオススメです。(Amazon)
Smarty入門~PHP5+テンプレート・エンジンでつくるMVCアプリケーション~
プラグインの自作方法も詳しく解説しています。

更新

2010/12/20
Google MAPS API V3に対応したのでAPIキーの入力が不要になりました。
また、lat、lng属性を追加しました。

ライセンス

MITライセンスとします。
ただし、気に入っていただけた方からの寄付は歓迎します。