ejabberd 自定义模块发送回确认

问题描述 投票:0回答:1

您好,我正在尝试创建一个自定义 ejabberd 模块,一旦消息到达服务器,该模块就会向消息发送者发回确认信息。基本上与 Whatsapp 具有相同的功能,带有一个复选标记。 在我的客户端,我将 smack 与 Java 结合使用。我有一个自定义节扩展,需要节侦听器中的某种格式。

-module(mod_acknowledgment).

-behaviour(gen_mod).

%% Exported functions
-export([start/2, stop/1, on_user_send_packet/4, depends/2, mod_doc/0, mod_options/1]).

%% Records
-record(xmlel, {name, attrs = [], children = []}).
-record(jid, {user = <<"">>, server = <<"">>, resource = <<>>}).

-define(NS_ARRIVED, <<"urn:xmpp:ack">>).

%% Start module and register hooks
start(Host, _Opts) ->
    ejabberd_hooks:add(user_send_packet, Host, ?MODULE, on_user_send_packet, 10),
    ok.

%% Stop module and unregister hooks
stop(Host) ->
    ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, on_user_send_packet, 10),
    ok.

%% Dependencies function
depends(_Host, _Opts) ->
    [].

%% Documentation function
mod_doc() ->
    "This module sends an acknowledgment when a message arrives at the server.".

%% Options function
mod_options(_Host) ->
    [].

%% Packet filtering and acknowledgment sending
on_user_send_packet(Packet, _C2SState, From, To) ->
    case should_acknowledge(Packet) of
        true ->
            send_acknowledgment(From, To, Packet);
        false ->
            ok
    end,
    Packet.

%% Determine if a packet should trigger an acknowledgment
should_acknowledge(#xmlel{name = <<"message">>, attrs = Attrs, children = Children}) ->
    case lists:keyfind(<<"type">>, 1, Attrs) of
        {_, <<"chat">>} ->
            %% Check if the message has a body
            lists:any(fun(C) -> C#xmlel.name =:= <<"body">> end, Children);
        _ ->
            false
    end;
should_acknowledge(_) ->
    false.

%% Send acknowledgment back to the sender
send_acknowledgment(FromJID, ToJID, Packet) ->
    %% Extract the message ID to include in the acknowledgment
    ReceiptId = xml:get_tag_attr_s(<<"id">>, Packet),
    AckPacket = #xmlel{
        name = <<"message">>,
        attrs = [
            {<<"to">>, jid_to_binary(FromJID)},
            {<<"from">>, jid_to_binary(ToJID)},
            {<<"type">>, <<"chat">>}
        ],
        children = [
            #xmlel{name = <<"arrived">>, attrs = [{<<"xmlns">>, ?NS_ARRIVED}, {<<"id">>, ReceiptId}], children = []}
        ]
    },
    ejabberd_router:route(ToJID, FromJID, AckPacket),
    ok.

%% JID to binary conversion
jid_to_binary(#jid{user = User, server = Server, resource = Resource}) when Resource =:= <<>> ->
    <<User/binary, "@", Server/binary>>;
jid_to_binary(#jid{user = User, server = Server, resource = Resource}) ->
    <<User/binary, "@", Server/binary, "/", Resource/binary>>.

在我的客户端,我有一个自定义节扩展,如下所示:

package net.chatchap.extensions;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.XmlStringBuilder;

/**
 * A custom stanza extension to notify user than a message has arrived at the server
 */

public class ArrivedExtension implements ExtensionElement {
    public static final String ELEMENT = "arrived";
    public static final String NAMESPACE = "urn:xmpp:ack";

    @Override
    public String getNamespace() {
        return NAMESPACE;
    }
    @Override
    public String getElementName() {
        return ELEMENT;
    }
    @Override
    public CharSequence toXML(XmlEnvironment xmlEnvironment) {
        return new XmlStringBuilder(this).closeEmptyElement();
    }

    @Override
    public CharSequence toXML() {
        return toXML(XmlEnvironment.EMPTY);
    }
}

因此自定义模块应该使用钩子来捕获消息,然后将确认返回给服务器 不幸的是,该模块无法工作。 Erlang 不是我的语言,所以我很难接受这个

java erlang xmpp ejabberd ejabberd-module
1个回答
0
投票

代码中存在严重的不连贯性,即使是第一天的开发人员也不会执行,但令人惊讶的是,编码风格是完美的。显然该代码将无法工作。看来你使用了一些 AI 程序来编写 Erlang 代码,对吗?

有一些 XEP(XMPP 协议扩展)描述了此类功能如何工作:

不幸的是,这些都没有在 ejabberd 中实现。

与 Whatsapp 的功能基本相同,只是带有一个复选标记。

您计划免费完成此任务,对吧?

© www.soinside.com 2019 - 2024. All rights reserved.