Update user presence using API

Hi,

I'm trying to update the user presence based on the status of the IP phone of the user.
The idea is:
- When the SIP Server receive a call to the IP phone it will update the XMPP user presence.
- When the call hangup, it will update again the XMPP user presence.

I tried using ejabberdctl with the command, but didn't worked:
ejabberdctl set_presence nivaldo unity.local 4713450754257555570104 available away Saiu 0

I enabled the REST API and tried using this shell script, but didn't worked:

#!/bin/sh
curl -X POST -H "Cache-Control: no-cache" -d '{
    "user": "nivaldo",
    "host": "unity.local",
    "resource": "4713450754257555570104",
    "type": "available",
    "show": "away",
    "status": "Saiu",
    "priority": "0"
  }' "http://127.0.0.1:5280/api/set_presence"

How can i update the user presence using an external component?

I execute a command similar

I execute a command similar to yours, indicating an existing XMPP session (a user is already connected there):

$ ejabberdctl set_presence user1 localhost tka1 available away Saiu 0
$

Then the connected client receives:

<presence to='user1@localhost/tka1'
	from='user1@localhost/tka1'>
  <priority>0</priority>
  <show>away</show>
  <status xml:lang='en'>Saiu</status>
</presence>

If I configure loglevel to 5, then I see in the logs:

