This document is for an older version of Kazoo (version 4.3) that is no longer supported. You should upgrade and read the current documentation.
Configuring Conferences
About Conferences
Conference documents are enriched with real-time information along side their configuration, namely showing the number of members, number of moderators, duration of the conference, conference locked status.
The real-time information (if available) is added to conference document under _read_only
key (to avoid accident document update).
Schema
Schema for conferences
Key | Description | Type | Default | Required | Support Level |
---|---|---|---|---|---|
bridge_password | the password used for a conference bridge | string() | false | ||
bridge_username | the username used for a conference bridge | string() | false | ||
caller_controls | caller controls (config settings) | string() | false | ||
conference_numbers.[] | string() | false | |||
conference_numbers | Defines conference numbers that can be used by members or moderators | array(string()) | [] | false | |
controls | controls | object() | false | ||
domain | domain | string() | false | ||
flags.[] | string() | false | supported | ||
flags | Flags set by external applications | array(string()) | false | supported | |
focus | This is a read-only property indicating the media server hosting the conference | string() | false | ||
language | Prompt language to play in the conference | string() | false | ||
max_members_media | Media to play when the conference is full | string() | false | ||
max_participants | The maximum number of participants that can join | integer() | false | ||
member.join_deaf | Determines if a member will join deaf | boolean() | false | false | supported |
member.join_muted | Determines if a member will join muted | boolean() | true | false | supported |
member.numbers.[] | string() | false | |||
member.numbers | Defines the conference (call in) number(s) for members | array(string()) | [] | false | |
member.pins.[] | string() | false | |||
member.pins | Defines the pin number(s) for members | array(string()) | [] | false | |
member.play_entry_prompt | Whether to play the entry prompt on member join | boolean() | false | ||
member | Defines the discovery (call in) properties for a member | object() | {} | false | |
moderator.join_deaf | Determines if a moderator will join deaf | boolean() | false | false | |
moderator.join_muted | Determines if a moderator will join muted | boolean() | false | false | |
moderator.numbers.[] | string() | false | |||
moderator.numbers | Defines the conference (call in) number(s) for moderators | array(string()) | [] | false | |
moderator.pins.[] | string() | false | |||
moderator.pins | Defines the pin number(s) for moderators | array(string()) | [] | false | |
moderator | Defines the discovery (call in) properties for a moderator | object() | {} | false | |
moderator_controls | profile on the switch for controlling the conference as a moderator | string() | false | ||
name | A friendly name for the conference | string(1..128) | false | supported | |
owner_id | The user ID who manages this conference | string(32) | false | supported | |
play_entry_tone | Whether to play an entry tone, or the entry tone to play | `boolean() | string()` | false | |
play_exit_tone | Whether to play an exit tone, or the exit tone to play | `boolean() | string()` | false | |
play_name | Do we need to announce new conference members? | boolean() | false | false | |
play_welcome | Whether to play the welcome prompt | boolean() | false | ||
profile | Profile configuration | object() | false | ||
profile_name | conference profile name | string() | false | ||
require_moderator | does the conference require a moderator | boolean() | false | ||
wait_for_moderator | should members wait for a moderator before joining the conference | boolean() | false |
conferences.profile
Schema for conference profiles
Key | Description | Type | Default | Required | Support Level |
---|---|---|---|---|---|
alone-sound | Audio that plays while you are alone in the conference | string() | false | ||
announce-count | Play member count to conference when above this threshold | integer() | false | ||
caller-controls | Name of the caller control group | string() | false | ||
comfort-noise | The volume level of background white noise | integer() | false | ||
energy-level | Energy level required for audio to be sent to other users | integer() | false | ||
enter-sound | Audio to play when entering a conference | string() | false | ||
exit-sound | Audio to play when exiting a conference | string() | false | ||
interval | Milliseconds per frame | integer() | false | ||
locked-sound | Audio to play when the conference is locked | string() | false | ||
max-members | Set the maximum number of members in the conference | integer() | false | ||
max-members-sound | If max-members has been reached, audio to play to caller instead of joining the conference | string() | false | ||
moderator-controls | Name of the moderator control group to use | string() | false | ||
moh-sound | Audio to play, on a loop, while participant count is 1 | string() | false | ||
muted-sound | Audio to play when muted | string() | false | ||
rate | Audio sample rate | integer() | false | ||
unmuted-sound | Audio to play when unmuted | string() | false |
Keys under development
require_moderator
wait_for_moderator
Perform an action on a conference
PUT /v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}
curl -v -X PUT \
-d '{"action": "{CONFERENCE_ACTION}", "data": {"ACTION":"DATA"}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}
Action | Description |
---|---|
lock | Lock the conference; no new participants may join |
unlock | Unlock the conference; new participants may join |
dial | Dial an endpoint (user/device/DID) |
play | Play media to the conference (all participants) |
record | Start/stop the recording of the conference |
Lock / unlock
Lock and unlock take no additional data.
curl -v -X PUT \
-d '{"action": "lock", "data": {}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}
Play media into a conference
The play
action takes the media ID to play into the conference.
curl -v -X PUT \
-d '{"action": "play", "data": {"media_id":"{MEDIA_TO_PLAY}"}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}
Start/Stop recording the conference
The record
action takes a toggle of “start” or “stop”:
curl -v -X PUT \
-d '{"action": "record", "data": {"action":"start"}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}
Dialing an endpoint
Sometimes you want to dial out from a conference to an endpoint (versus waiting for the caller to dial into the conference). Similar to how the group
callflow works, you can include device and user IDs; unlike groups, you can include DIDs as well (similar to quickcall/click2call).
Schema
Schema for conferences
Key | Description | Type | Default | Required | Support Level |
---|---|---|---|---|---|
bridge_password | the password used for a conference bridge | string() | false | ||
bridge_username | the username used for a conference bridge | string() | false | ||
caller_controls | caller controls (config settings) | string() | false | ||
conference_numbers.[] | string() | false | |||
conference_numbers | Defines conference numbers that can be used by members or moderators | array(string()) | [] | false | |
controls | controls | object() | false | ||
domain | domain | string() | false | ||
flags.[] | string() | false | supported | ||
flags | Flags set by external applications | array(string()) | false | supported | |
focus | This is a read-only property indicating the media server hosting the conference | string() | false | ||
language | Prompt language to play in the conference | string() | false | ||
max_members_media | Media to play when the conference is full | string() | false | ||
max_participants | The maximum number of participants that can join | integer() | false | ||
member.join_deaf | Determines if a member will join deaf | boolean() | false | false | supported |
member.join_muted | Determines if a member will join muted | boolean() | true | false | supported |
member.numbers.[] | string() | false | |||
member.numbers | Defines the conference (call in) number(s) for members | array(string()) | [] | false | |
member.pins.[] | string() | false | |||
member.pins | Defines the pin number(s) for members | array(string()) | [] | false | |
member.play_entry_prompt | Whether to play the entry prompt on member join | boolean() | false | ||
member | Defines the discovery (call in) properties for a member | object() | {} | false | |
moderator.join_deaf | Determines if a moderator will join deaf | boolean() | false | false | |
moderator.join_muted | Determines if a moderator will join muted | boolean() | false | false | |
moderator.numbers.[] | string() | false | |||
moderator.numbers | Defines the conference (call in) number(s) for moderators | array(string()) | [] | false | |
moderator.pins.[] | string() | false | |||
moderator.pins | Defines the pin number(s) for moderators | array(string()) | [] | false | |
moderator | Defines the discovery (call in) properties for a moderator | object() | {} | false | |
moderator_controls | profile on the switch for controlling the conference as a moderator | string() | false | ||
name | A friendly name for the conference | string(1..128) | false | supported | |
owner_id | The user ID who manages this conference | string(32) | false | supported | |
play_entry_tone | Whether to play an entry tone, or the entry tone to play | `boolean() | string()` | false | |
play_exit_tone | Whether to play an exit tone, or the exit tone to play | `boolean() | string()` | false | |
play_name | Do we need to announce new conference members? | boolean() | false | false | |
play_welcome | Whether to play the welcome prompt | boolean() | false | ||
profile | Profile configuration | object() | false | ||
profile_name | conference profile name | string() | false | ||
require_moderator | does the conference require a moderator | boolean() | false | ||
wait_for_moderator | should members wait for a moderator before joining the conference | boolean() | false |
conferences.profile
Schema for conference profiles
Key | Description | Type | Default | Required | Support Level |
---|---|---|---|---|---|
alone-sound | Audio that plays while you are alone in the conference | string() | false | ||
announce-count | Play member count to conference when above this threshold | integer() | false | ||
caller-controls | Name of the caller control group | string() | false | ||
comfort-noise | The volume level of background white noise | integer() | false | ||
energy-level | Energy level required for audio to be sent to other users | integer() | false | ||
enter-sound | Audio to play when entering a conference | string() | false | ||
exit-sound | Audio to play when exiting a conference | string() | false | ||
interval | Milliseconds per frame | integer() | false | ||
locked-sound | Audio to play when the conference is locked | string() | false | ||
max-members | Set the maximum number of members in the conference | integer() | false | ||
max-members-sound | If max-members has been reached, audio to play to caller instead of joining the conference | string() | false | ||
moderator-controls | Name of the moderator control group to use | string() | false | ||
moh-sound | Audio to play, on a loop, while participant count is 1 | string() | false | ||
muted-sound | Audio to play when muted | string() | false | ||
rate | Audio sample rate | integer() | false | ||
unmuted-sound | Audio to play when unmuted | string() | false |
Endpoints
Dial-able endpoints are
- Devices (by device id or device JSON)
- Users (by user id)
- Phone Numbers
- SIP URIs (
sip:user@realm
)
Note: Phone numbers will involve some internal legs being generated (loopback legs) to process the number as if it was a call coming in for the desired number. This means billing and limits will be applied just the same as if a user dialed the number from their device.
Examples
{
"action":"dial"
,"data":{
"data":{
"endpoints":["{DEVICE_ID}","{USER_ID}","{NUMBER}","sip:{URI}"],
"caller_id_name":"Conference XYZ",
"caller_id_number":"5551212"
}
}
}
As when making QuickCalls, you can include custom_application_vars
:
{
"action":"dial"
,"data":{
"custom_application_vars":{
"foo":"bar"
}
,"data":{
"endpoints":["{DEVICE_ID}","{USER_ID}","{NUMBER}","sip:{URI}"],
"caller_id_name":"Conference XYZ",
"caller_id_number":"5551212"
}
}
}
You can also include the outbound call id you’d like the leg to use:
{
"action":"dial"
,"data":{
"custom_application_vars":{
"foo":"bar"
}
,"data":{
"endpoints":["{DEVICE_ID}","{USER_ID}","{NUMBER}","sip:{URI}"],
"caller_id_name":"Conference XYZ",
"caller_id_number":"5551212",
"outbound_call_id":"xyz-abc"
}
}
}
Participant Flags
You can specify how a participant will enter a conference with a list of attributes:
Value | Description |
---|---|
deaf | Participant joins unable to hear conference audio |
disable_moh | Disable music on hold when the participant is the only one in the conference |
distribute_dtmf | Send DTMF from participant’s leg to all other participants |
ghost | Uncounted in conference membership total |
is_moderator | Participant will join as a moderator |
join_existing | Participant may only join a running conference (won’t start a conference) |
mute | Participant joins muted |
video_mute | Participant joins with video stream muted |
{
"action":"dial"
,"data":{
"data":{
"endpoints":["{DEVICE_ID}","{USER_ID}","{NUMBER}","sip:{URI}"],
"caller_id_name":"Conference XYZ",
"caller_id_number":"5551212",
"participant_flags":["deaf", "mute"]
}
}
}
Dialing out to a dynamic conference
Sometimes you want to create ad-hoc conferences and put a participant in there. You can PUT
a conference and the endpoints to dial out to create a temporary conference. The {CONFERENCE_ID}
you supply will be used to name the conference and any conference schema parameters in the request will be used when creating the conference. For example:
{
"action":"dial"
,"data":{
"data":{
"endpoints":["{DEVICE_ID}","{USER_ID}","{NUMBER}","sip:{URI}"],
"caller_id_name":"Conference XYZ",
"caller_id_number":"5551212",
"play_entry_tone": true,
"play_exit_tone": true,
"play_name": false
}
}
}
These properties will be merged into a “default” conference document and then executed the same as if the conference was preconfigured.
The API response
{
"data": {
"endpoint_responses": [
{
"call_id": "522bb682-da03-11e7-8ce9-5364ba916f96",
"endpoint_id": "{ENDPOINT_FROM_REQUEST}",
"job_id": "137b1e9e-d9fb-11e7-8cad-5364ba916f96",
"message": "dial resulted in call id 522bb682-da03-11e7-8ce9-5364ba916f96",
"status": "success"
}
]
}
,...
}
Playing media to a conference
Playing a media file to everyone in a conference:
{
"action":"play",
"data": {
"data":{"media_id":"{MEDIA_ID}"}
}
}
{MEDIA_ID}
can be a pre-uploaded media ID or a URL to fetch media from.
Perform an action on participants
PUT /v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants
curl -v -X PUT \
-d '{"data": {"action": {PARTICIPANTS_ACTION}}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants
Action | Description |
---|---|
mute | Mute all the participants that are currently unmuted |
unmute | Unmute all the participants that are currently muted |
deaf | Stop sending conference audio to all participants |
undeaf | Start sending conference audio to all participants |
kick | Kick all the participants from the conference |
relate | Relate two participants |
Relate participants
The relate
action takes a data
object:
{
"data":{
"action":"relate"
,"data":{
"participant_id":{ID}
,"other_participant":{ID}
,"relationship":"{RELATIONSHIP}"
}
}
}
Schema
Relate two participants to each other in a conference
Key | Description | Type | Default | Required | Support Level |
---|---|---|---|---|---|
conference_id | The ID of the conference | string() | true | ||
other_participant | The other participant ID to relate | `string() | integer()` | true | |
participant_id | The participant ID to relate | `string() | integer()` | true | |
relationship | The relationship to establish between the two participants | `string(‘deaf' | 'clear' | 'mute’)` | clear |
API example
curl -v -X PUT \
-H "X-Auth-Token: $AUTH_TOKEN" \
"http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants" \
-d'{"data":{"action":"relate","data":{"participant_id":23, "other_participant":24}}}'
{
"auth_token": "{AUTH_TOKEN}",
"data": "relating participants",
"node": "{NODE}",
"request_id": "{REQUEST_ID}",
"revision": "1-100475067fa624422c9a21bd976c7b84",
"status": "success",
"timestamp": "{TIMESTAMP}",
"version": "4.2.2"
}
Perform an action on participant
PUT /v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants/{PARTICIPANT_ID}
curl -v -X PUT \
-d '{"data": {"action": {PARTICIPANT_ACTION}}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants/{PARTICIPANT_ID}
Sometimes you may get a HTTP/1.1 304 Not Modified response from crossbar for similar API calls. If you do, add a random string filter to the end of the call to ensure the request is viewed as ‘unique’. For example:
curl -v -X PUT \
-d '{"data": {"action": {PARTICIPANT_ACTION}}}' \
-H "X-Auth-Token: {AUTH_TOKEN}" \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/conferences/{CONFERENCE_ID}/participants/{PARTICIPANT_ID}?random={RANDOM_BIT}
Action | Description |
---|---|
mute | Mute the participant |
unmute | Unmute the participant |
deaf | Stop sending conference audio to the participant |
undeaf | Start sending conference audio to the participant |
kick | Kick the participant from the conference |
play | Play media to a single participant |
Playing media to a conference
Playing a media file to everyone in a conference:
{"data":{
"action":"play",
"data":{"media_id":"{MEDIA_ID}"}
}
}
{MEDIA_ID}
can be a pare-uploaded media ID or a URL to fetch media from.
List of conferences example
[
{
"id": "",
"name": "",
"owner_id": "",
"member": {
"join_muted": false,
"join_deaf": false,
"numbers": [],
"pins": []
},
"moderator": {
"join_deaf": false,
"join_muted": false,
"numbers": [],
"pins": []
},
"members": 0,
"admins": 0,
"duration": 0,
"is_locked": false
},
...
]
Conference document
{
"name": "Conf",
"id": "",
"owner_id": "",
"play_entry_tone": true,
"play_exit_tone": true,
"play_name": false,
"conference_numbers": [],
"member": {
"join_muted": false,
"join_deaf": false,
"numbers": [],
"pins": []
},
"ui_metadata": {
"ui": "kazoo-ui"
},
"moderator": {
"join_deaf": false,
"join_muted": false,
"numbers": [],
"pins": []
},
"_read_only": {
"members": 0,
"admins": 0,
"duration": 0,
"is_locked": false,
"participants": [
{
"call_id": "",
"conference_name": "",
"conference_uuid": "",
"switch_hostname": "",
"floor": false,
"hear": true,
"speak": true,
"talking": false,
"mute_detect": false,
"participant_id": 1,
"energy_level": 20,
"current_energy": 0,
"video": false,
"is_moderator": false,
"join_time": 63635217275,
"duration": 10
},
...
]
}
}
join_time
is participant’s join time as epoch, duration is number of seconds participant participate in conference.
Here we can see values set up for a Member, then for a Moderator.
The last field, play_entry_tone
, is at the root of the document: meaning this field applies to everyone in the conference.
Available fields
- play_entry_tone and play_exit_tone: can be either a boolean or a non-empty string.
true
means play the default tone when someone joins (or leaves) the conferencefalse
disables the tone from being played- A string like a tone string or a URI to a media file can be inputted.
Web-socket events
A client may subscribe to conference event using websocket connection. Participant events are published as
amqp conference.event.{conference_id}.{call_id}
, where call_id is participant”s call.
The list of published events is determined by publish_participant_event
parameter of ecallmgr configuration,
if parameter is unset, then all events are published.
Participant events
add-member
del-member
stop-talking
start-talking
mute-member
unmute-member
deaf-member
undeaf-member
Example event
{
"custom_channel_vars": {
"account_id": "9d351ad7ffd6f846313af9eed3bb7b85",
"authorizing_id": "6507f40b09a61fbb8b025dbad9316eb5",
"authorizing_type": "device",
"owner_id": "32d8788da9506b4b1991d5bb86d27b0a",
"presence_id": "1000@kamailio.kazoo",
"fetch_id": "56507071-a216-4e0a-a28f-ff3bd9c86ac3",
"bridge_id": "934800819",
"precedence": 5,
"realm": "kamailio.kazoo",
"username": "sip1",
"call_interaction_id": "63635497023-3e247b2e"
},
"channel_presence_id": "1000@kamailio.kazoo",
"caller_id_number": "sip1",
"caller_id_name": "sip1",
"mute_detect": false,
"video": false,
"energy_level": 20,
"current_energy": 0,
"talking": false,
"speak": true,
"hear": true,
"floor": false,
"participant_id": 20,
"instance_id": "d5765180-53d5-4104-860e-b352f3f8e6b1",
"conference_id": "5edbfdd3b825314a71b0a05957392edb",
"focus": "freeswitch@freeswitch.kazoo",
"call_id": "934800819",
"event": "add-member",
"node": "kazoo_apps@jh460",
"msg_id": "a6fbbf034b5cd3af",
"event_name": "participant_event",
"event_category": "conference",
"app_version": "4.0.0",
"app_name": "ecallmgr",
"routing_key": "participant_event"
}