理系学生日記

おまえはいつまで学生気分なのか

Gmail の フォロー返しスクリプト修正

先日のエントリでコメントを頂いて,Twitter からのメールのヘッダに様々な情報があることを知りました.

なんでみなさん知ってるんだろう,どこにドキュメント化されてんのかと思ったら,ここに書いてあった.

How should my bot follow users that follow it or inspect direct messages?

By default, Twitter sends an email the first time a user follows you or sends you a direct message. For your bot-building pleasure, we've added the following headers to those emails:

* X-TwitterEmailType - will be 'is_following' or 'direct_message'
* X-TwitterCreatedAt - ex: Thu Aug 07 15:17:15 -0700 2008
* X-TwitterSenderScreenName - ex: 'bob'
* X-TwitterSenderName - ex: 'Bob Smith'
* X-TwitterSenderID - ex: 12345
* X-TwitterRecipientScreenName - ex: 'john'
* X-TwitterRecipientName - ex: 'John Doe'
* X-TwitterRecipientID - ex: 67890
* X-TwitterDirectMessageID - ex: 2346346

http://apiwiki.twitter.com/FAQ#Howshouldmybotfollowusersthatfollowitorinspectdirectmessages

というわけで,この情報を使って書き換えてみました.
なお,MIME::Head は MIME::Parser 経由で作る方が行儀が良いと思います.

use strict;
use warnings;
use Net::IMAP::Simple::SSL;
use Net::Twitter;
use MIME::Head;
use Jcode;
use Getopt::Long;

GetOptions( verbose => \my $verbose );

my $imaps = Net::IMAP::Simple::SSL->new( 'imap.gmail.com' )
    or die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";

$imaps->login( 'your gmail account', 'your gmail password' )
    or die "Authentication failed";
my $num = $imaps->select( 'INBOX' );

my (@followers, $msgno);
for $msgno ( 1 .. $num ) {
    my $head = MIME::Head->new( $imaps->get( $msgno ) ) or do {
        warn "MIME::Head creation failed: [$msgno]\n";
        next;
    };

    printf "[%3d]: %s", $msgno, Jcode->new( $head->get( 'Subject' ), 'MIME-Header' )->utf8
        if $verbose;

    my $mailtype = $head->get('X-TwitterEmailType');
    if ($mailtype and $mailtype =~ /^is_following/) {
        my $name = $head->get('X-TwitterSenderScreenName'); chomp( $name );
        push @followers, $name;

        $imaps->copy($msgno, 'INBOX/read');
        $imaps->delete($msgno);
    }

}

print "\nnow following: ", join "\n" => @followers
    if $verbose;

my $twit = Net::Twitter->new(
    username => 'your twitter account',
    password => 'your twitter password',
);
$twit->create_friend($_) for @followers;