Skip to content

Commit f435e34

Browse files
Merge pull request #131 from Bandwidth/DX-2895
DX-2895 `<Conference>` Verb Refactored
2 parents 4b44c49 + 7835aaa commit f435e34

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

bandwidth/model/bxml/verbs/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .bridge import Bridge
2+
from .conference import Conference
23
from .hangup import Hangup
34
from .gather import Gather
45
from .pause import Pause
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""
2+
conference.py
3+
4+
Bandwidth's Conference BXML verb
5+
6+
@copyright Bandwidth INC
7+
"""
8+
from typing import Union, List
9+
from ..verb import Verb
10+
from .play_audio import PlayAudio
11+
from .speak_sentence import SpeakSentence
12+
from .start_recording import StartRecording
13+
from .stop_recording import StopRecording
14+
from .pause_recording import PauseRecording
15+
from .resume_recording import ResumeRecording
16+
17+
18+
class Conference(Verb):
19+
20+
def __init__(
21+
self, name: str,
22+
audio_and_recording_verbs: List[Union[PlayAudio, SpeakSentence, StartRecording, StopRecording, PauseRecording, ResumeRecording]] = [], mute: str=None,
23+
hold: str=None, call_ids_to_coach: str=None,
24+
conference_event_url: str=None, conference_event_method: str=None,
25+
conference_event_fallback_url: str=None, conference_event_fallback_method: str=None,
26+
username: str=None, password: str=None,
27+
fallback_username: str=None, fallback_password: str=None,
28+
tag: str=None, callback_timeout: str=None,
29+
):
30+
"""Initialize a <Conference> verb
31+
32+
Args:
33+
name (str): The name of the conference. Can contain up to 100 characters of letters, numbers, and the symbols -, _, and .
34+
mute (str, optional): A boolean value to indicate whether the member should be on mute in the conference. When muted, a member can hear others speak, but others cannot hear them speak. Defaults to false.
35+
hold (str, optional): A boolean value to indicate whether the member should be on hold in the conference. When on hold, a member cannot hear others, and they cannot be heard. Defaults to false.
36+
call_ids_to_coach (str, optional): A comma-separated list of call ids to coach. When a call joins a conference with this attribute set, it will coach the listed calls.
37+
Those calls will be able to hear and be heard by the coach, but other calls in the conference will not hear the coach.
38+
conference_event_url (str, optional): URL to send Conference events to. The URL, method, username, and password are set by the BXML document that creates the conference,
39+
and all events related to that conference will be delivered to that same endpoint. If more calls join afterwards and also have this property (or any other webhook related properties like username and password),
40+
they will be ignored and the original webhook information will be used. This URL may be a relative endpoint.
41+
conference_event_method (str, optional): The HTTP method to use for the request to conferenceEventUrl. GET or POST. Default value is POST.
42+
conference_event_fallback_url (str, optional): A fallback url which, if provided, will be used to retry the conference webhook deliveries in case conferenceEventUrl fails to respond.
43+
conference_event_fallback_method (str, optional): The HTTP method to use to deliver the conference webhooks to conferenceEventFallbackUrl. GET or POST. Default value is POST.
44+
username (str, optional):The username to send in the HTTP request to conferenceEventUrl.
45+
password (str, optional): The password to send in the HTTP request to conferenceEventUrl.
46+
fallback_username (str, optional): The username to send in the HTTP request to conferenceEventFallbackUrl.
47+
fallback_password (str, optional): The password to send in the HTTP request to conferenceEventFallbackUrl.
48+
tag (str, optional): A custom string that will be sent with this and all future callbacks unless overwritten by a future tag attribute or <Tag> verb, or cleared. May be cleared by setting tag="".
49+
Max length 256 characters. Defaults to None.
50+
callback_timeout (str, optional): This is the timeout (in seconds) to use when delivering webhooks for the conference.
51+
If not set, it will inherit the webhook timeout from the call that creates the conference. Can be any numeric value (including decimals) between 1 and 25.
52+
53+
Nested Verbs:
54+
PlayAudio: (optional)
55+
SpeakSentence: (optional)
56+
StartRecording: (optional)
57+
StopRecording: (optional)
58+
PauseRecording: (optional)
59+
ResumeRecording: (optional)
60+
"""
61+
self.name = name
62+
self.mute = mute
63+
self.hold = hold
64+
self.call_ids_to_coach = call_ids_to_coach
65+
self.conference_event_url = conference_event_url
66+
self.conference_event_method = conference_event_method
67+
self.conference_event_fallback_url = conference_event_fallback_url
68+
self.conference_event_fallback_method = conference_event_fallback_method
69+
self.username = username
70+
self.password = password
71+
self.fallback_username = fallback_username
72+
self.fallback_password = fallback_password
73+
self.tag = tag
74+
self.callback_timeout = callback_timeout
75+
self.audio_and_recording_verbs = audio_and_recording_verbs
76+
super().__init__(
77+
tag="Conference",
78+
content=self.name,
79+
nested_verbs=self.audio_and_recording_verbs)
80+
81+
@property
82+
def _attributes(self):
83+
return {
84+
"mute": self.mute,
85+
"hold": self.hold,
86+
"callIdsToCoach": self.call_ids_to_coach,
87+
"conferenceEventUrl": self.conference_event_url,
88+
"conferenceEventMethod": self.conference_event_method,
89+
"conferenceEventFallbackUrl": self.conference_event_fallback_url,
90+
"conferenceEventFallbackMethod": self.conference_event_fallback_method,
91+
"username": self.username,
92+
"password": self.password,
93+
"fallbackUsername": self.fallback_username,
94+
"fallbackPassword": self.fallback_password,
95+
"tag": self.tag,
96+
"callbackTimeout": self.callback_timeout,
97+
}

test/unit/bxml/test_conference.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
test_conference.py
3+
4+
Unit tests for the <Conference> BXML verb
5+
6+
@copyright Bandwidth Inc.
7+
"""
8+
import os
9+
import pytest
10+
import unittest
11+
12+
from bandwidth.model.bxml.verb import Verb
13+
from bandwidth.model.bxml.verbs import *
14+
15+
class TestGather(unittest.TestCase):
16+
17+
def setUp(self):
18+
self.play_audio = PlayAudio(
19+
audio_uri="https://audio.url/audio1.wav"
20+
)
21+
22+
self.speak_sentence = SpeakSentence(
23+
text='Hello there.'
24+
)
25+
self.start_recording = StartRecording(
26+
recording_available_url = "example.com",
27+
recording_available_method = "POST",
28+
username = "user",
29+
password = "pass",
30+
tag = "tag",
31+
file_format = "wav",
32+
multi_channel = "true"
33+
)
34+
35+
self.conference = Conference(
36+
name="conf1",
37+
mute = "true",
38+
hold = "false",
39+
call_ids_to_coach = "example-call-id",
40+
conference_event_url = "example.com/eventurl",
41+
conference_event_method = "POST",
42+
conference_event_fallback_url = "backupexample.com/eventurl",
43+
conference_event_fallback_method = "POST",
44+
username = "user",
45+
password = "pass",
46+
fallback_username = "user",
47+
fallback_password = "pass",
48+
tag = "tag",
49+
callback_timeout = "5",
50+
audio_and_recording_verbs=[self.play_audio, self.start_recording]
51+
)
52+
53+
def test_to_bxml(self):
54+
if os.environ['PYTHON_VERSION'] == '3.7':
55+
expected = '<Conference callIdsToCoach="example-call-id" callbackTimeout="5" conferenceEventFallbackMethod="POST" conferenceEventFallbackUrl="backupexample.com/eventurl" conferenceEventMethod="POST" conferenceEventUrl="example.com/eventurl" fallbackPassword="pass" fallbackUsername="user" hold="false" mute="true" password="pass" tag="tag" username="user">conf1<PlayAudio>https://audio.url/audio1.wav</PlayAudio><StartRecording fileFormat="wav" multiChannel="true" password="pass" recordingAvailableMethod="POST" recordingAvailableUrl="example.com" tag="tag" username="user" /></Conference>'
56+
else:
57+
expected = '<Conference mute="true" hold="false" callIdsToCoach="example-call-id" conferenceEventUrl="example.com/eventurl" conferenceEventMethod="POST" conferenceEventFallbackUrl="backupexample.com/eventurl" conferenceEventFallbackMethod="POST" username="user" password="pass" fallbackUsername="user" fallbackPassword="pass" tag="tag" callbackTimeout="5">conf1<PlayAudio>https://audio.url/audio1.wav</PlayAudio><StartRecording recordingAvailableUrl="example.com" recordingAvailableMethod="POST" username="user" password="pass" tag="tag" fileFormat="wav" multiChannel="true" /></Conference>'
58+
assert(expected == self.conference.to_bxml())
59+
60+
def test_add_verb(self):
61+
if os.environ['PYTHON_VERSION'] == '3.7':
62+
expected = '<Conference callIdsToCoach="example-call-id" callbackTimeout="5" conferenceEventFallbackMethod="POST" conferenceEventFallbackUrl="backupexample.com/eventurl" conferenceEventMethod="POST" conferenceEventUrl="example.com/eventurl" fallbackPassword="pass" fallbackUsername="user" hold="false" mute="true" password="pass" tag="tag" username="user">conf1<PlayAudio>https://audio.url/audio1.wav</PlayAudio><StartRecording fileFormat="wav" multiChannel="true" password="pass" recordingAvailableMethod="POST" recordingAvailableUrl="example.com" tag="tag" username="user" /><SpeakSentence>Hello there.</SpeakSentence></Conference>'
63+
else:
64+
expected = '<Conference mute="true" hold="false" callIdsToCoach="example-call-id" conferenceEventUrl="example.com/eventurl" conferenceEventMethod="POST" conferenceEventFallbackUrl="backupexample.com/eventurl" conferenceEventFallbackMethod="POST" username="user" password="pass" fallbackUsername="user" fallbackPassword="pass" tag="tag" callbackTimeout="5">conf1<PlayAudio>https://audio.url/audio1.wav</PlayAudio><StartRecording recordingAvailableUrl="example.com" recordingAvailableMethod="POST" username="user" password="pass" tag="tag" fileFormat="wav" multiChannel="true" /><SpeakSentence>Hello there.</SpeakSentence></Conference>'
65+
self.conference.add_verb(self.speak_sentence)
66+
assert(expected == self.conference.to_bxml())

0 commit comments

Comments
 (0)