0
# TwiML Generation
1
2
TwiML (Twilio Markup Language) builders provide a fluent, type-safe interface for creating XML responses to handle incoming calls, messages, and faxes. These response builders generate valid TwiML that instructs Twilio how to handle communications.
3
4
## Capabilities
5
6
### VoiceResponse
7
8
TwiML response builder for handling voice calls with comprehensive support for call control, media playback, recording, and advanced telephony features.
9
10
```typescript { .api }
11
/**
12
* TwiML response builder for voice communications
13
* Generates XML instructions for handling incoming voice calls
14
*/
15
class VoiceResponse {
16
constructor();
17
18
/** Generate the final TwiML XML string */
19
toString(): string;
20
21
/** Add XML comments to the response */
22
comment(comment: string): XMLElement;
23
commentBefore(comment: string): XMLElement;
24
commentAfter(comment: string): XMLElement;
25
}
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
import TwilioSDK from "twilio";
32
33
// Access TwiML classes via namespace
34
const { twiml } = TwilioSDK;
35
36
// Basic voice response
37
const response = new twiml.VoiceResponse();
38
response.say("Hello, welcome to our service!");
39
response.hangup();
40
41
console.log(response.toString());
42
// Outputs: <?xml version="1.0" encoding="UTF-8"?><Response><Say>Hello, welcome to our service!</Say><Hangup/></Response>
43
```
44
45
### Voice Communication Verbs
46
47
Core TwiML verbs for voice communication and call control.
48
49
```typescript { .api }
50
/** Text-to-speech with voice and language options */
51
say(message?: string, attributes?: SayAttributes): Say;
52
53
/** Play audio files or streams */
54
play(url?: string, attributes?: PlayAttributes): Play;
55
56
/** Collect DTMF input from caller */
57
gather(attributes?: GatherAttributes): Gather;
58
59
/** Make outbound calls or connect to other parties */
60
dial(number?: string, attributes?: DialAttributes): Dial;
61
62
/** Record audio from the caller */
63
record(attributes?: RecordAttributes): Record;
64
65
/** Redirect call to another TwiML URL */
66
redirect(url?: string, attributes?: RedirectAttributes): Redirect;
67
68
/** Pause execution for specified duration */
69
pause(attributes?: PauseAttributes): Pause;
70
71
/** Terminate the call */
72
hangup(): Hangup;
73
74
/** Reject incoming call with specific reason */
75
reject(attributes?: RejectAttributes): Reject;
76
```
77
78
### Advanced Voice Features
79
80
Advanced TwiML verbs for complex call flows and integrations.
81
82
```typescript { .api }
83
/** Connect call to WebRTC clients, conferences, or other services */
84
connect(attributes?: ConnectAttributes): Connect;
85
86
/** Place caller in a queue for agent handling */
87
enqueue(name?: string, attributes?: EnqueueAttributes): Enqueue;
88
89
/** Leave current queue or conference */
90
leave(): Leave;
91
92
/** Process payments during the call */
93
pay(attributes?: PayAttributes): Pay;
94
95
/** Prompt for caller input with customizable settings */
96
prompt(attributes?: PromptAttributes): Prompt;
97
98
/** Refer call to another party (SIP REFER) */
99
refer(attributes?: ReferAttributes): Refer;
100
101
/** Send SMS during voice call */
102
sms(message?: string, attributes?: SmsAttributes): Sms;
103
104
/** Start call recording or stream */
105
start(attributes?: StartAttributes): Start;
106
107
/** Stop call recording or stream */
108
stop(): Stop;
109
110
/** Echo call audio back to caller */
111
echo(): Echo;
112
113
/** Add caller to named queue */
114
queue(name: string, attributes?: QueueAttributes): Queue;
115
```
116
117
### Voice Attributes and Configuration
118
119
```typescript { .api }
120
interface SayAttributes {
121
/** Voice to use for speech synthesis */
122
voice?: "man" | "woman" | "alice" | "Polly.Aditi" | "Polly.Amy" | string;
123
/** Language and accent for speech */
124
language?: "en" | "en-au" | "en-ca" | "en-gb" | "en-in" | "en-us" | string;
125
/** Number of times to repeat the message */
126
loop?: number;
127
}
128
129
interface PlayAttributes {
130
/** Number of times to play the audio */
131
loop?: number;
132
/** Digits to press to skip playback */
133
digits?: string;
134
}
135
136
interface GatherAttributes {
137
/** URL to POST collected digits */
138
action?: string;
139
/** HTTP method for action URL */
140
method?: "GET" | "POST";
141
/** Timeout in seconds for input collection */
142
timeout?: number;
143
/** Key to finish input collection */
144
finishOnKey?: string;
145
/** Maximum number of digits to collect */
146
numDigits?: number;
147
/** Minimum number of digits to collect */
148
minDigits?: number;
149
/** Maximum number of attempts */
150
maxAttempts?: number;
151
/** Text to speak while gathering input */
152
input?: "dtmf" | "speech" | "dtmf speech";
153
/** Language for speech recognition */
154
language?: string;
155
/** Hints for speech recognition */
156
hints?: string;
157
/** Profanity filter for speech */
158
profanityFilter?: boolean;
159
}
160
161
interface DialAttributes {
162
/** Caller ID to display */
163
callerId?: string;
164
/** Timeout in seconds */
165
timeout?: number;
166
/** Music to play while connecting */
167
hangupOnStar?: boolean;
168
/** Timeout music URL */
169
timeLimit?: number;
170
/** URL for call status updates */
171
action?: string;
172
/** HTTP method for action URL */
173
method?: "GET" | "POST";
174
/** Record the call */
175
record?: "do-not-record" | "record-from-answer" | "record-from-ringing";
176
/** Trim silence from recordings */
177
trim?: "trim-silence" | "do-not-trim";
178
/** Recording status callback URL */
179
recordingStatusCallback?: string;
180
/** Recording status callback method */
181
recordingStatusCallbackMethod?: "GET" | "POST";
182
}
183
184
interface RecordAttributes {
185
/** URL to POST recording details */
186
action?: string;
187
/** HTTP method for action URL */
188
method?: "GET" | "POST";
189
/** Maximum recording length in seconds */
190
timeout?: number;
191
/** Key to finish recording */
192
finishOnKey?: string;
193
/** Maximum recording duration */
194
maxLength?: number;
195
/** Play beep before recording */
196
playBeep?: boolean;
197
/** Trim silence from recording */
198
trim?: "trim-silence" | "do-not-trim";
199
/** Recording status callback URL */
200
recordingStatusCallback?: string;
201
/** Transcribe the recording */
202
transcribe?: boolean;
203
/** Transcription callback URL */
204
transcribeCallback?: string;
205
}
206
207
interface QueueAttributes {
208
/** URL to request when call leaves queue */
209
url?: string;
210
/** HTTP method for queue URL */
211
method?: "GET" | "POST";
212
/** Number of seconds to wait in queue before giving up */
213
reservationSid?: string;
214
/** Post task receipt to this URL when enqueued */
215
postWorkActivitySid?: string;
216
}
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
// Interactive Voice Response (IVR) system
223
const response = new twiml.VoiceResponse();
224
225
const gather = response.gather({
226
action: "/handle-selection",
227
numDigits: 1,
228
timeout: 10
229
});
230
231
gather.say("Press 1 for sales, 2 for support, or 0 for operator");
232
response.say("No input received. Goodbye!");
233
response.hangup();
234
235
// Call forwarding with recording
236
const response = new twiml.VoiceResponse();
237
response.say("This call will be recorded for quality purposes");
238
239
const dial = response.dial({
240
callerId: "+1234567890",
241
record: "record-from-answer",
242
action: "/call-complete"
243
});
244
dial.number("+0987654321");
245
246
// Conference call setup
247
const response = new twiml.VoiceResponse();
248
response.say("Welcome to the conference");
249
250
const dial = response.dial();
251
const conference = dial.conference("support-room", {
252
startConferenceOnEnter: true,
253
endConferenceOnExit: false,
254
waitUrl: "http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient"
255
});
256
```
257
258
### MessagingResponse
259
260
TwiML response builder for handling SMS and MMS messages.
261
262
```typescript { .api }
263
/**
264
* TwiML response builder for messaging communications
265
* Generates XML instructions for handling incoming messages
266
*/
267
class MessagingResponse {
268
constructor();
269
270
/** Generate the final TwiML XML string */
271
toString(): string;
272
273
/** Add XML comments to the response */
274
comment(comment: string): XMLElement;
275
commentBefore(comment: string): XMLElement;
276
commentAfter(comment: string): XMLElement;
277
}
278
```
279
280
### Messaging Verbs
281
282
TwiML verbs for message handling and response generation.
283
284
```typescript { .api }
285
/** Send reply message with text and optional media */
286
message(body?: string, attributes?: MessageAttributes): Message;
287
288
/** Redirect to another TwiML URL for further processing */
289
redirect(url?: string, attributes?: RedirectAttributes): Redirect;
290
```
291
292
### Messaging Attributes
293
294
```typescript { .api }
295
interface MessageAttributes {
296
/** Callback URL for message status updates */
297
action?: string;
298
/** Phone number to send message from */
299
from?: string;
300
/** HTTP method for action URL */
301
method?: "GET" | "POST";
302
/** Phone number to send message to */
303
to?: string;
304
/** Status callback URL */
305
statusCallback?: string;
306
}
307
308
interface RedirectAttributes {
309
/** HTTP method for redirect */
310
method?: "GET" | "POST";
311
}
312
```
313
314
**Usage Examples:**
315
316
```typescript
317
// Auto-reply with message
318
const response = new twiml.MessagingResponse();
319
response.message("Thanks for your message! We'll get back to you soon.");
320
321
// Forward message with media
322
const response = new twiml.MessagingResponse();
323
const message = response.message("Here's your requested information:");
324
message.media("https://example.com/document.pdf");
325
326
// Conditional response based on message content
327
const response = new twiml.MessagingResponse();
328
329
if (incomingMessage.includes("STOP")) {
330
response.message("You've been unsubscribed from notifications.");
331
} else if (incomingMessage.includes("HELP")) {
332
response.redirect("/help-menu");
333
} else {
334
response.message("Message received. Reply HELP for options or STOP to unsubscribe.");
335
}
336
```
337
338
### FaxResponse
339
340
TwiML response builder for handling incoming fax transmissions.
341
342
```typescript { .api }
343
/**
344
* TwiML response builder for fax communications
345
* Generates XML instructions for handling incoming faxes
346
*/
347
class FaxResponse {
348
constructor();
349
350
/** Generate the final TwiML XML string */
351
toString(): string;
352
353
/** Add XML comments to the response */
354
comment(comment: string): XMLElement;
355
commentBefore(comment: string): XMLElement;
356
commentAfter(comment: string): XMLElement;
357
}
358
```
359
360
### Fax Verbs
361
362
TwiML verb for fax reception and processing.
363
364
```typescript { .api }
365
/** Configure fax reception settings */
366
receive(attributes?: ReceiveAttributes): Receive;
367
```
368
369
### Fax Attributes
370
371
```typescript { .api }
372
interface ReceiveAttributes {
373
/** URL to POST fax reception status */
374
action?: string;
375
/** Media type for storing received fax */
376
mediaType?: "application/pdf" | "image/tiff";
377
/** HTTP method for action URL */
378
method?: "GET" | "POST";
379
/** Page size for fax interpretation */
380
pageSize?: "letter" | "legal" | "a4";
381
/** Whether to store fax media */
382
storeMedia?: boolean;
383
}
384
```
385
386
**Usage Examples:**
387
388
```typescript
389
// Basic fax reception
390
const response = new twiml.FaxResponse();
391
response.receive({
392
action: "/fax-received",
393
mediaType: "application/pdf",
394
storeMedia: true
395
});
396
397
// Fax with custom page size and processing
398
const response = new twiml.FaxResponse();
399
response.receive({
400
action: "/process-fax",
401
method: "POST",
402
pageSize: "legal",
403
mediaType: "image/tiff",
404
storeMedia: true
405
});
406
```
407
408
## SSML Support
409
410
VoiceResponse includes comprehensive support for Speech Synthesis Markup Language (SSML) elements for enhanced speech control.
411
412
```typescript { .api }
413
// SSML elements for advanced speech synthesis
414
class SsmlBreak {
415
constructor(attributes?: { strength?: string; time?: string });
416
}
417
418
class SsmlEmphasis {
419
constructor(attributes?: { level?: "strong" | "moderate" | "reduced" });
420
}
421
422
class SsmlLang {
423
constructor(attributes?: { xmlLang?: string });
424
}
425
426
class SsmlPhoneme {
427
constructor(attributes?: { alphabet?: string; ph?: string });
428
}
429
430
class SsmlProsody {
431
constructor(attributes?: {
432
pitch?: string;
433
rate?: string;
434
volume?: string;
435
});
436
}
437
438
class SsmlSayAs {
439
constructor(attributes?: {
440
interpretAs?: "characters" | "spell-out" | "cardinal" | "number" | "ordinal" | "digits" | "fraction" | "unit" | "date" | "time" | "telephone" | "address";
441
format?: string;
442
});
443
}
444
445
class SsmlSub {
446
constructor(attributes?: { alias?: string });
447
}
448
449
class SsmlP {
450
constructor(attributes?: object);
451
}
452
453
class SsmlS {
454
constructor(attributes?: object);
455
}
456
457
class SsmlW {
458
constructor(attributes?: object);
459
}
460
```
461
462
**Usage Examples:**
463
464
```typescript
465
// Using SSML for enhanced speech synthesis
466
const response = new twiml.VoiceResponse();
467
468
const say = response.say();
469
say.ssmlBreak({ strength: "medium" });
470
say.ssmlEmphasis({ level: "strong" }, "Important announcement:");
471
say.ssmlProsody({ rate: "slow" }, "Please listen carefully");
472
say.ssmlSayAs({ interpretAs: "telephone" }, "415-555-1212");
473
```
474
475
## Types
476
477
```typescript { .api }
478
interface XMLElement {
479
ele(name: string, attributes?: object, text?: string): XMLElement;
480
comment(comment: string): XMLElement;
481
commentBefore(comment: string): XMLElement;
482
commentAfter(comment: string): XMLElement;
483
}
484
485
abstract class TwiML {
486
protected _propertyName: string;
487
protected response: XMLElement;
488
489
/** Generate the final XML string representation */
490
toString(): string;
491
}
492
```