Отправка сообщений в Jabber через web

Date April 17th, 2012 Author Vitaly Agapov

— Мне сказали — умный человек.
— Ну мало ли что про человека болтают!

— «Тот самый Мюнхгаузен»


Эта краткая заметка посвящена отправке сообщений по протоколу XMPP с помощью Perl. В данном случае это будет не простой Perl-скрипт, а cgi-сценарий под веб-сервером, хотя суть и не меняется. Фактически и не заметка это будет, а просто набор рабочего кода, который может пригодиться в будущем. Если пригодится кому-то кроме меня самого, то вообще прекрасно.

HTML

Допустим, у нас есть в вёрстке страницы такой набор элементов:

<input type="text" id="jabberTo">
<textarea id="jabberText"></textarea>
<input type="submit" value="Send" onclick="sendJabber(this)">

JavaScript

В js у нас задана соответствующая функция (jQuery подключён, куда ж без него):

function sendjabber(el) {
        var text=$('#jabberText').val();
        var to=$('#jabberTo').val();
        $.ajax({
                type: 'POST',
                url: "/cgi-bin/sendjabber",
                data: { jabbertText: text, jabberTo: to },
                cache: false,
                beforeSend: function(){
                        $('.tmpdiv').remove();
                        $(el).after('<img class="tmpimg" src="ajax.gif">');
                },
                success: function(html) {
                        $('.tmpimg').remove();
                        $(el).after('<div class="tmpdiv">'+html+'</div>');
                }
        });
}

Тут заодно вставим рядом с кнопкой ajax-анимацию, а после получения ответа заменим её на то, что вернёт нам скрипт.

Perl

В /cgi-bin/sendjabber у нас находится Perl-скрипт:

#!/usr/bin/perl
use CGI;
use Net::XMPP;
use Encode;
my $cgi = new CGI;
foreach my $name ($cgi->param())
{
        my @values = $cgi->param($name);
        foreach my $value(@values){
                $input{$name} = $value;
        }
}
if ($input{jabberText}) {
        my $text=$input{jabberText};
        my $to=$input{jabberTo};
        print qq~
        ~;
        my $server="ourserver.addr";
        my $port=5223;
        my $user="username";
        my $password="password";
        my $resource="resource";
        my $connectiontype="tcpip";
        my $ssl=1;
        my $tls=0;
        my $debugLevel = 0;
        my $bot = new Net::XMPP::Client(debuglevel => $debugLevel);
        my $status = $bot->Connect(
                hostname        => $server,
                port            => $port,
                connectiontype  => $connectiontype,
                ssl             => $ssl,
                tls             => $tls);
        if (!(defined($status))) {
                print "ERROR:  XMPP connection failed.\n";
                print "($!)\n";
                exit(0);
        }
        my @result = $bot->AuthSend(
                username => $user, password => $password,
                resource => $resource);
        print $result[0];
        if ($result[0] ne "ok") {
                print "ERROR: Authorization failed: $result[0] - $result[1]\n";
                exit(0);
        }
        $text = decode('utf-8', $text);
        $bot->MessageSend(
                to       => $to,
                resource => $resource,
                subject  => "Subj",
                type     => "chat",
                body     => $text);
        exit(0);
}

В том случае, если аутентификация на Jabber-сервере проходит через SSL, как у меня, то она может не проходить, а скрипт может вываливать ошибку. Можно решить проблему лёгким костылём: надо закомментировать строки в /usr/lib/perl5/vendor_perl/5.8.8/Net/XMPP/Protocol.pm:

if($self->{STREAM}->GetStreamFeature($self->GetStreamID(),”xmpp-sasl”))
{
return $self->AuthSASL(%args);
}

Плюс потребуется модуль IO::Socket::SSL.

Ссылки
Net::XMPP на CPAN

Tags: , ,
Category: Perl, Web-dev | No comments »

Comments

Leave a comment

 Comment Form