- ææ°çã¯ãã®ã¸ãã«ãããã
ããããªã¼ãã¼ã©ã¤ããã¡ããã°ãããã ãããã§XML::Streamãããããã§ãGoogle Talkã«ã¤ãªããããã
2006-09-03追è¨
ãªã¼ãã¼ã©ã¤ãã¯localãã¹ããããref subtechã°ã«ã¼ã - otsune's SnakeOil - _ã§å§ã¾ãå é¨ã¡ã½ããããªã¼ãã¼ã©ã¤ãããã®ã¯ããããã®ã
package Plagger::Plugin::Notify::XMPP; our $VERSION = '0.04'; use strict; use warnings; use base qw( Plagger::Plugin ); use Encode; use Net::XMPP; sub register { my ($self, $context) = @_; $context->register_hook( $self, 'plugin.init' => \&initialize, 'publish.entry' => \¬ify, 'publish.finalize' => \&finalize, ); } sub initialize { my ($self, $context, $args) = @_; $context->log(debug => ">>initialize"); my $connectattempts = 3; my $connectsleep = 1; $self->{connected} = 0; $self->{client} = Net::XMPP::Client->new(debuglevel=>0); my $jid = $self->conf->{jid} || do { $context->log(error => "missing: jid"); return; }; unless (index($jid, '@') >= 1) { $context->log(error => "missing: jid"); return; } my ($username, $componentname) = split /@/, $jid; my $password = $self->conf->{password} || do { $context->log(error => "missing: password"); return; }; my $hostname = $self->conf->{server_host} || $componentname; my $port = $self->conf->{server_port} || '5222'; my $tls = $self->conf->{tls} || 0; unless ($self->conf->{to}) { $context->log(warn => "missing: to"); return; } $context->log(debug => "hostname=$hostname port=$port tls=$tls componentname=$componentname"); my ($status, $error); while (--$connectattempts >= 0) { $status = $self->{client}->Connect( hostname => $hostname, port => $port, tls => $tls, componentname => $componentname, ); last if defined $status; $context->log(warn => "retry[$connectattempts]"); sleep $connectsleep; } unless (defined $status) { $context->log(error => "connection failure"); return; } { # quick hack to connect Google Talk # override XML::Stream-1.22 no warnings 'redefine'; *XML::Stream::SASLClient = sub { my $self = shift; my $sid = shift; my $username = shift; my $password = shift; my $mechanisms = $self->GetStreamFeature($sid,"xmpp-sasl"); return unless defined($mechanisms); my $sasl = new Authen::SASL(mechanism=>join(" ",@{$mechanisms}), callback=>{ authname => $username."@".($self->{SIDS}->{$sid}->{to} or $self->{SIDS}->{$sid}->{hostname}), user => $username, pass => $password } ); $self->{SIDS}->{$sid}->{sasl}->{client} = $sasl->client_new(); $self->{SIDS}->{$sid}->{sasl}->{username} = $username; $self->{SIDS}->{$sid}->{sasl}->{password} = $password; $self->{SIDS}->{$sid}->{sasl}->{authed} = 0; $self->{SIDS}->{$sid}->{sasl}->{done} = 0; $self->SASLAuth($sid); }; } ($status,$error) = $self->{client}->AuthSend( username => $username, password => $password, resource => 'Plagger', ); unless ($status and $status eq 'ok') { $context->log(error => "authentication failure"); return; } $self->{connected} = 1; } sub notify { my ($self, $context, $args) = @_; return unless $self->{connected}; $context->log(debug => ">>notify"); my $body = $self->templatize('xmpp_notify.tt', $args); utf8::decode($body) if utf8::is_utf8($body); foreach my $a_to (@{$self->conf->{to}}) { $context->log(info => "Notifying <" . $args->{entry}->title . "> to $a_to"); $self->{client}->MessageSend( to => $a_to, body => $body, ); } } sub finalize { my ($self, $context, $args) = @_; return unless $self->{connected}; $context->log(debug => ">>finalize"); $self->{client}->Disconnect(); } 1; __END__ =head1 NAME Plagger::Plugin::Notify::XMPP - Notify feed updates to XMPP client =head1 SYNOPSIS jabber.org - module: Notify::XMPP config: jid: [email protected] password: plahplahplah to: - [email protected] - [email protected] - [email protected] Google Talk - module: Notify::XMPP config: jid: [email protected] password: plahplahplah server_host: talk.google.com tls: 1 to: - [email protected] - [email protected] - [email protected] =head1 DESCRIPTION This plugin allows you to notify feed updates to XMPP clients (jabber, Google Talk) using Net::XMPP. =head1 AUTHOR HIROSE Masaaki (hirose31) =head1 SEE ALSO L<Plagger>, L<Net::XMPP> =cut # for Emacsen # Local Variables: # mode: cperl # cperl-indent-level: 4 # cperl-indent-parens-as-block: t # indent-tabs-mode: nil # coding: euc-jp # End: # vi: set ts=4 sw=4 sts=0 :