Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

mod_muc_call.lua 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. local ext_events = module:require "ext_events"
  2. local jid = require "util.jid"
  3. local extract_subdomain = module:require "util".extract_subdomain;
  4. -- Options and configuration
  5. local poltergeist_component = module:get_option_string(
  6. "poltergeist_component",
  7. module.host
  8. );
  9. local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
  10. if not muc_domain_base then
  11. module:log(
  12. "warn",
  13. "No 'muc_domain_base' option set, unable to send call events."
  14. );
  15. return
  16. end
  17. -- Status strings that trigger call events.
  18. local calling_status = "calling"
  19. local busy_status = "busy"
  20. local rejected_status = "rejected"
  21. local connected_status = "connected"
  22. local expired_status = "expired"
  23. -- url_from_room_jid will determine the url for a conference
  24. -- provided a room jid. It is required that muc domain mapping
  25. -- is enabled and configured. There are two url formats that are supported.
  26. -- The following urls are examples of the supported formats.
  27. -- https://meet.jit.si/jitsi/ProductiveMeeting
  28. -- https://meet.jit.si/MoreProductiveMeeting
  29. -- The urls are derived from portions of the room jid.
  30. local function url_from_room_jid(room_jid)
  31. local node, _, _ = jid.split(room_jid)
  32. if not node then return nil end
  33. local target_subdomain, target_node = extract_subdomain(node);
  34. if not(target_node or target_subdomain) then
  35. return "https://"..muc_domain_base.."/"..node
  36. else
  37. return "https://"..muc_domain_base.."/"..target_subdomain.."/"..target_node
  38. end
  39. end
  40. -- Listening for all muc presences stanza events. If a presence stanza is from
  41. -- a poltergeist then it will be further processed to determine if a call
  42. -- event should be triggered. Call events are triggered by status strings
  43. -- the status strings supported are:
  44. -- -------------------------
  45. -- Status | Event Type
  46. -- _________________________
  47. -- "calling" | INVITE
  48. -- "busy" | CANCEL
  49. -- "rejected" | CANCEL
  50. -- "connected" | CANCEL
  51. module:hook(
  52. "muc-broadcast-presence",
  53. function (event)
  54. -- Detect if the presence is for a poltergeist or not.
  55. if not (jid.bare(event.occupant.jid) == poltergeist_component) then
  56. return
  57. end
  58. -- A presence stanza is needed in order to trigger any calls.
  59. if not event.stanza then
  60. return
  61. end
  62. local call_id = event.stanza:get_child_text("call_id")
  63. if not call_id then
  64. module:log("info", "A call id was not provided in the status.")
  65. return
  66. end
  67. local invite = function()
  68. local url = assert(url_from_room_jid(event.stanza.attr.from))
  69. ext_events.invite(event.stanza, url, call_id)
  70. end
  71. local cancel = function()
  72. local url = assert(url_from_room_jid(event.stanza.attr.from))
  73. local status = event.stanza:get_child_text("status")
  74. ext_events.cancel(event.stanza, url, string.lower(status), call_id)
  75. end
  76. -- If for any reason call_cancel is set to true then a cancel
  77. -- is sent regardless of the rest of the presence info.
  78. local should_cancel = event.stanza:get_child_text("call_cancel")
  79. if should_cancel == "true" then
  80. cancel()
  81. return
  82. end
  83. local missed = function()
  84. cancel()
  85. ext_events.missed(event.stanza, call_id)
  86. end
  87. -- All other call flow actions will require a status.
  88. if event.stanza:get_child_text("status") == nil then
  89. return
  90. end
  91. local switch = function(status)
  92. case = {
  93. [calling_status] = function() invite() end,
  94. [busy_status] = function() cancel() end,
  95. [rejected_status] = function() missed() end,
  96. [expired_status] = function() missed() end,
  97. [connected_status] = function() cancel() end
  98. }
  99. if case[status] then case[status]() end
  100. end
  101. switch(event.stanza:get_child_text("status"))
  102. end,
  103. -101
  104. );