19:00:58.716 [debug] Command 'set_presence' execution allowed by rule 'console commands' (CallerInfo=#{caller_module => ejabberd_ctl})
19:00:58.716 [debug] Executing command mod_admin_extra:set_presence with Args=["user1",...
19:00:58.718 [debug] Won't add stanza for user1@localhost/tka1 to CSI queue
19:00:58.718 [debug] Flushing packets of user1@localhost from CSI queue of user1@localhost/tka1
19:00:58.718 [debug] (tcp|<0.544.0>) Send XML on stream = "<presence to='user1@localhost/tka1' from='user1@localhost/tka1'>...
19:00:58.742 [debug] user1@localhost/tka1 acknowledged 16 of 16 stanzas

Hi, Did your clients received

Hi,

Did your clients received the presence and updated the user presence?
I have this at the logs too, but the presence is not updated on the user clients, neither at the server side.

[root@unity bin]# ./ejabberdctl get_presence junior unity.local
junior@unity.local/MacBook-Pro-de-Nivaldo available
[root@unity bin]# ./ejabberdctl set_presence junior unity.local MacBook-Pro-de-Nivaldo available away Saiu 0
[root@unity bin]# ./ejabberdctl get_presence junior unity.local
junior@unity.local/MacBook-Pro-de-Nivaldo available

At the log i receive the same messages, the only diference is the last line 19:00:58.742 [debug] user1@localhost/tka1 acknowledged 16 of 16 stanzas:

2017-06-24 11:42:20.853 [debug] <0.307.0>@ejabberd_access_permissions:handle_call:139 Command 'set_presence' execution allowed by rule 'API used from localhost allows all calls' (CallerInfo=#{caller_module => ejabberd_ctl})
2017-06-24 11:42:20.853 [debug] <0.686.0>@ejabberd_commands:do_execute_command:633 Executing command mod_admin_extra:set_presence with Args=[<<"junior">>,<<"unity.local">>,<<"MacBook-Pro-de-Nivaldo">>,<<"available">>,<<"away">>,<<"Saiu">>,<<"0">>]
2017-06-24 11:42:20.853 [debug] <0.646.0>@mod_client_state:filter_other:291 Won't add stanza for junior@unity.local/MacBook-Pro-de-Nivaldo to CSI queue
2017-06-24 11:42:20.853 [debug] <0.646.0>@mod_client_state:dequeue_sender:330 Flushing packets of junior@unity.local from CSI queue of junior@unity.local/MacBook-Pro-de-Nivaldo
2017-06-24 11:42:20.853 [debug] <0.646.0>@ejabberd_socket:send:216 (tls|<0.645.0>) Send XML on stream = <<"0awaySaiu">>

Do i need to change any configuration at the server side?

Thanks!

Ah, you are right, that

Ah, you are right, that doesn't work correctly in recent ejabberd. I've written and tested this patch. Can you test it?

From 0a279e834968666906e04a5d225aed826d6282ca Mon Sep 17 00:00:00 2001
From: Badlop 
Date: Wed, 5 Jul 2017 18:27:02 +0200
Subject: [PATCH] Fix set_presence command to work in recent ejabberd

---
 src/ejabberd_c2s.erl    |  9 ++++++++-
 src/mod_admin_extra.erl | 24 ++++++++++--------------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 7cbc16f..9738b40 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -46,7 +46,7 @@
 	 reject_unauthenticated_packet/2, process_closed/2,
 	 process_terminated/2, process_info/2]).
 %% API
--export([get_presence/1, resend_presence/1, resend_presence/2,
+-export([set_presence/2, get_presence/1, resend_presence/1, resend_presence/2,
 	 open_session/1, call/3, send/2, close/1, close/2, stop/1,
 	 reply/2, copy_state/2, set_timeout/2, route/2,
 	 host_up/1, host_down/1]).
@@ -93,6 +93,10 @@ call(Ref, Msg, Timeout) ->
 reply(Ref, Reply) ->
     xmpp_stream_in:reply(Ref, Reply).
 
+-spec set_presence(pid(), any()) -> presence().
+set_presence(Ref, Pres) ->
+    call(Ref, {set_presence, Pres}, 1000).
+
 -spec get_presence(pid()) -> presence().
 get_presence(Ref) ->
     call(Ref, get_presence, 1000).
@@ -516,6 +520,9 @@ init([State, Opts]) ->
 		    shaper => Shaper},
     ejabberd_hooks:run_fold(c2s_init, {ok, State1}, [Opts]).
 
+handle_call({set_presence, Pres}, From, State) ->
+    reply(From, ok),
+    process_self_presence(State, Pres);
 handle_call(get_presence, From, #{jid := JID} = State) ->
     Pres = case maps:get(pres_last, State, error) of
 	       error ->
diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl
index e5d2892..f2cb692 100644
--- a/src/mod_admin_extra.erl
+++ b/src/mod_admin_extra.erl
@@ -1002,20 +1002,16 @@ set_presence(User, Host, Resource, Type, Show, Status, Priority0) ->
     Priority = if is_integer(Priority0) -> Priority0;
 		  true -> binary_to_integer(Priority0)
 	       end,
-    case ejabberd_sm:get_session_pid(User, Host, Resource) of
-	none ->
-	    error;
-	Pid ->
-	    From = jid:make(User, Host, Resource),
-	    To = jid:make(User, Host),
-	    Presence = #presence{from = From, to = To,
-				 type = misc:binary_to_atom(Type),
-				 show = misc:binary_to_atom(Show),
-				 status = xmpp:mk_text(Status),
-				 priority = Priority},
-	    Pid ! {route, Presence},
-	    ok
-    end.
+    Pres = #presence{
+        from = jid:make(User, Host, Resource),
+        to = jid:make(User, Host),
+        type = misc:binary_to_atom(Type),
+        status = xmpp:mk_text(Status),
+        show = misc:binary_to_atom(Show),
+        priority = Priority,
+        sub_els = []},
+    Ref = ejabberd_sm:get_session_pid(User, Host, Resource),
+    ejabberd_c2s:set_presence(Ref, Pres).
 
 user_sessions_info(User, Host) ->
     CurrentSec = calendar:datetime_to_gregorian_seconds({date(), time()}),
-- 
2.7.4

Hi, I applied the patch at

Hi,

I applied the patch at version 17.06. It worked!

Thanks! :)

Ok, I've comitted the patch

Syndicate content