goagi.*AGI.RecordFile   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 21
nop 7
dl 0
loc 30
rs 8.4426
c 0
b 0
f 0
1
package goagi
2
3
import (
4
	"fmt"
5
)
6
7
// Command sends command as string to the AGI and returns response values with
8
// text response
9
func (agi *AGI) Command(cmd string) (Response, error) {
10
	return agi.execute(cmd + "\n")
11
}
12
13
// Answer executes AGI command "ANSWER"
14
// Answers channel if not already in answer state.
15
func (agi *AGI) Answer() (Response, error) {
16
	return agi.execute("ANSWER\n")
17
}
18
19
// AsyncAGIBreak Interrupts Async AGI
20
//
21
//	Interrupts expected flow of Async AGI commands and returns control
22
//
23
// to previous source (typically, the PBX dialplan).
24
func (agi *AGI) AsyncAGIBreak() (Response, error) {
25
	return agi.execute("ASYNCAGI BREAK\n")
26
}
27
28
/*
29
ChannelStatus returns status of the connected channel.
30
31
If no channel name is given (empty line) then returns the status of the current channel.
32
33
Return values:
34
35
0 - Channel is down and available.
36
37
1 - Channel is down, but reserved.
38
39
2 - Channel is off hook.
40
41
3 - Digits (or equivalent) have been dialed.
42
43
4 - Line is ringing.
44
45
5 - Remote end is ringing.
46
47
6 - Line is up.
48
49
7 - Line is busy.
50
*/
51
func (agi *AGI) ChannelStatus(channel string) (Response, error) {
52
	cmd := fmt.Sprintf("CHANNEL STATUS %s\n", channel)
53
	return agi.execute(cmd)
54
}
55
56
/*
57
ControlStreamFile sends audio file on channel and allows the listener to control the stream.
58
Send the given file, allowing playback to be controlled by the given digits, if any.
59
Use double quotes for the digits if you wish none to be permitted. If offsetms
60
is provided then the audio will seek to offsetms before play starts.
61
62
Example:
63
64
	agi.ControlStreamFile("prompt_en", "19", "3000", "#", "0", "#", "1600")
65
	agi.ControlStreamFile("prompt_en", "")
66
	agi.ControlStreamFile("prompt_en", "19", "", "", "", "#", "1600")
67
*/
68
func (agi *AGI) ControlStreamFile(filename, digits string, args ...string) (Response, error) {
69
	cmd := fmt.Sprintf("CONTROL STREAM FILE %s %q", filename, digits)
70
71
	if len(args) > 5 {
72
		return nil, ErrAGI.Msg("Too many arguments. Unknown args: %v", args[5:])
73
	}
74
75
	for _, v := range args {
76
		cmd = fmt.Sprintf("%s %q", cmd, v)
77
	}
78
79
	cmd = fmt.Sprintf("%s\n", cmd)
80
	return agi.execute(cmd)
81
}
82
83
// DatabaseDel deletes an entry in the Asterisk database for a given family and key.
84
//
85
//	Returns status and error if fails.
86
func (agi *AGI) DatabaseDel(family, key string) (Response, error) {
87
	cmd := fmt.Sprintf("DATABASE DEL %s %s\n", family, key)
88
	return agi.execute(cmd)
89
}
90
91
// DatabaseDelTree deletes a family or specific keytree within a family in the Asterisk database.
92
func (agi *AGI) DatabaseDelTree(family, keytree string) (Response, error) {
93
	cmd := fmt.Sprintf("DATABASE DELTREE %s %s\n", family, keytree)
94
	return agi.execute(cmd)
95
}
96
97
// DatabaseGet Retrieves an entry in the Asterisk database for a given family and key.
98
//
99
//		Returns value as string or error if failed or value not set
100
//	 Response.Value() for result
101
func (agi *AGI) DatabaseGet(family, key string) (Response, error) {
102
	cmd := fmt.Sprintf("DATABASE GET %s %s\n", family, key)
103
	return agi.execute(cmd)
104
}
105
106
// DatabasePut adds or updates an entry in the Asterisk database for
107
// a given family, key, and value.
108
func (agi *AGI) DatabasePut(family, key, val string) (Response, error) {
109
	cmd := fmt.Sprintf("DATABASE PUT %s %s %s\n", family, key, val)
110
	return agi.execute(cmd)
111
}
112
113
// Exec executes application with given options.
114
func (agi *AGI) Exec(app, opts string) (Response, error) {
115
	cmd := fmt.Sprintf("EXEC %s %q\n", app, opts)
116
	return agi.execute(cmd)
117
}
118
119
/*
120
GetData Stream the given file, and receive DTMF data.
121
Note: when timeout is 0 then Asterisk will use 6 seconds.
122
Note: Asterisk has strange way to handle get data response.
123
Contrary to other responses, where result has numeric value,
124
here asterisk puts DTMF to sent by user to result and this value
125
may contain "#" and "*".
126
127
To get DTMF sent by user use Response.Data()
128
129
Response.Value() will contain "timeout" if user has not terminated
130
input with "#"
131
*/
132
func (agi *AGI) GetData(file string, timeout, maxdigit int) (Response, error) {
133
	cmd := fmt.Sprintf("GET DATA %s %d %d\n", file, timeout, maxdigit)
134
	resp, err := agi.execute(cmd)
135
	if err != nil {
136
		return nil, err
137
	}
138
	// special get data result treatment
139
	if resp.Result() == -1 || resp.Code() != codeSucc {
140
		return resp, nil
141
	}
142
143
	r := resp.(*responseSuccess)
144
	r.result = 0
145
	r.data = scanResultStrFromRaw(r.raw)
146
	return r, nil
147
}
148
149
// GetFullVariable evaluates a channel expression
150
func (agi *AGI) GetFullVariable(name, channel string) (Response, error) {
151
	cmd := "GET FULL VARIABLE"
152
	if channel == "" {
153
		cmd = fmt.Sprintf("%s %s\n", cmd, name)
154
	} else {
155
		cmd = fmt.Sprintf("%s %s %s\n", cmd, name, channel)
156
	}
157
	return agi.execute(cmd)
158
}
159
160
// GetOption Stream file, prompt for DTMF, with timeout.
161
//
162
//	Behaves similar to STREAM FILE but used with a timeout option.
163
//	Returns digit pressed, offset and error
164
func (agi *AGI) GetOption(filename, digits string, timeout int32) (Response, error) {
165
	cmd := fmt.Sprintf("GET OPTION %s %q %d\n", filename, digits, timeout)
166
	return agi.execute(cmd)
167
}
168
169
// GetVariable Gets a channel variable.
170
func (agi *AGI) GetVariable(name string) (Response, error) {
171
	cmd := fmt.Sprintf("GET VARIABLE %s\n", name)
172
	return agi.execute(cmd)
173
}
174
175
// Hangup hangs up the specified channel. If no channel name is given, hangs up the current channel
176
func (agi *AGI) Hangup(channel ...string) (Response, error) {
177
	cmd := "HANGUP"
178
179
	if len(channel) > 0 {
180
		cmd = fmt.Sprintf("%s %s\n", cmd, channel[0])
181
	} else {
182
		cmd = fmt.Sprintf("%s\n", cmd)
183
	}
184
	return agi.execute(cmd)
185
}
186
187
/*
188
ReceiveChar Receives one character from channels supporting it.
189
Most channels do not support the reception of text. Returns the decimal value of
190
the character if one is received, or 0 if the channel does not support text reception.
191
192
timeout - The maximum time to wait for input in milliseconds, or 0 for infinite.
193
194
Returns result -1 on error or char byte
195
*/
196
func (agi *AGI) ReceiveChar(timeout int) (Response, error) {
197
	cmd := fmt.Sprintf("RECEIVE CHAR %d\n", timeout)
198
	return agi.execute(cmd)
199
}
200
201
/*
202
ReceiveText Receives text from channels supporting it.
203
204
timeout - The timeout to be the maximum time to wait for input in milliseconds, or 0 for infinite.
205
*/
206
func (agi *AGI) ReceiveText(timeout int) (Response, error) {
207
	cmd := fmt.Sprintf("RECEIVE TEXT %d\n", timeout)
208
	return agi.execute(cmd)
209
}
210
211
/*
212
RecordFile Record to a file until a given dtmf digit in the sequence is received.
213
The format will specify what kind of file will be recorded. The timeout is the
214
maximum record time in milliseconds, or -1 for no timeout.
215
216
offset samples is optional, and, if provided, will seek to the offset without
217
exceeding the end of the file.
218
219
beep causes Asterisk to play a beep to the channel that is about to be recorded.
220
221
silence is the number of seconds of silence allowed before the function returns
222
despite the lack of dtmf digits or reaching timeout.
223
224
silence is the number of seconds of silence that are permitted before the
225
recording is terminated, regardless of the escape_digits or timeout arguments
226
227
If interrupted by DTMF, digits will be available in Response.Data()
228
*/
229
func (agi *AGI) RecordFile(file, format, escDigits string,
230
	timeout, offset int, beep bool, silence int,
231
) (Response, error) {
232
	cmd := "RECORD FILE"
233
	cmd = fmt.Sprintf("%s %s %s %q %d", cmd, file, format, escDigits, timeout)
234
	if offset > 0 {
235
		cmd = fmt.Sprintf("%s %d", cmd, offset)
236
	}
237
	if beep {
238
		cmd = fmt.Sprintf("%s BEEP", cmd)
239
	}
240
	if silence > 0 {
241
		cmd = fmt.Sprintf("%s s=%d", cmd, silence)
242
	}
243
	cmd = fmt.Sprintf("%s\n", cmd)
244
245
	resp, err := agi.execute(cmd)
246
	if err != nil {
247
		return nil, err
248
	}
249
250
	if resp.Value() != "dtmf" {
251
		return resp, nil
252
	}
253
254
	r := resp.(*responseSuccess)
255
	r.result = 1
256
	r.data = scanResultStrFromRaw(r.raw)
257
258
	return r, nil
259
}
260
261
// SayAlpha says a given character string, returning early if any of the given
262
// DTMF digits are received on the channel.
263
func (agi *AGI) SayAlpha(line, escDigits string) (Response, error) {
264
	cmd := fmt.Sprintf("SAY ALPHA %s %q\n", line, escDigits)
265
	return agi.execute(cmd)
266
}
267
268
// SayDate say a given date, returning early if any of the given DTMF digits
269
// are received on the channel
270
func (agi *AGI) SayDate(date, escDigits string) (Response, error) {
271
	cmd := fmt.Sprintf("SAY DATE %s %q\n", date, escDigits)
272
	return agi.execute(cmd)
273
}
274
275
// SayDatetime say a given time, returning early if any of the given DTMF
276
// digits are received on the channel
277
func (agi *AGI) SayDatetime(time, escDigits, format, timezone string) (Response, error) {
278
	cmd := fmt.Sprintf("SAY DATETIME %s %q %q %q\n", time, escDigits, format, timezone)
279
	return agi.execute(cmd)
280
}
281
282
// SayDigits say a given digit string, returning early if any of the given
283
// DTMF digits are received on the channel
284
func (agi *AGI) SayDigits(number, escDigits string) (Response, error) {
285
	cmd := fmt.Sprintf("SAY DIGITS %s %q\n", number, escDigits)
286
	return agi.execute(cmd)
287
}
288
289
// SayNumber say a given digit string, returning early if any of the given
290
// DTMF digits are received on the channel
291
func (agi *AGI) SayNumber(number, escDigits string) (Response, error) {
292
	cmd := fmt.Sprintf("SAY NUMBER %s %q\n", number, escDigits)
293
	return agi.execute(cmd)
294
}
295
296
// SayPhonetic say a given character string with phonetics, returning early
297
// if any of the given DTMF digits are received on the channel
298
func (agi *AGI) SayPhonetic(str, escDigits string) (Response, error) {
299
	cmd := fmt.Sprintf("SAY PHONETIC %s %q\n", str, escDigits)
300
	return agi.execute(cmd)
301
}
302
303
// SayTime say a given time, returning early if any of the given DTMF digits
304
// are received on the channel
305
func (agi *AGI) SayTime(time, escDigits string) (Response, error) {
306
	cmd := fmt.Sprintf("SAY TIME %s %q\n", time, escDigits)
307
	return agi.execute(cmd)
308
}
309
310
// SendImage Sends the given image on a channel. Most channels do not support
311
// the transmission of images.
312
func (agi *AGI) SendImage(image string) (Response, error) {
313
	cmd := fmt.Sprintf("SEND IMAGE %q\n", image)
314
	return agi.execute(cmd)
315
}
316
317
// SendText Sends the given text on a channel. Most channels do not support
318
// the transmission of text.
319
func (agi *AGI) SendText(text string) (Response, error) {
320
	cmd := fmt.Sprintf("SEND TEXT %q\n", text)
321
	return agi.execute(cmd)
322
}
323
324
// SetAutoHangup Cause the channel to automatically hangup at time seconds in the future.
325
// Setting to 0 will cause the autohangup feature to be disabled on this channel.
326
func (agi *AGI) SetAutoHangup(seconds int) (Response, error) {
327
	cmd := fmt.Sprintf("SET AUTOHANGUP %d\n", seconds)
328
	return agi.execute(cmd)
329
}
330
331
// SetCallerid Changes the callerid of the current channel.
332
func (agi *AGI) SetCallerid(clid string) (Response, error) {
333
	cmd := fmt.Sprintf("SET CALLERID %q\n", clid)
334
	return agi.execute(cmd)
335
}
336
337
// SetContext Sets the context for continuation upon exiting the application.
338
func (agi *AGI) SetContext(ctx string) (Response, error) {
339
	cmd := fmt.Sprintf("SET CONTEXT %s\n", ctx)
340
	return agi.execute(cmd)
341
}
342
343
// SetExtension Changes the extension for continuation upon exiting the application.
344
func (agi *AGI) SetExtension(ext string) (Response, error) {
345
	cmd := fmt.Sprintf("SET EXTENSION %s\n", ext)
346
	return agi.execute(cmd)
347
}
348
349
// SetMusic Enables/Disables the music on hold generator. If class is not specified,
350
// then the default music on hold class will be used.
351
func (agi *AGI) SetMusic(enable bool, class string) (Response, error) {
352
	cmd := "SET MUSIC"
353
354
	if enable {
355
		cmd = fmt.Sprintf("%s on", cmd)
356
	} else {
357
		cmd = fmt.Sprintf("%s off", cmd)
358
	}
359
360
	cmd = fmt.Sprintf("%s %q\n", cmd, class)
361
	return agi.execute(cmd)
362
}
363
364
// SetPriority Changes the priority for continuation upon exiting the application.
365
// The priority must be a valid priority or label.
366
func (agi *AGI) SetPriority(priority string) (Response, error) {
367
	cmd := fmt.Sprintf("SET PRIORITY %s\n", priority)
368
	return agi.execute(cmd)
369
}
370
371
// SetVariable Sets a variable to the current channel.
372
func (agi *AGI) SetVariable(name, value string) (Response, error) {
373
	cmd := fmt.Sprintf("SET VARIABLE %s %q\n", name, value)
374
	return agi.execute(cmd)
375
}
376
377
// StreamFile Send the given file, allowing playback to be interrupted by the given
378
// digits, if any.
379
func (agi *AGI) StreamFile(file, escDigits string, offset int) (Response, error) {
380
	cmd := fmt.Sprintf("STREAM FILE %s %q %d\n", file, escDigits, offset)
381
	return agi.execute(cmd)
382
}
383
384
// TDDMode Enable/Disable TDD transmission/reception on a channel.
385
// Modes: on, off, mate, tdd
386
func (agi *AGI) TDDMode(mode string) (Response, error) {
387
	cmd := "TDD MODE"
388
	switch mode {
389
	case "on", "off", "mate", "tdd":
390
		cmd = fmt.Sprintf("%s %s\n", cmd, mode)
391
	default:
392
		cmd = fmt.Sprintf("%s off\n", cmd)
393
	}
394
	return agi.execute(cmd)
395
}
396
397
// Verbose Sends message to the console via verbose message system.
398
// level is the verbose level (1-4)
399
func (agi *AGI) Verbose(msg string, level ...int) (Response, error) {
400
	cmd := fmt.Sprintf("VERBOSE %q", msg)
401
	lvl := 1
402
	if level != nil {
403
		if level[0] > 0 && level[0] < 5 {
404
			lvl = level[0]
405
		}
406
	}
407
	cmd = fmt.Sprintf("%s %d\n", cmd, lvl)
408
	return agi.execute(cmd)
409
}
410
411
/*
412
WaitForDigit Waits up to timeout *milliseconds* for channel to receive a DTMF digit.
413
Use -1 for the timeout value if you desire the call to block indefinitely.
414
415
Return digit pressed as string or error
416
*/
417
func (agi *AGI) WaitForDigit(timeout int) (Response, error) {
418
	cmd := fmt.Sprintf("WAIT FOR DIGIT %d\n", timeout)
419
	return agi.execute(cmd)
420
}
421