Commit 314a4647 authored by Johannes Barthel's avatar Johannes Barthel
Browse files

intial

parents
# senfsip-moderated-mute
this tool fixes two issues where meeting permissions don't work for (or rather, against) telephone users in bbb conferences
* phone users can unmute themselves, even when moderators restrict the microphone permission
* phone users are not muted when the microphone permission is disabled
you need to make one change in the dialplan for this to work. in the file `/opt/freeswitch/etc/freeswitch/autoload_configs/conference.conf.xml`, change the line
```xml
<control action="mute" digits="0"/>
```
to
```xml
<!--<control action="mute" digits="0"/>-->
```
then, run `events.sh`. we should probably make a systemd service for this. for now, just leave it running in a tmux.
#!/usr/bin/env python3
import greenswitch
from xml.dom.minidom import parse
import pymongo
import json
import logging
logging.basicConfig(level=logging.DEBUG)
# find out password for esl socket
dom = parse("/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml")
password = None
for param in dom.getElementsByTagName("param"):
if param.attributes.get("name").nodeValue == "password":
password = param.attributes.get("value").nodeValue
if password is None:
raise ValueError("no password found in config")
# connect to mongo
mongo = pymongo.MongoClient("127.0.1.1")
db = mongo.meteor
# connect to freeswitch
fs = greenswitch.InboundESL(host='127.0.0.1', port=8021, password=password)
fs.connect()
def get_fs_member_id(caller_num, conference_id):
fs_conference = json.loads(fs.send("api conference {} json_list".format(conference_id)).data)[0]
fs_member_id = [m["id"] for m in fs_conference["members"] if m["caller_id_number"] == caller_num][0]
return fs_member_id
# wait until participant's right to use the mic gets restricted
for change in db.meetings.watch([{ "$match" : {"operationType" : "update" }}]):
print("meeting is now disableMic?")
mics_disabled = change['updateDescription']['updatedFields']['lockSettingsProps']['disableMic']
if not mics_disabled:
print("no")
continue
print("yes")
meeting_mongo_id = change['documentKey']['_id']
meeting = db.meetings.find_one({"_id": meeting_mongo_id})
#print("meeting",meeting)
conference_id = meeting["voiceProp"]["voiceConf"]
for user in db.voiceUsers.find({"joined":True, "meetingId": meeting["meetingId"]}):
#print("user")
#print(user)
if user["callerNum"].startswith("w_"):
#print("is a web user")
continue # this is a web user, phone users have their number as callerNum
fs_member_id = get_fs_member_id(user["callerNum"], conference_id)
print("muting phone user {} in meeting \"{}\" due to meeting-wide mic permission restriction by moderator".format(user["callerNum"], meeting["meetingProp"]["name"]))
#print(fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
#!/usr/bin/env python3
import greenswitch
from xml.dom.minidom import parse
import pymongo
import json
import logging
logging.basicConfig(level=logging.DEBUG)
# find out password for esl socket
dom = parse("/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml")
password = None
for param in dom.getElementsByTagName("param"):
if param.attributes.get("name").nodeValue == "password":
password = param.attributes.get("value").nodeValue
if password is None:
raise ValueError("no password found in config")
# connect to mongo
mongo = pymongo.MongoClient("127.0.1.1")
db = mongo.meteor
# connect to freeswitch
fs = greenswitch.InboundESL(host='127.0.0.1', port=8021, password=password)
fs.connect()
def get_fs_member_id(caller_num, conference_id):
fs_conference = json.loads(fs.send("api conference {} json_list".format(conference_id)).data)[0]
fs_member_id = [m["id"] for m in fs_conference["members"] if m["caller_id_number"] == caller_num][0]
return fs_member_id
def show_event(evt):
#print(evt.headers)
digit = int(evt.headers["DTMF-Digit"])
if digit != 0:
return
caller_num = evt.headers["Caller-Username"]
# SECURITY: this assumes there is only one voiceUser per call. What happens
# if there are multiple concurrent calls from the same number in
# different meetings?
voice_user = db.voiceUsers.find_one({"callerNum":caller_num, "joined": True})
if voice_user is None:
return
meeting_id = voice_user["meetingId"]
meeting = db.meetings.find_one({"meetingId": meeting_id})
locked = meeting["lockSettingsProps"]["disableMic"]
conference_id = meeting["voiceProp"]["voiceConf"]
fs_member_id = get_fs_member_id(caller_num, conference_id)
print("caller {} pressed {}, they are in a {} meeting.".format(caller_num, digit, "locked" if locked else "unlocked"))
try:
if not locked:
print(fs.send("api conference {} tmute {}".format(conference_id, fs_member_id)).data)
else:
print(fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
except KeyError as e:
print("Error when sending (t)mute:")
print(e)
# register handler
print(fs.send('EVENTS PLAIN DTMF').data)
# fs.register_handle("DTMF", lambda event: print(event.__dict__))
fs.register_handle("DTMF", show_event)
fs.process_events()
#!/bin/bash
cd "$(dirname "$0")"
trap 'kill %1' SIGINT
./events-observe-lockmic.py & ./events-observe-zerokey.py
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment