您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

mod_muc_call.lua 3.1KB

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