昨日、 @yosuke_furukawa がPlaggerを知らなくて、D社の教育どうなってるんだ!って思いましたね(老害
— songmu (@songmu) December 1, 2014
忘年会,一般枠: 4000円,若手枠: 1000円,Plagger知らない枠: 10万円,とかの振り分けになりそう
— SKS rep (@repeatedly) December 1, 2014
Installation
\$ docker pull zoncoen/plagger
Plugin
plugin.init
, subscription.load
, customfeed.handle
, aggregator.finalize
, plugin.finalize
というような hook point が用意されており、各 plugin は load_plugin()
した時に呼ばれる register()
の中で各 hook に任意のサブルーチンを登録します。すると実行の際に各フェイズで hook に登録されているサブルーチンが呼ばれ、データが加工されていく仕組みになっています。
Plagger::Plugin::CustomFeed::GitHub
sub register {
my ( $self, $context ) = @\_;
$context->register_hook( $self, 'subscription.load' => $self->can('load'), );
}
sub load {
my ( $self, $context, \$args ) = @\_;
my $feed = Plagger::Feed->new;
$feed->aggregator( sub { $self->aggregate(@_) } );
$context->subscription->add($feed);
return;
}
sub load {
sub aggregate {
my ( $self, $context, \$args ) = @\_;
my $token = $self->conf->{token} or return;
my $users = $self->conf->{users} or return;
$users = [$users] unless ref $users;
my $ua = LWP::UserAgent->new;
my $header = HTTP::Headers->new(
"Authorization" => "token $token",
"Accept" => "application/atom+xml"
);
for my $user (@$users) {
my $url = "https://github.com/$user";
my $req = HTTP::Request->new( 'GET', $url, $header );
$context->log( debug => "Fetch feed from $url" );
my $res = $ua->request($req);
unless ( $res->is_success ) {
$context->log( error => "GitHub API failed: " . $res->status_line );
next;
}
my $content = HTML::Entities::decode( $res->content );
Plagger::Plugin::Aggregator::Simple->handle_feed( $url, \$content );
}
}
Plagger::Plugin::Notify::Slack
sub load {
sub register {
my ( $self, $context ) = @\_;
$context->register_hook(
$self,
'publish.entry' => $self->can('publish'),
'plugin.init' => $self->can('initialize'),
);
}
sub initialize {
my ( $self, $context, \$args ) = @\_;
$self->{remote} = $self->conf->{webhook_url} or return;
}
sub publish {
my ( $self, $context, \$args ) = @\_;
$context->log( info => "Notifying " . $args->{entry}->title . " to Slack" );
my $text = $self->templatize( 'notify.tt', $args );
Encode::_utf8_off($text) if Encode::is_utf8($text);
my $payload = +{ text => $text };
$payload->{username} = $self->conf->{username} if exists $self->conf->{username};
$payload->{icon_url} = $self->conf->{icon_url} if exists $self->conf->{icon_url};
$payload->{icon_emoji} = $self->conf->{icon_emoji} if exists $self->conf->{icon_emoji};
$payload->{channel} = $self->conf->{channel} if exists $self->conf->{channel};
my $ua = LWP::UserAgent->new;
my $res = $ua->post( $self->{remote}, [ payload => encode_json($payload) ] );
unless ( $res->is_success ) {
$context->log( error => "Notiying to Slack failed: " . $res->status_line );
}
}
Usage
plagger -c config.yaml
すると Slack に宮川さんの activity が通知されるので動いてるっぽい。
global:
assets: ./assets
log:
level: info
plugins:
- module: CustomFeed::GitHub
config:
token: {github_api_token}
users: - miyagawa
- module: Filter::Rule
rule:
- module: Deduped
- module: Notify::Slack
config:
webhook_url: {incoming_webhook_url}
module: Deduped
と設定しておくと重複は弾いてくれるようになるので、動かすたびに同じ feed が再送されなくなる感じです。
global:
assets_path: ./assets
plugin_path: - ./plugins
感想
要出典 ↩︎