forked from Marquis42/ari
/
bridge.go
215 lines (181 loc) · 6.1 KB
/
bridge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package native
import (
"errors"
"time"
"github.com/CyCoreSystems/ari"
"github.com/CyCoreSystems/ari/rid"
)
// Bridge provides the ARI Bridge accessors for the native client
type Bridge struct {
client *Client
}
// Create creates a bridge and returns the lazy handle for the bridge
func (b *Bridge) Create(key *ari.Key, t string, name string) (bh *ari.BridgeHandle, err error) {
bh, err = b.StageCreate(key, t, name)
if err != nil {
return nil, err
}
return bh, bh.Exec()
}
// StageCreate creates a new bridge handle, staged with a bridge `Create` operation.
func (b *Bridge) StageCreate(key *ari.Key, btype, name string) (*ari.BridgeHandle, error) {
if key.ID == "" {
key.ID = rid.New(rid.Bridge)
}
req := struct {
ID string `json:"bridgeId,omitempty"`
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
}{
ID: key.ID,
Type: btype,
Name: name,
}
return ari.NewBridgeHandle(b.client.stamp(key), b, func(bh *ari.BridgeHandle) (err error) {
return b.client.post("/bridges/"+key.ID, nil, &req)
}), nil
}
// Get gets the lazy handle for the given bridge id
func (b *Bridge) Get(key *ari.Key) *ari.BridgeHandle {
return ari.NewBridgeHandle(b.client.stamp(key), b, nil)
}
// List lists the current bridges and returns a list of lazy handles
func (b *Bridge) List(filter *ari.Key) (bx []*ari.Key, err error) {
// native client ignores filter
var bridges = []struct {
ID string `json:"id"`
}{}
err = b.client.get("/bridges", &bridges)
for _, i := range bridges {
k := b.client.stamp(ari.NewKey(ari.BridgeKey, i.ID))
if filter.Match(k) {
bx = append(bx, k)
}
}
return
}
// Data returns the details of a bridge
// Equivalent to Get /bridges/{bridgeId}
func (b *Bridge) Data(key *ari.Key) (*ari.BridgeData, error) {
if key == nil || key.ID == "" {
return nil, errors.New("bridge key not supplied")
}
var data = new(ari.BridgeData)
if err := b.client.get("/bridges/"+key.ID, data); err != nil {
return nil, dataGetError(err, "bridge", "%v", key.ID)
}
data.Key = b.client.stamp(key)
return data, nil
}
// AddChannel adds a channel to a bridge
// Equivalent to Post /bridges/{id}/addChannel
func (b *Bridge) AddChannel(key *ari.Key, channelID string) (err error) {
id := key.ID
type request struct {
ChannelID string `json:"channel"`
Role string `json:"role,omitempty"`
}
req := request{channelID, ""}
err = b.client.post("/bridges/"+id+"/addChannel", nil, &req)
return
}
// RemoveChannel removes the specified channel from a bridge
// Equivalent to Post /bridges/{id}/removeChannel
func (b *Bridge) RemoveChannel(key *ari.Key, channelID string) (err error) {
id := key.ID
req := struct {
ChannelID string `json:"channel"`
}{
ChannelID: channelID,
}
//pass request
err = b.client.post("/bridges/"+id+"/removeChannel", nil, &req)
return
}
// Delete shuts down a bridge. If any channels are in this bridge,
// they will be removed and resume whatever they were doing beforehand.
// This means that the channels themselves are not deleted.
// Equivalent to DELETE /bridges/{id}
func (b *Bridge) Delete(key *ari.Key) (err error) {
return b.client.del("/bridges/"+key.ID, nil, "")
}
// MOH requests that the given musiconhold class be played to the bridge
func (b *Bridge) MOH(key *ari.Key, class string) error {
req := struct {
Class string `json:"mohClass"`
}{
Class: class,
}
return b.client.post("/bridges/"+key.ID+"/moh", nil, &req)
}
// StopMOH requests that any MusicOnHold which is playing to the bridge be stopped.
func (b *Bridge) StopMOH(key *ari.Key) error {
return b.client.del("/bridges/"+key.ID+"/moh", nil, "")
}
// Play attempts to play the given mediaURI on the bridge, using the playbackID
// as the identifier to the created playback handle
func (b *Bridge) Play(key *ari.Key, playbackID string, mediaURI string) (*ari.PlaybackHandle, error) {
h, err := b.StagePlay(key, playbackID, mediaURI)
if err != nil {
return nil, err
}
return h, h.Exec()
}
// StagePlay stages a `Play` operation on the bridge
func (b *Bridge) StagePlay(key *ari.Key, playbackID string, mediaURI string) (*ari.PlaybackHandle, error) {
if playbackID == "" {
playbackID = rid.New(rid.Playback)
}
resp := make(map[string]interface{})
req := struct {
Media string `json:"media"`
}{
Media: mediaURI,
}
playbackKey := b.client.stamp(ari.NewKey(ari.PlaybackKey, playbackID))
return ari.NewPlaybackHandle(playbackKey, b.client.Playback(), func(h *ari.PlaybackHandle) error {
return b.client.post("/bridges/"+key.ID+"/play/"+playbackID, &resp, &req)
}), nil
}
// Record attempts to record audio on the bridge, using name as the identifier for
// the created live recording handle
func (b *Bridge) Record(key *ari.Key, name string, opts *ari.RecordingOptions) (*ari.LiveRecordingHandle, error) {
h, err := b.StageRecord(key, name, opts)
if err != nil {
return nil, err
}
return h, h.Exec()
}
// StageRecord stages a `Record` opreation
func (b *Bridge) StageRecord(key *ari.Key, name string, opts *ari.RecordingOptions) (*ari.LiveRecordingHandle, error) {
if opts == nil {
opts = &ari.RecordingOptions{}
}
resp := make(map[string]interface{})
req := struct {
Name string `json:"name"`
Format string `json:"format"`
MaxDuration int `json:"maxDurationSeconds"`
MaxSilence int `json:"maxSilenceSeconds"`
IfExists string `json:"ifExists,omitempty"`
Beep bool `json:"beep"`
TerminateOn string `json:"terminateOn,omitempty"`
}{
Name: name,
Format: opts.Format,
MaxDuration: int(opts.MaxDuration / time.Second),
MaxSilence: int(opts.MaxSilence / time.Second),
IfExists: opts.Exists,
Beep: opts.Beep,
TerminateOn: opts.Terminate,
}
recordingKey := b.client.stamp(ari.NewKey(ari.LiveRecordingKey, name))
return ari.NewLiveRecordingHandle(recordingKey, b.client.LiveRecording(), func(h *ari.LiveRecordingHandle) error {
return b.client.post("/bridges/"+key.ID+"/record", &resp, &req)
}), nil
}
// Subscribe creates an event subscription for events related to the given
// bridge␃entity
func (b *Bridge) Subscribe(key *ari.Key, n ...string) ari.Subscription {
return b.client.Bus().Subscribe(key, n...)
}