Erlang 过滤消息包';埃贾伯德的尸体

Erlang 过滤消息包';埃贾伯德的尸体,erlang,ejabberd,Erlang,Ejabberd,我正在尝试过滤ejabberd中不需要的消息。我从邮局走了一些方向。下面是通过filter_数据包钩子执行的函数片段: check_stanza({_From, _To, #xmlel{name = StanzaType}} = Input) -> AccessRule = case StanzaType of <<"message">> -> ?DEBUG("filtering packet...~nF

我正在尝试过滤ejabberd中不需要的消息。我从邮局走了一些方向。下面是通过filter_数据包钩子执行的函数片段:

check_stanza({_From, _To, #xmlel{name = StanzaType}} = Input) ->
    AccessRule = case StanzaType of
             <<"message">> ->
           ?DEBUG("filtering packet...~nFrom: ~p~nTo: ~p~nPacket: ~p~nResult: ",
             [_From, _To, Input]),
           Input
           %check_stanza_type(AccessRule, Input)
         end.
check_节({u-From,{u-To,{xmlel{name=StanzaType}}}=Input)->
AccessRule=的大小写节类型
->
?调试(“筛选数据包…~nFrom:~p~nTo:~p~nPacket:~p~nResult:”,
[[u-From,[u-To,Input]),
输入
%检查节类型(访问规则,输入)
结束。
在日志中打印的数据包:

{{jid,<<"test25">>,<<"localhost">>,<<"Administrators-MacBook-Pro-6">>,
<<"test25">>,<<"localhost">>,<<"Administrators-MacBook-Pro-6">>},{jid,
<<"test24">>,<<"localhost">>,<<"Administrators-MacBook-Pro-6">>,
<<"test24">>,<<"localhost">>,<<"Administrators-MacBook-Pro-6">>},{xmlel,
<<"message">>,[{<<"type">>,<<"chat">>},{<<"id">>,<<"purpleaed2ec77">>},
{<<"to">>,<<"test24@localhost/Administrators-MacBook-Pro-6">>}],[{xmlel,
<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
[]},{xmlel,<<"body">>,[],[{xmlcdata,<<"MESSAGE BODY GOES HERE">>}]}]}}
{{jid,,,,
,},{jid,
,,,
,},{xmllel,
,[{,},{,},
{,}],{xmllel,
,[{,}],
[]},{xmlel,,[],[{xmlcata,}]}
我的要求:提取邮件的正文并过滤掉辱骂性的词语。例如,如果用户正在发送“MessageBody goes here”,则应发生以下顺序:

  • 模块通过钩子拦截发送方发送的数据包(完成)
  • 提取正文信息,并通过一组数据运行文字进行过滤。数据可以是Mnesia或MySQL(待定)
  • 修改后的数据包(过滤体)被发送到接收方客户端
如果“here”是一个不需要的词,则接收方将收到“messagebody goes****”

我是Erlang的新手,它是一个小社区,很少有好文章,所以需要一些关于实现上述目标的最佳方法的建议。关于如何使用elixir支持实现这一点,有很多很好的建议,但我想坚持使用Erlang。任何帮助都将不胜感激

更新

谢谢你,阿米拉米克斯。以下是替换特定单词的代码:

{xmlel,Syntax,Type,OuterBody} = Xmlel.   


case Syntax ->
    "<<message>>" ,
        XmlelBody = lists:keyfind(<<"body">>, 2, OuterBody),  %{xmlel,<<"body">>,[],[{xmlcdata,<<"HI">>}]}
        {xmlel,BodySyntax,_,Innerbody} = XmlelBody,      % [{xmlcdata,<<"HI">>}]    
        Body = proplists:get_value(xmlcdata, Innerbody),   %<<"HI">>


        TmpList = re:replace(Body,<<"HI$">>,<<"**">>),
        NewBody = binary:list_to_bin(TmpList),      %<<"**">>
        NewInnerBody = lists:keyreplace(xmlcdata, 1, Innerbody, {xmlcdata, NewBody}).   %[{xmlcdata,<<"**">>}]
        NewXmlelBody = setelement(4,XmlelBody,NewInnerBody),   %{xmlel,<<"body">>,[],[{xmlcdata,<<"**">>}]}


        NewOuterBody  = lists:keyreplace(<<"body">>, 2, OuterBody, NewXmlelBody),
        NewXmlel = setelement(4, Xmlel, NewOuterBody)
{xmlel,语法,类型,OuterBody}=xmlel。
大小写语法->
"" ,
xmlebody=list:keyfind(,2,OuterBody),%{xmlel,,[],[{xmlcata,}]}
{xmlel,BodySyntax,u,Innerbody}=xmlebody,%[{xmlcata,}]
Body=proplist:get_值(xmlcdata,Innerbody),%
TmpList=re:更换(车身,,),
NewBody=二进制:列表到二进制(TmpList),%
NewInnerBody=列表:keyreplace(xmlcdata,1,Innerbody,{xmlcdata,NewBody})。%[{xmlcata,}]
NewXmlelBody=setelement(4,XmlelBody,NewInnerBody),%{xmlel,,[],[{xmlcdata,}]}
NewOuterBody=列表:keyreplace(,2,OuterBody,newxmlebody),
NewXmlel=setelement(4,Xmlel,NewOuterBody)

由于很难在许多被阻止的单词上重复body中的每个单词,因此我想将提取的body发送给一个python脚本,该脚本可以为我执行此操作。关于如何提取消息正文的任何建议都来自于?

日志与代码不匹配,即输出中没有“过滤数据包…”,因此我无法为您提供准确的代码,以便将其放入
check_stanza
功能。而且我也不太了解要验证的
ejabberd
。然而,我想给你们一些指导,如何在Erlang中处理这样的结构,这样你们就可以更容易地自己做你们想做的事情

首先,重新格式化结构,以便清楚数据是如何嵌套的:

{
  {jid,
   <<"test25">>,
   <<"localhost">>,
   <<"Administrators-MacBook-Pro-6">>,
   <<"test25">>,
   <<"localhost">>,
   <<"Administrators-MacBook-Pro-6">>
  },
  {jid,
   <<"test24">>,
   <<"localhost">>,
   <<"Administrators-MacBook-Pro-6">>,
   <<"test24">>,
   <<"localhost">>,<<"Administrators-MacBook-Pro-6">>
  },
  {xmlel, <<"message">>,
   [
    {<<"type">>, <<"chat">>},
    {<<"id">>, <<"purpleaed2ec77">>},
    {<<"to">>, <<"test24@localhost/Administrators-MacBook-Pro-6">>}
   ],
   [
    {xmlel, <<"active">>,
     [{<<"xmlns">>, <<"http://jabber.org/protocol/chatstates">>}], []
    },
    {xmlel, <<"body">>, [],
     [{xmlcdata, <<"MESSAGE BODY GOES HERE">>}]
    }
   ]
  }
}.
外部数据是元组看起来不太正确,我希望它是一个列表,例如:

[ {jid, ...}, {jid, ...}, {xmlel, ...} ].
但可能就是这样,但请确保您正确地记录了它

要修改主体,需要执行以下步骤:

  • 提取包含正文的
    xmlcata
  • 修改主体
  • 将其存储回主结构中
  • 在继续之前,请将整个结构复制到erlangshell中,并将其作为变量存储,以便您可以在自己的shell中进行操作。不要忘记在开头添加变量名,在结尾添加

    Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
    
    Eshell V7.2.1  (abort with ^G)
    1> M =
    1> {
    1>   {jid,
    1>    <<"test25">>,
    1>    <<"localhost">>,
    1>    <<"Administrators-MacBook-Pro-6">>,
    1>    <<"test25">>,
    1>    <<"localhost">>,
    1>    <<"Administrators-MacBook-Pro-6">>
    1>   },
    1>   {jid,
    1>    <<"test24">>,
    1>    <<"localhost">>,
    1>    <<"Administrators-MacBook-Pro-6">>,
    1>    <<"test24">>,
    1>    <<"localhost">>,<<"Administrators-MacBook-Pro-6">>
    1>   },
    1>   {xmlel, <<"message">>,
    1>    [
    1>     {<<"type">>, <<"chat">>},
    1>     {<<"id">>, <<"purpleaed2ec77">>},
    1>     {<<"to">>, <<"test24@localhost/Administrators-MacBook-Pro-6">>}
    1>    ],
    1>    [
    1>     {xmlel, <<"active">>,
    1>      [{<<"xmlns">>, <<"http://jabber.org/protocol/chatstates">>}], []
    1>     },
    1>     {xmlel, <<"body">>, [],
    1>      [{xmlcdata, <<"MESSAGE BODY GOES HERE">>}]
    1>     }
    1>    ]
    1>   }
    1> }.
    {{jid,<<"test25">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test25">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {jid,<<"test24">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test24">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {xmlel,<<"message">>,
            [{<<"type">>,<<"chat">>},
             {<<"id">>,<<"purpleaed2ec77">>},
             {<<"to">>,
              <<"test24@localhost/Administrators-MacBook-Pro-6">>}],
            [{xmlel,<<"active">>,
                    [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
                    []},
             {xmlel,<<"body">>,[],
                    [{xmlcdata,<<"MESSAGE BODY GOES HERE">>}]}]}}
    2>
    
    如果数据确实是一个元组,则可以使用以下代码获取最后一个子元组:

    3> {_, _, Xmlel} = M.
    
    同样,只需在shell中键入
    Xmlel.
    即可打印出该变量的内容(
    表示不调用或不调用)。现在要提取最后一个列表,
    xmlel
    本身就是一个元组:

    4> {xmlel, _, _, L} = Xmlel.
    
    与第一个
    匹配,然后将第一个列表与第二个
    匹配。然后将第二个列表绑定到
    L

    6> L.
    [{xmlel,<<"active">>,
            [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
            []},
     {xmlel,<<"body">>,[],
            [{xmlcdata,<<"MESSAGE BODY GOES HERE">>}]}]
    
    绑定的
    BL
    是一个,只需获取主体:

    16> Body = proplists:get_value(xmlcdata, BL).
    <<"MESSAGE BODY GOES HERE">>
    
    我们将元组中的元素替换为:

    如果这确实是一条记录,那么它的定义必须位于
    ejabberd
    代码中某个可用的Erlang
    .hrl
    文件中,以便您将其包含在代码中并使用。如果该记录的定义发生了变化,您只能重新编译代码,而且它仍然可以工作。使用
    setelement
    时,如果元组的大小发生变化,则代码可能会停止工作,因此请记住这一点。我将继续使用
    setelement
    ,因为此时对我来说更简单(记录定义需要使用
    rr
    导入shell才能使用)

    现在剩下三个操作:替换主列表中的
    元组
    L
    ,然后替换
    元组中的
    L
    ,最后替换主结构中的该元组:

    21> TmpList = re:replace(Body, <<"HERE$">>, <<"*****">>).
    [<<"MESSAGE BODY GOES ">>,<<"*****">>]
    
    23> binary:list_to_bin(TmpList).
    <<"MESSAGE BODY GOES *****">>
    
    24> NewBody = binary:list_to_bin(TmpList).
    <<"MESSAGE BODY GOES *****">>
    
    35> NewL = lists:keyreplace(<<"body">>, 2, L, NewT).
    [{xmlel,<<"active">>,
            [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
            []},
     {xmlel,<<"body">>,[],
            [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]
    
    41> NewXmlel = setelement(4, Xmlel, NewL).
    {xmlel,<<"message">>,
           [{<<"type">>,<<"chat">>},
            {<<"id">>,<<"purpleaed2ec77">>},
            {<<"to">>,
             <<"test24@localhost/Administrators-MacBook-Pro-6">>}],
           [{xmlel,<<"active">>,
                   [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
                   []},
            {xmlel,<<"body">>,[],
                   [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]}
    
    42> NewM = setelement(3, M, NewXmlel).
    {{jid,<<"test25">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test25">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {jid,<<"test24">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test24">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {xmlel,<<"message">>,
            [{<<"type">>,<<"chat">>},
             {<<"id">>,<<"purpleaed2ec77">>},
             {<<"to">>,
              <<"test24@localhost/Administrators-MacBook-Pro-6">>}],
            [{xmlel,<<"active">>,
                    [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
                    []},
             {xmlel,<<"body">>,[],
                    [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]}}
    
    35>NewL=列表:键替换(,2,L,NewT)。
    [{xmllel,,
    [{,}],
    []},
    {xmlel,,[],
    [{xmlcata,}]}]
    41>NewXmlel=setelement(4,Xmlel,NewL)。
    {xmllel,,
    [{,},
    {,},
    {,
    }],
    [{xmllel,,
    [{,}],
    []},
    {xmlel,,[],
    [{xmlcata,}]}]}
    42>NewM=setelement(3,M,NewXmlel)。
    {{jid,,,
    ,,
    ,},
    {jid,,,
    ,,
    ,},
    {xmllel,,
    [{,},
    {,},
    {,
    }],
    [{xmllel,,
    [{,}],
    []},
    {xmlel,,[],
    [{xmlcata,}]}]}
    
    现在
    NewM
    包含与
    M
    相同的消息,但根据需要更换了主体

    这相当长,因为为了清晰起见,我分别对每个步骤进行了编码。实际上,当在代码中使用它时,您将能够缩短这些步骤,特别是
    8> {xmlel, _, _, BL} = T.
    
    16> Body = proplists:get_value(xmlcdata, BL).
    <<"MESSAGE BODY GOES HERE">>
    
    21> TmpList = re:replace(Body, <<"HERE$">>, <<"*****">>).
    [<<"MESSAGE BODY GOES ">>,<<"*****">>]
    
    23> binary:list_to_bin(TmpList).
    <<"MESSAGE BODY GOES *****">>
    
    24> NewBody = binary:list_to_bin(TmpList).
    <<"MESSAGE BODY GOES *****">>
    
    28> NewBL = lists:keyreplace(xmlcdata, 1, BL, {xmlcdata, NewBody}).
    [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]
    
    31> NewT = setelement(4, T, NewBL).
    {xmlel,<<"body">>,[], [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}
    
    32> NewT = T#xmlel{body = NewBody}
    
    35> NewL = lists:keyreplace(<<"body">>, 2, L, NewT).
    [{xmlel,<<"active">>,
            [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
            []},
     {xmlel,<<"body">>,[],
            [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]
    
    41> NewXmlel = setelement(4, Xmlel, NewL).
    {xmlel,<<"message">>,
           [{<<"type">>,<<"chat">>},
            {<<"id">>,<<"purpleaed2ec77">>},
            {<<"to">>,
             <<"test24@localhost/Administrators-MacBook-Pro-6">>}],
           [{xmlel,<<"active">>,
                   [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
                   []},
            {xmlel,<<"body">>,[],
                   [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]}
    
    42> NewM = setelement(3, M, NewXmlel).
    {{jid,<<"test25">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test25">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {jid,<<"test24">>,<<"localhost">>,
          <<"Administrators-MacBook-Pro-6">>,<<"test24">>,
          <<"localhost">>,<<"Administrators-MacBook-Pro-6">>},
     {xmlel,<<"message">>,
            [{<<"type">>,<<"chat">>},
             {<<"id">>,<<"purpleaed2ec77">>},
             {<<"to">>,
              <<"test24@localhost/Administrators-MacBook-Pro-6">>}],
            [{xmlel,<<"active">>,
                    [{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],
                    []},
             {xmlel,<<"body">>,[],
                    [{xmlcdata,<<"MESSAGE BODY GOES *****">>}]}]}}