123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- local ext_events = module:require "ext_events"
- local jid = require "util.jid"
- local extract_subdomain = module:require "util".extract_subdomain;
-
- -- Options and configuration
- local poltergeist_component = module:get_option_string(
- "poltergeist_component",
- module.host
- );
- local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
- if not muc_domain_base then
- module:log(
- "warn",
- "No 'muc_domain_base' option set, unable to send call events."
- );
- return
- end
-
- -- Status strings that trigger call events.
- local calling_status = "calling"
- local busy_status = "busy"
- local rejected_status = "rejected"
- local connected_status = "connected"
- local expired_status = "expired"
-
- -- url_from_room_jid will determine the url for a conference
- -- provided a room jid. It is required that muc domain mapping
- -- is enabled and configured. There are two url formats that are supported.
- -- The following urls are examples of the supported formats.
- -- https://meet.jit.si/jitsi/ProductiveMeeting
- -- https://meet.jit.si/MoreProductiveMeeting
- -- The urls are derived from portions of the room jid.
- local function url_from_room_jid(room_jid)
- local node, _, _ = jid.split(room_jid)
- if not node then return nil end
-
- local target_subdomain, target_node = extract_subdomain(node);
-
- if not(target_node or target_subdomain) then
- return "https://"..muc_domain_base.."/"..node
- else
- return "https://"..muc_domain_base.."/"..target_subdomain.."/"..target_node
- end
- end
-
- -- Listening for all muc presences stanza events. If a presence stanza is from
- -- a poltergeist then it will be further processed to determine if a call
- -- event should be triggered. Call events are triggered by status strings
- -- the status strings supported are:
- -- -------------------------
- -- Status | Event Type
- -- _________________________
- -- "calling" | INVITE
- -- "busy" | CANCEL
- -- "rejected" | CANCEL
- -- "connected" | CANCEL
- module:hook(
- "muc-broadcast-presence",
- function (event)
- -- Detect if the presence is for a poltergeist or not.
- if not (jid.bare(event.occupant.jid) == poltergeist_component) then
- return
- end
-
- -- A presence stanza is needed in order to trigger any calls.
- if not event.stanza then
- return
- end
-
- local call_id = event.stanza:get_child_text("call_id")
- if not call_id then
- module:log("info", "A call id was not provided in the status.")
- return
- end
-
- local invite = function()
- local url = assert(url_from_room_jid(event.stanza.attr.from))
- ext_events.invite(event.stanza, url, call_id)
- end
-
- local cancel = function()
- local url = assert(url_from_room_jid(event.stanza.attr.from))
- local status = event.stanza:get_child_text("status")
- ext_events.cancel(event.stanza, url, string.lower(status), call_id)
- end
-
- -- If for any reason call_cancel is set to true then a cancel
- -- is sent regardless of the rest of the presence info.
- local should_cancel = event.stanza:get_child_text("call_cancel")
- if should_cancel == "true" then
- cancel()
- return
- end
-
- local missed = function()
- cancel()
- ext_events.missed(event.stanza, call_id)
- end
-
- -- All other call flow actions will require a status.
- if event.stanza:get_child_text("status") == nil then
- return
- end
-
- local switch = function(status)
- case = {
- [calling_status] = function() invite() end,
- [busy_status] = function() cancel() end,
- [rejected_status] = function() missed() end,
- [expired_status] = function() missed() end,
- [connected_status] = function() cancel() end
- }
- if case[status] then case[status]() end
- end
-
- switch(event.stanza:get_child_text("status"))
- end,
- -101
- );
|