【Lifehacks】mixiに投稿する
■タスク
ファイルに記述したメッセージをmixiに投稿する。
■背景
・残念ながらmixiでは日記等への投稿APIを公開していません。
・PerlのWWW::Mixiモジュールなど、有志によるAPIモジュールが存在しますが、mixiの通常ウェブ画面操作を元に作り上げているため、mixiの使用変更に追従できず使用不可に陥ります。
・2007.06.28、mixiは常駐型クライアントソフトウェア「mixi station」に新着通知機能等を追加しましたが、これに目をつけたユーザがサーバとの通信を解析した結果、一般的なWebAPIであるAtomPubに準拠していることが判明しました。非公開ながら安定性の高いAPIとして注目を集めました。
・2008.07.30、mixiはiPhoneから日記投稿等が可能なソフトウェア「mixi for iPhone」を発表。
上記と同様に通信を解析し、AtomPub準拠で日記投稿を行う方法が判明しました。
・このAPIを利用してごく初歩的な投稿プログラムを作成してみました。
■参考
mixiのあしあとAPI発掘
http://ido.nu/kuma/2007/06/29/mixi%E3%81%AE%E3%81%82%E3%81%97%E3%81%82%E3%81%A8api%E7%99%BA%E6%8E%98/
mixi notifyにはAtomが使われている
http://blog.fkoji.com/2007/06290200.html
たけまる / mixi station API
http://teahut.sakura.ne.jp/b/2007-07-01-1.html
mixi に写真をアップロードする
http://blog.8-p.info/articles/2007/06/29/mixi
mixi for iPhoneから発掘されたmixi日記投稿用API
http://ido.nu/kuma/2008/07/30/digging-mixi-for-iphone-application-and-new-api-for-posting-a-diary-with-a-photo/
mixiステーション2.2.1で追加されたAPIの発掘
http://ido.nu/kuma/2007/08/01/two-more-api-found-in-mixi-station-221/
■仕様
・入力ファイルの文字コードはShift_JISとします。
・入力ファイルは以下の形式としています。
- 1行目:タイトル。先頭に「【…】」を含むこと。
- 2行目:空行。
■使用方法
> perl SgPostMixi.pl < Input.txt > Result.txt
■プログラム
# # SgPostMixi.pl # mixiに投稿する。 # # Author: Orihika Ikuo # Create: 2009.06.26 # Update: 2009.XX.XX # ##### Pragma use strict; use warnings; use utf8; ##### Module use Encode; use URI; use URI::Escape; use LWP::Authen::Wsse; use LWP::UserAgent; ##### Setting our $MIXI_URI = 'mixi.jp:80'; our $USR = 'USER@DOMAIN'; our $PWD = 'XXXXXXXX'; our $MEMBER_ID = 'XXXXXXXX'; our $UA_NAME = 'SgPostMixi/1.0 '; our $KEEP_ALIVE = 4; our $DIARY_URI = "http://mixi.jp/atom/diary/member_id=$MEMBER_ID"; our $ENC_SJIS = ':encoding(shiftjis)'; our $ENC_UTF8 = ':encoding(utf8)'; ##### Constant our $ERR_ILL_FORMAT = "ERR: Illegal format."; our $ERR_ILL_TITLE = "ERR: Illegal title."; our $ERR_SEP_NOT_EXIST = "ERR: Separator is not there."; our $ERR_ILL_MSG = "ERR: Illegal message."; our $RET_SUCCESS = 'RET: Success.'; our $RET_FAILURE = 'RET: Failure.'; our $CTYPE_JPG = 'image/jpeg', our $CTYPE_ATOM = 'application/atom+xml', ##### Global binmode STDIN, $ENC_SJIS; binmode STDOUT, $ENC_UTF8; ##### Main routine &main(); sub main { my $ua; my $req; my $res; my $line; my $title; my $msg; my $content; my %param_asc; # メッセージの読み込み ($title, $msg) = SgMxReadSrcTxt(); # 投稿の準備 $ua = LWP::UserAgent->new( agent => $UA_NAME, keep_alive => $KEEP_ALIVE ); $ua->credentials($MIXI_URI, "", $USR, $PWD); $content = <<SG_MX_CONTENT; <?xml version='1.0' encoding='utf-8'?> <entry xmlns='http://www.w3.org/2007/app'> <title>$title</title> <summary>$msg</summary> </entry> SG_MX_CONTENT %param_asc = ('Content-Type' => $CTYPE_ATOM, 'content' => encode('utf8', $content) ); # 投稿の実行 $res = $ua->post($DIARY_URI, %param_asc); # 返信を標準出力に出力 if ($res->is_success) { print $RET_SUCCESS, "\n"; print $res->status_line, "\n"; print $res->content, "\n"; print "\n"; } else { print $RET_FAILURE, "\n"; print $res->status_line, "\n"; print $res->content, "\n"; print "\n"; } } sub SgMxReadSrcTxt { my @lines; my $title; my $line_2nd; my $msg; @lines = <STDIN>; if (@lines < 3) { die $ERR_ILL_FORMAT; } $title = shift(@lines); chomp($title); unless ($title =~ /^【.+】/) { die $ERR_ILL_TITLE; } $line_2nd = shift(@lines); chomp($line_2nd); if ($line_2nd ne "") { die $ERR_SEP_NOT_EXIST; } $msg = join('', @lines); if ($msg eq "") { die $ERR_ILL_MSG; } return $title, $msg; }