毎日のTwitterのつぶやきをMovabletypeに自動投稿するプラグインを書いてみました。run-periodic-taskを毎日定期的に実行させる必要があります。"Twilog - Twitterのつぶやきをブログ形式で保存"(http://twilog.org/)からページを抽出、投稿するプラグインとなります。ご使用前にTwilogへのユーザー登録を推奨します。
先日 twitterの1日分のつぶやきをmixiに投稿するPerlスクリプトというエントリーを読んでこれはいいなぁーと思い。前回同様、勉強も兼ねてTwitterの1日の発言をMovabletypeに自動投稿するプラグインTwilogを書きました。
Twilog - Twitterのつぶやきをブログ形式で保存から前日のログを抽出し、投稿します。任意のカテゴリへ指定投稿でき、カテゴライズして表示させることが可能です。
run-periodic-taskを毎日定期的に実行させ、ログを抽出、自動投稿させるといったフローとなります。参照:指定日投稿や公開キュー等のスケジュール処理の設定 | Movable Type 4 ドキュメント
昨日から試験的に自動投稿させるようにしています。毎日0時5分にcronを利用して、run-periodic-taskを走らせるようにしています。
こんな感じの投稿となります。今日のTweet 2009-09-27。カテゴリはtweetで指定して投稿しています。WEBデザイン BLOG: tweetアーカイブ
使用前にTwilog - Twitterのつぶやきをブログ形式で保存にユーザー登録することを推奨します。
[追記:Tuesday, September 29, 2009]
Twilog管理者のロプロス (ropross) on Twitterから確認ご返事いただきました。夜中0時ごろの更新だと反映されていないときがあるというアドバイスをもらいましたので、更新時間を朝方に変更した方がいいかと思います。
Twitter / ロプロス: @cool_ni_ikou MTのプラグインを作って ...より引用:
@cool_ni_ikou MTのプラグインを作ってくださってありがとうございます。ただ、ログの更新はリアルタイムではないので、cronで0時5分に取得すると、前日の夜のpostはまだtwilogに反映されていないことが多いと思います。
MovalbletypeプラグインTwilog
プラグイン設定画面にてtwitterユーザーネーム、自動投稿するブログID、投稿者ID、カテゴリーID、投稿ステータス、タイトルの設定が必要となります。
ブログID,投稿者ID,カテゴリーID,投稿ステータス
ブログID、カテゴリIDはtwilog用の新規カテゴリを作成、再構築後に作成したカテゴリページを開き、アドレスからブログID、カテゴリIDを確認することができます。以下参照
投稿者IDは、システムメニューのユーザー情報から投稿者のページを開き、そちらのアドレスからIDを確認することができます。
投稿ステータスについては、自動投稿後のエントリーの公開状態となります。公開指定が[2]、未公開原稿が[1]となります。
Twilogプラグインのダウンロード
Twilog.zip後ほどリリースノートも作成して、そちらからダウンロードできるようにします。MT4Plugins::WEB DESIGN BLOG
不具合、わからないことがあれば、FriendFeedにコメントいただければ早めに対応できるかと思います。
css設定サンプル
/*
Twilog plugin : Plugin Twilog
-----------------------------------------------------------------------------------------*/
div.tl-tweet {
margin: 0px 0px 5px;
padding: 0;}
p.tl-text {
margin: 5px 0 0;
font-size: 1em;
overflow: hidden; }
p.tl-posted {
margin: 0 5px 0;
text-align: right;
font-size: 0.8em;
color: #aaa;
border-bottom: dashed 1px #ccc; }
プラグイン作成で学んだこと
今回もプラグイン作成でいくつか学べることがありましたので、書き残しておきます。
package MT::Plugin::Twilog;
use strict;
use MT;
use MT::Blog;
use MT::Entry;
use MT::Log;
use MT::I18N;
use MT::Util qw( start_end_day epoch2ts format_ts );
use MT::Placement;
use MT::WeblogPublisher;
our $VERSION = '0.0.1';
our $NAME = 'Twitlog';
use base qw( MT::Plugin );
my $plugin; $plugin = new MT::Plugin::Twilog({
id => 'Twilog',
key => 'twilog',
description => 'Twitlog.comから1日のtweet情報を抽出し、エントリとして自動で公開します。',
name => 'Twilog',
doc_link => 'http://weblibrary.s224.xrea.com/mt4plugins/twilog/',
author_name => 'cool_ni_ikou',
author_link => 'http://weblibrary.s224.xrea.com/',
blog_config_template => 'twilog_config.tmpl',
settings => new MT::PluginSettings([
['twitter_username',{ Scope => 'blog' }],
['blogid',{ Default => '1' }],
['author_id',{ Default => '1', Scope => 'blog' }],
['category_id',{ Default => '1', Scope => 'blog' }],
['status', { Default => '1', Scope => 'blog' }],
['title', { Default => 'today tweet', Scope => 'blog' }],
]),
registry => {
tasks => {
$NAME => {
name => $NAME,
frequency => 1,
code => \&_hdlr_auto_twilog_entry,
},
},
},
});
MT->add_plugin( $plugin );
sub doLog {
my ($msg) = @_;
return unless defined($msg);
use MT::Log;
my $log = MT::Log->new;
$log->message($msg) ;
$log->save or die $log->errstr;
}
sub _hdlr_auto_twilog_entry {
my $blog_id = $plugin->get_config_value('blogid');
my $username = $plugin->get_config_value('twitter_username', 'blog:'.$blog_id);
my $author_id = $plugin->get_config_value('author_id', 'blog:'.$blog_id);
my $category_id = $plugin->get_config_value('category_id', 'blog:'.$blog_id);
my $status = $plugin->get_config_value('status', 'blog:'.$blog_id);
my $title = $plugin->get_config_value('title', 'blog:'.$blog_id);
my $blog;
if ($blog_id) {
$blog = MT::Blog->load($blog_id);
} else {
$blog = MT::Blog->load( undef, { limit => 1 } );
}
my $start = start_end_day( epoch2ts( $blog, time - ( 60 * 60 * 24 * 2) ) );
$start = format_ts( '%Y%m%d', $start, $blog );
$start =~ s/\d{2}//;
my $ago = start_end_day( epoch2ts( $blog, time - ( 60 * 60 * 24 ) ) );
my $end = format_ts( '%Y%m%d', $ago, $blog );
$end =~ s/\d{2}//;
my $date = format_ts( '%Y-%m-%d', $ago, $blog );
$title .= " ".$date;
my $body = get_data($username, $start, $end);
$body .= '<p>via <a href="http://twilog.org/" title="Twilog - Twitterのつぶやきをブログ形式で保存">Twilog - Twitterのつぶやきをブログ形式で保存</a></p>';
my $entry = MT::Entry->new;
$entry->blog_id($blog_id);
$entry->author_id($author_id);
$entry->status($status);
$entry->class('entry');
$entry->allow_comments($blog->allow_comments_default);
$entry->allow_pings($blog->allow_pings_default);
$entry->title($title);
$entry->text($body);
$entry->save
or die 'Error saving entry', $entry->errstr;
my $entry_id = $entry->id;
my $place = MT::Placement->new;
$place->entry_id($entry_id);
$place->blog_id($blog_id);
$place->category_id($category_id);
$place->is_primary(1);
$place->save
or die 'Error saving placement',$place->errstr;
my $pub = MT::WeblogPublisher->new();
$pub->rebuild_entry( Entry => $entry,
BuildDependencies => 1,
NoIndexes => 1
);
$pub->rebuild_indexes( Blog => $blog );
MT->log({
message => $NAME.': EntryID-'.$entry_id.':'. $title.' published',
blog_id => $blog->id,
level => MT::Log::INFO(),
});
}
sub get_data{
my ($username, $start, $end ) = @_;
my $pattern = qq/"d$end">(.*?)<\/div><a name="$start"><\/a>/;
doLog($pattern);
my $ua = MT->new_ua({ agent => join("/", $NAME, $VERSION) });
my $url = 'http://twilog.org/' . $username;
doLog($url);
my $res = $ua->get($url);
if ($res->is_success) {
my $html = $res->content;
$html =~ s/\n//g;
if ( $html =~ /$pattern/g ){
return $1;
}
} else {
MT->log({
message => '情報を取得することができません。プラグイン設定画面にて、各種設定を確認してください。'. $res->status_line,
class => 'system',
level => MT::Log::ERROR(),
});
die '情報を取得することができません。プラグイン設定画面にて、各種設定を確認してください。'. $res->status_line;
}
}
1;
__END__
記事の新規作成・保存は以下のコードで
my $entry = MT::Entry->new;
$entry->blog_id($blog_id);
$entry->author_id($author_id);
$entry->status($status);
$entry->class('entry');
$entry->allow_comments($blog->allow_comments_default);
$entry->allow_pings($blog->allow_pings_default);
$entry->title($title);
$entry->text($body);
$entry->save
or die 'Error saving entry', $entry->errstr;
任意のカテゴリを指定する場合は、記事作成後に以下のコードで
記事を作成しているのでentry_idを紐付けることができます。
my $entry_id = $entry->id; my $place = MT::Placement->new; $place->entry_id($entry_id); $place->blog_id($blog_id); $place->category_id($category_id); $place->is_primary(1); $place->save or die 'Error saving placement',$place->errstr;
記事作成、保存、設定後に、記事の投稿、インデックステンプレートの再構築は以下のコードで
my $pub = MT::WeblogPublisher->new(); $pub->rebuild_entry( Entry => $entry, BuildDependencies => 1, NoIndexes => 1 ); $pub->rebuild_indexes( Blog => $blog );
タスク処理のフローもわかりましたので、任意のフィードを読み込み、そちらから本文を抽出、投稿するようなプラグインも作成できることがわかりました。Plaggerみたいなこともできそうですね。また何かいいアイデアを思いついたら形にしてみようかなと考えています。
[追記:Tuesday, September 29, 2009]
インデックスページ(トップページ)の記事表示について、ブログの更新頻度が少ない方は、このプラグインを使って毎日更新するとTweetの記事ばかりになってしまいます。以下のコードを使って特定カテゴリの記事を表示しない設定にしておくといいかとおもいます。実際にはrssフィードのみで記事の更新を読者に伝えるだけでいいかと。
<mt:Entries lastn="5" category="NOT tweet">
<mt:Ignore><!-- Use the Entry Summary module for each entry published on this page --></mt:Ignore>
<$mt:Include module="ブログ記事の概要"$>
</mt:Entries>
インデックステンプレートにて、mt:Entriesにlastn属性(最新5件表示)とcategory属性(特定カテゴリの記事以外を表示する)をしておくといいとおもいます。今現在このブログでもtweet(今日のつぶやき)カテゴリ以外の記事をインデックステンプレートに表示するようにしています。




コメントする