perl下发送jabber/xmpp消息方法参考
2014-07-28 16:51:49 阿炯

本站赞助商链接,请多关照。 perl下目前主要有两个模块用于处理xmpp/jabber消息,Net::Jabber(Net::XMPP)和AnyEvent::XMPP,后者使用了事件驱动机制,需要比较高的编程技巧,这里我们主要介绍实用的从命令行的脚本中发送消息的实例。

Net::Jabber provides a Perl user with access to the Jabber Instant Messaging protocol. Net::Jabber is a convenient tool to use for any perl script that would like to utilize the Jabber Instant Messaging protocol. While not a client in and of itself, it provides all of the necessary back-end functions to make a CGI client or command-line perl client feasible and easy to use.

需要注意的是,你需要一个支持标准的jabber服务器,多年前的gtalk也是采用的xmmp协议,对此也是兼容的,不过gtalk已经离我们远去

一般情况下,你需要一个自建的服务器及相应的域名(域名最好能自己有解析的服务器),下面的示例就假定前面的条件成立,在配置域名时可以参考:jabber服务器在dns中的srv记录设置

-------------------
示例脚本一
use strict;
use Net::Jabber;
 
my $sttime=time;
if( $#ARGV != 3 ) {
  print "\n".'Usage: ./sendmessage.pl USERNAME PASSWORD "BUDDY@gmail.com" "MESSAGE"'."\n\n";
  exit 0;
}

print "Username:$ARGV[0]\n";
my $username = "$ARGV[0]";
my $password = "$ARGV[1]";
my $to = "$ARGV[2]";
my $msg = "$ARGV[3]";
print "$to: $msg\n";
 
my $resource = "dipin";
my $hostname = 'talk.google.com';
my $port = 5222;
my $componentname = 'gmail.com';
my $Contype = 'tcpip';
my $tls = 1;

my $Con = new Net::Jabber::Client();
$Con->SetCallBacks(presence=>\&presence,message=>\&message);
 
my $status = $Con->Connect(
  hostname => $hostname, port => $port,
  componentname => $componentname,
  connectiontype => $Contype, tls => $tls);

if (!(defined($status))) {
  print "ERROR: XMPP connection failed.\n";
  print " ($!)\n";
  exit(0);
}
 
# Change hostname
my $sid = $Con->{SESSION}->{id};
$Con->{STREAM}->{SIDS}->{$sid}->{hostname} = $componentname;
 
# Authenticate
my @result = $Con->AuthSend(
  username => $username, password => $password,
  resource => $resource);
 
if ($result[0] ne "ok") {
  print "ERROR: Authorization failed: $result[0] - $result[1]\n";
}
else{
  print "Logged in Sucessfull!\n";
  $Con->PresenceSend(show=>"Available");
  print "Sending Message!\n";
  $Con->MessageSend(to=>"$to",subject=>"Test",body=>"$msg\n",priority=>10);
}

它需要通过直接传入参数即可使用,如上面的示例。

-------------------
示例脚本二

use Net::Jabber qw(Client);

my $server = "freeoa.net";
my $port = "5222";
my $username = "Sec";
my $password = "<pw>";
my $resource = "autosend";
my @recipients = @ARGV;

my $clnt = new Net::Jabber::Client;
my $status = $clnt->Connect(hostname=>$server, port=>$port);

if (!defined($status)) {
 die "Jabber connect error ($!)\n";
}

my @result = $clnt->AuthSend(username=>$username,password=>$password,resource=>$resource);

if ($result[0] ne "ok") {
 die "Jabber auth error: @result\n";
}

my $body = '';
while (<STDIN>) {
 $body .= $_;
}
chomp($body);

foreach my $to (@recipients) {
 $clnt->MessageSend(to=>$to,subject=>"",body=>$body,type=>"chat",priority=>10);
}

$clnt->Disconnect();

这个脚本需要通过管道传入消息的主体。

-------------------
示例脚本三(建议使用这个)

use v5.12;
use Encode;
use Net::Jabber qw(Client);
use Data::Dumper;

#将输入与输出的编码转为utf8
binmode(STDOUT, ":encoding(utf8)");
binmode(STDIN, ":encoding(utf8)");

#载入配置文件
###########################################################
#im程序所要发送的对象组
#----------------------------------------------------------
#Jabber parameters
my $hostname='im.freeoa.net';
my $componentname='freeoa.net';
my $port=5222;
my $contype='tcpip';
my $tls='1';
#----------------------------------------------------------
###########################################################
#发送用户登录信息
my ($username,$password)=('monitor','loveme');
#频道房间
my $resource='monitor';

#=======================
#发送IM消息
sub imsender{
 my ($user,$mesg,$subject)=@_;
 $subject=$subject.'-' if($subject);
 #将内容强转为utf8,解决中文中的乱码问题
 Encode::_utf8_off($mesg);
 $mesg=decode("utf8",$mesg);
#初始化到jabberd服务器的连接
#my $im_connect=Net::XMPP::Client->new(debuglevel=>0);
my $im_connect=Net::Jabber::Client->new();
$im_connect->SetCallBacks(presence=>\&presence,message=>\&message);

# Connect to my xmpp server
my $status=$im_connect->Connect(hostname=>$hostname,port=>$port,componentname=>$componentname,im_connecttype=>$contype,tls=>$tls);

#检查连接的结果
if(!(defined($status))){
 say "ERROR:XMPP connect failed:($!)";
 exit(2);
}

#Change hostname
my $sid=$im_connect->{SESSION}->{id};
$im_connect->{STREAM}->{SIDS}->{$sid}->{hostname}=$componentname;

 #用户认证
 my @auth_rs=$im_connect->AuthSend(username=>$username,password=>$password,resource=>$resource);

 if($auth_rs[0] ne "ok"){
  say "ERROR:Authorization failed: $auth_rs[0] - $auth_rs[1]\n";
  exit(3);
 }
 
 $im_connect->MessageSend(to=>"$user",body=>"\n$subject$mesg\n",resource=>$resource);
 $im_connect->Disconnect();
}

#调用
imsender('用户','消息','主题');

其它可用的jabber发送使用脚本

-------------------
基于Net::XMPP的Perl脚本:sendxmpp

-------------------
另外还有用shell写成的客户端:shell-xmpp-client