2017-09-19 81 views
1

我正在創建一個連接到Matrix服務器的bot。爲此,我使用Net::Async::MatrixPerl:發佈祝福對象

代碼:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Net::Async::Matrix; 
use Net::Async::Matrix::Utils qw (parse_formatted_message); 
use IO::Async::Loop; 
use Data::Dumper; 


my $loop = IO::Async::Loop->new; 

my $matrix = Net::Async::Matrix->new(
server => 'matrix.server.net', 
    on_error => sub { 
      my (undef, $message) = @_; 
      warn "error: $message\n"; 
    }, 
); 
$loop->add($matrix); 

$matrix->login(
    user_id => '@bot:matrix.server.net', 
    password => 'password', 
)->get; 

my $room = $matrix->join_room('#Lobby:matrix.server.net')->get; 

$room->configure(
    on_message => sub { 
      my (undef, $member, $content, $event) = @_; 
      my $msg = parse_formatted_message($content); 
      my $sendername = $member->displayname; 
print Dumper $sendername; 
      &sendmsg("$sendername said: $msg"); 
    }, 
); 

my $stream = $matrix->start; 

sub sendmsg { 
     my $input = shift; 
     if ($input) { 
       $room->send_message(
         type => "m.text", 
         body => $input, 
       ), 
     } 
} 

$loop->run; 

基本上,我想機器人呼應說了些什麼。

我獲得以下的輸出:

$ VAR1 = 'm1ndgames'; Longpoll失敗 - 遇到對象'm1ndgames 說:test',但既不allow_blessed,convert_blessed也不允許 允許allow_tags設置(或TO_JSON/FREEZE方法丟失) /usr/local/share/perl/5.24.1/Net/Async /Matrix.pm line 292.

我不明白這一點。當我在身體中輸入像test這樣的字符串時,它會被髮送到房間。

回答

2

parse_formatted_message返回一個String :: Tagged對象。這個類重載了連接,因此"$sendername said: $msg"也返回一個String :: Tagged對象。該對象被傳遞給sendmsg,該對象試圖將其序列化爲JSON,但拒絕序列化對象。

修復:更換

my $msg = parse_formatted_message($content); 

my $msg = parse_formatted_message($content)->str; 
+0

謝謝!這是原因! – m1ndgames

0

我想這是一個引用錯誤。如果你看看Net::Async::Matrix::Room

sub send_message 
{ 
    my $self = shift; 
    my %args = (@_ == 1) ? (type => "m.text", body => shift) : @_; 

    my $type = $args{msgtype} = delete $args{type} or 
     croak "Require a 'type' field"; 

    $MSG_REQUIRED_FIELDS{$type} or 
     croak "Unrecognised message type '$type'"; 

    foreach (@{ $MSG_REQUIRED_FIELDS{$type} }) { 
     $args{$_} or croak "'$type' messages require a '$_' field"; 
    } 

    if(defined(my $txn_id = $args{txn_id})) { 
     $self->_do_PUT_json("/send/m.room.message/$txn_id", \%args) 
     ->then_done() 
    } 
    else { 
     $self->_do_POST_json("/send/m.room.message", \%args) 
     ->then_done() 
    } 
} 

type您發送由該子處理,然後實際的消息獲取Net::Async::Matrix傳遞給_do_POST_json

但是您發送了一個包含:的字符串。

所以我認爲發生的事情是它的編碼是這樣的:

use JSON; 
use Data::Dumper; 

my $json = encode_json ({body => "m1ndgames: said test"}); 
print Dumper $json; 

但是,這回來是響應,在第292行:

if(length $content and $content ne q("")) { 
     eval { 
      $content = decode_json($content); 
      1; 
     } or 
      return Future->fail("Unable to parse JSON response $content"); 
     return Future->done($content, $response); 
     } 

所以我認爲是什麼發生的事情是遠程服務器向您發送了一個錯誤代碼,而且該模塊沒有正確處理它 - 它期望JSON,但它實際上並沒有得到它。

我最好的猜測是 - 試着從你的消息中刪除:,因爲我猜想有一些不良的引用發生。但是,沒有看到服務器端的代碼,我不知道。