1WWW::Twilio::TwiML(3) User Contributed Perl DocumentationWWW::Twilio::TwiML(3)
2
3
4
6 WWW::Twilio::TwiML - Light and fast TwiML generator
7
9 use WWW::Twilio::TwiML;
10
11 my $t = new WWW::Twilio::TwiML;
12 $t->Response->Dial("+1234567890");
13 print $t->to_string;
14
16 WWW::Twilio::TwiML creates Twilio-compatible TwiML documents. Documents
17 can be built by creating and nesting one element at a time or by
18 chaining objects. Elements can contain attributes, text content, or
19 other elements.
20
21 TwiML, being XML, could be trivially generated with XML::LibXML or any
22 number of other XML parsers/generators. Philosophically,
23 WWW::Twilio::TwiML represents an economical TwiML generator. It has a
24 small footprint (TwiML documents are typically small and simple) and
25 means to make TwiML creation straightforward and moderately fun.
26
27 WWW::Twilio::TwiML's primary aim is for economy of expression.
28 Therefore, Any method you call on a TwiML object (except those
29 described below) will create new TwiML objects by the name of the
30 method you called. By chaining method calls, you can create robust
31 TwiML documents with very little code.
32
33 new( key => value, ... )
34 Creates a new TwiML object. With no arguments, this will create a root
35 for your TwiML document. You can also call new with name, content, or
36 attributes arguments to create unattached elements.
37
38 The following examples all create the this TwiML document using
39 different calling styles:
40
41 <?xml version="1.0" encoding="UTF-8" ?>
42 <Response>
43 <Say voice="man">Kilroy was here</Say>
44 </Response>
45
46 The upside-down, piecemeal, verbose way:
47
48 my $say = new WWW::Twilio::TwiML;
49 $say->name('Say');
50 $say->content("Kilroy was here");
51 $say->attributes({voice => "man"});
52
53 my $resp = new WWW::Twilio::TwiML;
54 $resp->name('Response');
55 $resp->content($say);
56
57 my $tw = new WWW::Twilio::TwiML;
58 $tw->content($resp);
59 print $tw->to_string;
60
61 The same thing, with a little more powerful constructor:
62
63 my $say = new WWW::Twilio::TwiML(name => 'Say',
64 content => "Kilroy was here",
65 attributes => {voice => "man"});
66
67 my $tw = new WWW::Twilio::TwiML;
68 $tw->Response->add_child($say);
69 print $tw->to_string;
70
71 The concise way:
72
73 my $tw = new WWW::Twilio::TwiML;
74 $tw->Response->Say({voice => "man"}, "Kilroy was here");
75 print $tw->to_string;
76
77 And the obligatory one-liner (spread across 4 lines for readability):
78
79 print WWW::Twilio::TwiML->new
80 ->Response
81 ->Say({voice => "man"}, "Kilroy was here")
82 ->root->to_string;
83
84 What you don't see in the latter two examples is that both Response and
85 Say create and return objects with the names Response and Say
86 respectively. When called in this way, methods can chain, making for
87 compact, yet readable expressions.
88
89 Any TwiML Verb( string | { attributes } )
90 Constructor shortcuts. TwiML verbs are described at
91 <http://www.twilio.com/docs/api/twiml>. Some examples include Response,
92 Say, Play, Gather, Record, Sms, Dial, Number, Client, Conference,
93 Hangup, Redirect, Reject, and Pause (this list may be out of date with
94 respect to the official documentation).
95
96 See Twilio's documentation for usage for these and other TwiML verbs.
97
98 The (any TwiML verb) shortcut is a constructor of a TwiML object. When
99 you call (any TwiML verb) on an existing TwiML object, the following
100 occurs:
101
102 · A new object is created and named by the method you called. E.g.,
103 if you called:
104
105 $tw->Response;
106
107 a TwiML object named 'Response' will be created.
108
109 · The newly created object is attached to its parent (the object
110 called to create it).
111
112 · The parent object has the new object added to its list of children.
113
114 These last two items means the objects are "chained" to each other.
115 Chaining objects allows concise expressions to create TwiML documents.
116 We could add another object to the chain:
117
118 $tw->Response
119 ->Say("I'm calling you.")
120 ->parent
121 ->Dial("+17175558309");
122
123 The parent method returns the Say object's parent (Response object),
124 and we chain a Dial object from it. The resulting $tw object returns:
125
126 <?xml version="1.0" encoding="UTF-8" ?>
127 <Response>
128 <Say>I'm calling you.</Say>
129 <Dial>+17175558309</Dial>
130 </Response>
131
132 name( string )
133 Gives a name to an element. This is what is used when the element is
134 printed out. If you're generally chaining objects, you won't use this
135 method often.
136
137 $elem->name('Dial');
138 $elem->content("+1234567890");
139
140 becomes:
141
142 <Dial>+1234567890</Dial>
143
144 When no string is supplied, the name of the object is returned.
145
146 print $elem->name . "\n";
147
148 The element name may also be given with new or is implicit when you
149 call the constructor by the name of the element you want to create.
150
151 content( string | object )
152 Sets the content of an element. A TwiML object's content can be either
153 a string or a listref of objects, but not both. If the argument is
154 another WWW::Twilio::TwiML object, the content of the element (if any)
155 will be replaced with the object. Any other argument will be considered
156 string content.
157
158 my $say = new WWW::Twilio::TwiML(name => 'Say');
159 $say->content("Eat at Joe's!"); ## a string as content
160
161 becomes:
162
163 <Say>Eat at Joe's!</Say>
164
165 Now we can add $say to another element:
166
167 my $parent = new WWW::Twilio::TwiML(name => 'Response');
168 $parent->content($say); ## an object as content
169
170 which becomes:
171
172 <Response>
173 <Say>Eat at Joe's!</Say>
174 </Response>
175
176 When no argument is supplied, the existing contents are returned.
177
178 my $content = $elem->content;
179 if( ref($content) ) {
180 for my $obj ( @$content ) {
181 ## do something with each $obj
182 }
183 }
184
185 else {
186 print $content . "\n"; ## assuming a string here
187 }
188
189 add_child( object )
190 Adds an element to the content of the TwiML object. Returns a reference
191 to the added object. Unlike content, add_child does not replace the
192 existing content, but appends an object to the existing content. Also
193 unlike content, add_child is not appropriate to use for setting text
194 content of an element.
195
196 my $tw = new WWW::Twilio::TwiML;
197 my $resp = $tw->Response;
198 $resp->add_child(new WWW::Twilio::TwiML(name => 'Say',
199 content => 'Soooey!'));
200
201 my $email = uri_escape('biff@example.com');
202 my $msg = uri_escape("Heeer piiiig!");
203 my $url = "http://twimlets.com/voicemail?Email=$email&Message=$msg";
204 $resp->add_child(new WWW::Twilio::TwiML(name => 'Redirect',
205 content => $url));
206
207 print $tw->to_string({'Content-type' => 'text/xml'});
208
209 becomes:
210
211 Content-type: text/xml
212
213 <?xml version="1.0" encoding="UTF-8" ?>
214 <Response>
215 <Say>Soooey!</Say>
216 <Redirect>http://twimlets.com/voicemail?Email=\
217 biff%40example.com&Message=Heeer%20piiiig!</Redirect>
218 </Response>
219
220 attributes({ key => value })
221 Sets attributes for an element. If a hash reference is not supplied, a
222 hashref of the existing attributes is returned.
223
224 my $elem = new WWW::Twilio::TwiML(name => 'Say');
225 $elem->attributes({voice => 'woman'});
226 $elem->content("gimme another donut");
227
228 becomes:
229
230 <Say voice="woman">gimme another donut</Say>
231
232 root
233 Returns a handle to the root object.
234
235 print WWW::Twilio::TwiML->new
236 ->Response
237 ->Say("All men are brothers,")
238 ->parent
239 ->Say("Like Jacob and Esau.")
240 ->root->to_string;
241
242 prints:
243
244 <?xml version="1.0" encoding="UTF-8" ?>
245 <Response>
246 <Say>All men are brothers,</Say>
247 <Say>Like Jacob and Esau.</Say>
248 </Response>
249
250 root is a convenient way to get a handle to the root TwiML object when
251 you're ready to print.
252
253 to_string( { header => value } )
254 Returns the object as a string. Unnamed (root) elements will include
255 the XML declaration entity. If a hashref is supplied, those will be
256 emitted as RFC 822 headers followed by a blank line.
257
258 Example:
259
260 print WWW::Twilio::TwiML->new->to_string;
261
262 prints:
263
264 <?xml version="1.0" encoding="UTF-8" ?>
265
266 while this:
267
268 print WWW::Twilio::TwiML->new
269 ->Response
270 ->Say("plugh")
271 ->root->to_string;
272
273 prints:
274
275 <?xml version="1.0" encoding="UTF-8" ?>
276 <Response>
277 <Say>plugh</Say>
278 </Response>
279
280 If we forget the call to root in the previous example, like this:
281
282 print WWW::Twilio::TwiML->new
283 ->Response
284 ->Say("plugh")
285 ->to_string;
286
287 we get:
288
289 <Say>plugh</Say>
290
291 because to_string is being applied to the object created by Say, not
292 $tw.
293
294 By specifying a hashref, you can add RFC 822 headers to your documents:
295
296 $tw = new WWW::Twilio::TwiML;
297 $tw->Response->Say('Arf!');
298 $tw->to_string({'Content-type' => 'text/xml'});
299
300 which returns:
301
302 Content-type: text/xml
303
304 <?xml version="1.0" encoding="UTF-8" ?>
305 <Response>
306 <Say>Arf!</Say>
307 </Response>
308
309 parent( object )
310 Sets the parent of the object; this done automatically by add_child and
311 content. When no arguments are given, the existing parent object is
312 returned.
313
314 Because WWW::Twilio::TwiML objects chain, parent is useful for getting
315 the previous object so you can add more content to it:
316
317 WWW::Twilio::TwiML->new
318 ->Response
319 ->Gather({action => "/process_gather.cgi", method => "GET"})
320 ->Say("Please enter your account number.")
321 ->parent ## Say's parent, Gather
322 ->parent ## Gather's parent, Response
323 ->Say("We didn't receive any input. Goodbye!");
324
325 becomes:
326
327 <Response>
328 <Gather action="/process_gather.cgi" method="GET">
329 <Say>Please enter your account number.</Say>
330 </Gather>
331 <Say>We didn't receive any input. Goodbye!</Say>
332 </Response>
333
334 A note on readability: the author recommends indenting multi-line
335 chains to show the parent-child relationship. Each time parent is
336 invoked, the next line should be outdented, as illustrated above.
337
339 You may control the behavior of WWW::Twilio::TwiML in several ways by
340 setting package variables described in this section.
341
342 Newlines
343 You may change the default newline from "\n" to anything else by
344 setting the $NL package variable:
345
346 local $WWW::Twilio::TwiML::NL = "\r\n";
347
348 Strict mode
349 WWW:Twilio::TwiML is capable of generating well-formed but invalid
350 TwiML documents. WWW::Twilio::TwiML uses autoloaded methods to
351 determine the name of TwiML elements (Response, Say, Dial, Redirect,
352 etc.); this means that if you specify an incorrectly named method, your
353 TwiML will be incorrect:
354
355 $tw->Response->Saay('plugh');
356
357 Saay is not a valid Twilio TwiML tag and you will not know it until
358 Twilio's TwiML parser attempts to handle your TwiML document.
359
360 You may enable strict checks on the TwiML elements at runtime by
361 setting two package variables:
362
363 $STRICT
364 When true, WWW::Twilio::TwiML's autoloader will look up the
365 unhandled method call in the %TAGS package variable (below). If the
366 method name is not in that hash, the autoloader will die with an
367 "Undefined subroutine" error.
368
369 %TAGS
370 Empty by default. When $STRICT is true, this hash will be consulted
371 to determine whether a method call is a valid TwiML tag or not.
372
373 For example:
374
375 local $WWW::Twilio::TwiML::STRICT = 1;
376 local %WWW::Twilio::TwiML::TAGS = (Response => 1, Say => 1, Dial => 1);
377
378 Now any methods invoked on WWW::Twilio::TwiML objects that are not
379 Response, Say, or Dial will die with an error. E.g.:
380
381 WWW::Twilio::TwiML->Response->Saay("Let's play Twister!");
382
383 generates the following fatal error:
384
385 Undefined subroutine Saay at line 1.
386
387 You may wish to use the fast hash creation with hash slices (I learned
388 this syntax from Damian Conway at a conference some years ago--it's
389 faster than map over an array for building hashes):
390
391 ## TwiML verbs taken from http://www.twilio.com/docs/api/twiml
392 my @tags = qw(Response Say Play Gather Record Sms Dial Number
393 Client Conference Hangup Redirect Reject Pause);
394
395 local @WWW::Twilio::TwiML::TAGS{@tags} = (1) x @tags;
396 local $WWW::Twilio::TwiML::STRICT = 1;
397
398 ## all method calls in this scope are now strict
399 ...
400
402 This section demonstrates a few things you can do with
403 WWW::Twilio::TwiML.
404
405 Example 1
406 $t = new WWW::Twilio::TwiML;
407 $t->Response->Say({voice => "woman"}, "This is Jenny");
408 print $t->to_string({'Content-type' => 'text/xml'});
409
410 Output:
411
412 Content-type: text/xml
413
414 <?xml version="1.0" encoding="UTF-8" ?>
415 <Response>
416 <Say voice="woman">This is Jenny</Say>
417 </Response>
418
419 Examples from twilio.com
420 The following examples are from twilio.com's TwiML documentation,
421 listed by the primary verb they implement. Assume a TwiML object $tw
422 for each of these examples has already been created:
423
424 my $tw = new WWW::Twilio::TwiML;
425
426 and consequently each example would be printed with:
427
428 print $tw->to_string;
429
430 See the t/twilio.t test file distributed with this package for
431 additional context for these examples.
432
433 Say
434 $tw->Response
435 ->Say({voice => "woman", loop => "2"}, "Hello");
436
437 Play
438 $tw->Response
439 ->Play("http://foo.com/cowbell.mp3");
440
441 Gather
442 $tw->Response
443 ->Gather({action => "/process_gather.cgi", method => "GET"})
444 ->Say("Enter something, or not")
445 ->parent
446 ->parent
447 ->Redirect({method => "GET"}, "/process_gather.cgi?Digits=TIMEOUT");
448
449 Record
450 $tw->Response
451 ->Say("Please leave a message at the beep. \
452 Press the star key when finished.")
453 ->parent
454 ->Record({action => "http://foo.edu/handleRecording.cgi",
455 method => "GET",
456 maxLength => "20",
457 finishOnKey => "*"});
458 ->parent
459 ->Say("I did not receive a recording");
460
461 Sms
462 $tw->Response
463 ->Say("Our store is located at 123 East St.")
464 ->parent
465 ->Sms({action => "/smsHandler.cgi", method => "POST"},
466 "Store location: 123 East St.");
467
468 Dial
469 $tw->Response
470 ->Dial
471 ->Number("858-987-6543")->parent
472 ->Number("415-123-4567")->parent
473 ->Number("619-765-4321");
474
475 Conference
476 $tw->Response
477 ->Dial
478 ->Conference({startConferenceOnEnter => "true",
479 endConferenceOnExit => "true"},
480 "1234");
481
482 Hangup
483 $tw->Response->Hangup;
484
485 Redirect
486 $tw->Response
487 ->Dial("415-123-4567")->parent
488 ->Redirect("http://www.foo.com/nextInstructions");
489
490 Reject
491 $tw->Response
492 ->Reject({reason => "busy"});
493
494 Pause
495 $tw->Response
496 ->Pause({length => 5})->parent
497 ->Say("Hi there.");
498
499 Other examples
500 Other examples may be found in the t directory that came with this
501 package, also available on CPAN.
502
504 WWW::Twilio::TwiML will likely be forward compatible with all future
505 revisions of Twilio's TwiML language. This is because method calls are
506 constructors which generate TwiML objects on the fly.
507
508 For example, say Twilio began to support a Belch verb (if only!), we
509 could take advantage of it immediately by simply calling a Belch method
510 like this:
511
512 my $tw = new WWW::Twilio::TwiML;
513 $tw->Response->Belch('Braaaaaap!');
514 print $tw->to_string;
515
516 Because there is no Belch method, WWW::Twilio::TwiML assumes you want
517 to create a node by that name and makes one for you:
518
519 <?xml version="1.0" encoding="UTF-8" ?>
520 <Response>
521 <Belch>Braaaaaap!</Belch>
522 </Response>
523
524 If the $STRICT package variable is enabled, all we need to do is add
525 Belch to our %TAGS hash and we're good to go.
526
528 WWW::Twilio::API
529
531 Scott Wiersdorf, <scott@perlcode.org>
532
534 Copyright (C) 2011 by Scott Wiersdorf
535
536 This library is free software; you can redistribute it and/or modify it
537 under the same terms as Perl itself, either Perl version 5.8.1 or, at
538 your option, any later version of Perl 5 you may have available.
539
540
541
542perl v5.32.0 2020-07-28 WWW::Twilio::TwiML(3)