1

我正在创建一个连接到Matrix服务器的机器人。为此,我使用Net::Async::Matrix

编码:

#!/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 说:测试”,但在 /usr/local/share/perl/5.24.1/Net/Async/Matrix 中未启用 allow_blessed、convert_blessed 和 allow_tags 设置(或缺少 TO_JSON/FREEZE 方法)。下午第 292 行。

我不明白。当我test在 body 中输入一个字符串时,它会被发送到房间。

4

2 回答 2

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;
于 2017-09-19T17:57:32.207 回答
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信息由这个 sub 处理,然后实际的消息被传递给_do_POST_jsonin Net::Async::Matrix

但是您发送了一个包含:.

所以我认为正在发生的事情是它的编码是这样的:

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但它实际上并没有得到它。

我最好的猜测是-尝试删除:您的消息,因为我猜可能会发生一些不好的引用。但是如果没有看到服务器端的代码,我不能说清楚。

于 2017-09-19T14:43:03.167 回答