Passed
Push — master ( dffabb...ad0bc7 )
by Vyacheslav
01:29
created

command.go (1 issue)

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