How to develop custom functions on top of Ejabberd?

青春壹個敷衍的年華 提交于 2019-12-22 04:46:09

问题


I'm developing a real time chat app. After searching around for a while, I found Ejabberd and Erlang is a good option.

The question is the Ejabberd is not providing all the functions I need. I need some custom features such as location based matching and anonymous login.

So how to development custom functions on top of Ejabberd? write modules for it? or develop another standalone server app (web or other kind of server app) to interact with it?

update: another concern is the way we add custom functions/features should be scalable.


回答1:


You can write your custom modules which hook up to events in ejabberd.

Here is a list of events of ejabberd:

adhoc_local_items(Acc, From, To, Lang) -> Adhoc
adhoc_sm_items(Acc, From, To, Lang) -> Adhoc
c2s_stream_features(Acc)
c2s_unauthenticated_iq(Acc, Server, IQ) -> Packet
disco_local_features(Acc, From, To, Node, Lang) -> Adhoc
disco_local_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_local_items(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_features(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_identity(Acc, From, To, Node, Lang) -> Adhoc
disco_sm_items(Acc, From, To, Node, Lang) -> Adhoc
ejabberd_ctl_process(Args) -> CtlStatus
filter_packet({From, To, Packet}) -> {From, To, Packet}
local_send_to_resource_hook(From, To, Packet) -> ok
offline_message_hook(From, To, Packet) -> ok
privacy_check_packet(Acc, User, Server, PrivacyList, {From, To, Packet}, Dir) -> Auth
privacy_get_user_list(Acc, User, Server) -> PrivacyList
privacy_iq_get(Acc, From, To, IQ, ActiveList) -> {result, Packet} | {error, Error}
privacy_iq_set(Acc, From, To, IQ) -> {result, Packet} | {error, Error}
privacy_updated_list(Acc, OldPrivacyList, NewPrivacyList) -> PrivacyList
pubsub_publish_item(Host, Node, From, To, ItemId, Payload) -> ok
remove_user(User, Server) -> ok
resend_offline_messages_hook(Acc, User, Server) -> [Route]
resend_subscription_requests_hook(Acc, User, Server) -> [Packet]
roster_get(Acc, {User, Server}) -> [RosterItem]
roster_get_jid_info(Acc, User, Server, JID) -> {Subscription, Groups}
roster_get_subscription_lists(Acc, User, Server) -> {[FromSubscription],[ToSubscription]}
roster_in_subscription(Acc, User, Server, JID, SubscriptionType, Reason) -> bool()
roster_out_subscription(Acc, User, Server, JID, SubscriptionType, Reason) -> bool()
roster_process_item(RosterItem, Server) -> RosterItem
sm_register_connection_hook(SID, JID, Info) -> ok
sm_remove_connection_hook(SID, JID, Info) -> ok
unset_presence_hook(User, Server, Resource, Status) -> void()
user_available_hook(JID) -> ok
user_receive_packet(JID, From, To, Packet) -> ok
user_send_packet(From, To, Packet) -> ok

http://www.ejabberd.im/Events+and+hooks

Here is a tutorial on how to create a module for ejabberd: http://happy.cat/blog/XMPP-Bots-ejabberd-mod-motion-2010-02-01-10-00.html

Basically write some module and register/add your module in ejabberd.cfg config file like so (e.g. "mod_motion"):

 {modules,

 [

  %% ....

  {mod_motion,  []},

  %% ....

 ]}

An example which I developed can be found here: https://github.com/Mingism/ejabberd-stanza-ack




回答2:


Here's a good example on how to implement a presence-based module of Ejabberd.

http://metajack.im/2008/08/28/writing-ejabberd-modules-presence-storms/

Some highlights:

Hook your event

In this example, author choose to hook presence on Ejabberd

start(Host, _Opts) ->
    ejabberd_hooks:add(set_presence_hook, Host, ?MODULE, on_presence, 50),
    ok.

the format of ejabberd_hooks:add is:

ejabberd_hooks:add(Hook, Host, Module, Function, Priority)

So you just need to implement the Function (4th argument) like this:

on_presence(_User, _Server, _Resource, _Packet) ->
    none.

The full list of all hooks: https://www.process-one.net/en/wiki/ejabberd_events_and_hooks/

Parsing Options

If you would like to made your modules scalable, you will need to define some variables let you could change it easily.

You can use gen_mod:get_module_opt(Host, Module, Opt, Default) to get options in your ejabberd.cfg

For example, if you have a configuration look like this:

{mod_sunshine, [{count, 20}, {interval, 60}]}

You can get the count by:

gen_mod:get_module_opt(Server, ?MODULE, count, 10)


来源:https://stackoverflow.com/questions/22193106/how-to-develop-custom-functions-on-top-of-ejabberd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!