【问题标题】:Ejabberd - Route message to users in offline_message_hookEjabberd - 在 offline_message_hook 中将消息路由给用户
【发布时间】:2017-10-27 01:24:51
【问题描述】:

我想构建一个客户支持聊天应用。有usersadmin。在管理员下方有multiple sub-admins。最初聊天仅由管理员发起,但如果管理员离线,我需要将消息路由给子管理员。

offline_message_hook 钩子达到了目的。我将检查To 是否为管理员,然后我需要将Packet 路由到其中一位子管理员。如何将数据包路由/发送给offline_message_hook 内的其他用户。简而言之,如何更改数据包中的To,以便将数据包重定向到新的子管理员?

这是我尝试过的:-

offline_message_hook({_Action, #message{from = Peer, to = To} = Pkt} = Acc) ->
    ?INFO_MSG("Inside offline", []),
    ejabberd_router:route(From, To, Packet),
    ok.

我正在使用ejabberd 17.04.105

更新

在听从user2610053 的建议后,我这样做了:-

-spec offline_message_hook({any(), message()}) -> {any(), message()}.
offline_message_hook({_Action, Msg} = Acc) ->
    ejabberd_router:route(xmpp:set_to(Msg, 'praful@localhost')),
    {routed, Msg}.

以下是错误:-

15:13:12.291 [error] failed to route packet:
#message{id = <<"purple187f6502">>,type = chat,lang = <<"en">>,
         from = {jid,<<"praful2">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,
                     <<"praful2">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},
         to = praful@localhost,subject = [],
         body = [#text{lang = <<>>,data = <<"co=umon">>}],
         thread = undefined,
         sub_els = [{xmlel,<<"active">>,
                           [{<<"xmlns">>,
                             <<"http://jabber.org/protocol/chatstates">>}],
                           []}],
         meta = #{ip => {0,0,0,0,0,0,0,1}}}
Reason = {error,{{badrecord,jid},[{ejabberd_router,do_route,1,[{file,"src/ejabberd_router.erl"},{line,343}]},{ejabberd_router,route,1,[{file,"src/ejabberd_router.erl"},{line,87}]},{mod_sunshine,offline_message_hook,1,[{file,"src/mod_sunshine.erl"},{line,24}]},{ejabberd_hooks,safe_apply,4,[{file,"src/ejabberd_hooks.erl"},{line,380}]},{ejabberd_hooks,run_fold1,4,[{file,"src/ejabberd_hooks.erl"},{line,364}]},{ejabberd_sm,route,1,[{file,"src/ejabberd_sm.erl"},{line,138}]},{ejabberd_local,route,1,[{file,"src/ejabberd_local.erl"},{line,116}]},{ejabberd_router,do_route,1,[{file,"src/ejabberd_router.erl"},{line,348}]}]}}

用户praful@localhost 存在。请指教到底出了什么问题?

Update2 - `UserReceivePacket 挂钩

user_receive_packet 数据包钩子中,使用相同的函数ejabberd_router:route(xmpp:set_to(Packet, jid:decode("praful@localhost"))), 时会抛出一个错误:-

Hook user_receive_packet crashed when running mod_sunshine:user_receive_packet/1:
** Reason = {error,function_clause,[{jid,decode,[{file,"src/jid.erl"},{line,132}],["praful@localhost"]},{mod_sunshine,user_receive_packet,[{file,"src/mod_sunshine.erl"},{line,29}],1},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{ejabberd_c2s,process_info,[{file,"src/ejabberd_c2s.erl"},{line,231}],2},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{xmpp_stream_in,handle_info,[{file,"src/xmpp_stream_in.erl"},{line,373}],2}]}

所以,我读到了function_clause,但无法理解。这里到底出了什么问题?

【问题讨论】:

    标签: erlang ejabberd ejabberd-module ejabberd-hooks


    【解决方案1】:

    我想你是在问xmpp:set_to/2。这是一个例子:

    offline_message_hook({_Action, Msg} = Acc) ->
      SubAdmins = get_sub_admins(Msg#message.to),
      lists:foreach(
        fun(Admin) ->
          ejabberd_router:route(xmpp:set_to(Msg, Admin))
        end, Admins),
      {routed, Msg}.
    

    【讨论】:

    • 我按照你的方法做了同样的事情,但是我收到了一个错误,说failed to route packet。请查看更新后的问题并提供您的宝贵建议。
    • to 字段中应该有记录 #jid{} 并且你在那里放了一个原子。详情请阅读:github.com/processone/xmpp/blob/master/doc/API.md#jid
    • 使用了jid:decode,它就像一个魅力。非常感谢:)
    • 嘿,我在以类似方式路由消息时收到另一个错误function_clause。你能看看更新的问题吗?谢谢:)
    • 您应该使用binary() 类型作为jid:decode/1 的输入,而不是string()
    猜你喜欢
    • 2018-12-03
    • 2013-11-21
    • 2019-08-27
    • 1970-01-01
    • 2016-11-13
    • 2015-08-07
    • 2014-04-16
    • 2014-09-19
    • 2014-02-03
    相关资源
    最近更新 更多