Erlang 过滤消息包';埃贾伯德的尸体
我正在尝试过滤ejabberd中不需要的消息。我从邮局走了一些方向。下面是通过filter_数据包钩子执行的函数片段:Erlang 过滤消息包';埃贾伯德的尸体,erlang,ejabberd,Erlang,Ejabberd,我正在尝试过滤ejabberd中不需要的消息。我从邮局走了一些方向。下面是通过filter_数据包钩子执行的函数片段: check_stanza({_From, _To, #xmlel{name = StanzaType}} = Input) -> AccessRule = case StanzaType of <<"message">> -> ?DEBUG("filtering packet...~nF
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(待定)
- 修改后的数据包(过滤体)被发送到接收方客户端
{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
。
:
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 *****">>}]}]}}