<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<base href="https://wiki.asterisk.org/wiki" />
<title>Message Title</title>
<style type="text/css">@media only screen and (max-device-width: 480px) {.mobile-only {
width: auto !important;
height: auto !important;
overflow: visible !important;
line-height: normal !important;
font-size: inherit !important;
mso-hide: all;
}
.desktop-only {
display: none !important;
}
/* iPhone 3GS fix for unwanted 20px right margin */
body { min-width: 100% !important; padding: 0; margin: 0; }
#center-content-table { max-width: none; !important; }
#header-pattern-container { padding: 10px 10px 10px 10px !important; line-height: 20px !important; }
#header-avatar-image-container { padding-right: 8px !important; }
#email-content-container { padding: 0 !important; }
.mobile-expand { border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; padding-left: 26px !important;}
.mobile-resize-text { font-size: 16px !important; line-height: 22px !important; }
#page-title-pattern-header { font-size: 20px !important; line-height: 28px !important; }
#page-title-pattern-icon-image-container-cell { padding-top: 7px !important; }
#inline-user-pattern { display: block !important; }
#inline-user-pattern-avatar { padding-top: 3px !important; }
.contextual-area-pattern { border-bottom: 1px solid #ccc !important; padding: 15px 10px 0 10px !important;}
.users-involved-pattern-column-table { width: 100% !important; }
.users-involved-pattern-avatar-table-cell { padding: 3px 5px 5px 0 !important; }
.users-involved-pattern-column-container { padding-right: 0 !important; }
.contextual-excerpt-pattern, #users-involved-pattern { border: 0 !important; }
/** Aui Typography upsized for mobile **/
#content-excerpt-pattern-container, #contextual-excerpt-pattern-text-container { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h1, #contextual-excerpt-pattern-text-container h1 { font-size: 24px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h2, #contextual-excerpt-pattern-text-container h2 { font-size: 20px !important; line-height: 28px !important; }
#content-excerpt-pattern-container h3, #contextual-excerpt-pattern-text-container h3 { font-size: 18px !important; line-height: 24px !important; }
#content-excerpt-pattern-container h4, #contextual-excerpt-pattern-text-container h4 { font-size: 16px !important; line-height: 22px !important; }
#content-excerpt-pattern-container h5, #contextual-excerpt-pattern-text-container h5 { font-size: 14px !important; line-height: 20px !important; }
#content-excerpt-pattern-container h6, #contextual-excerpt-pattern-text-container h6 { font-size: 14px !important; line-height: 20px !important; }
.user-mention { line-height: 18px !important; }
/** Aui Typography end **/
/* Show appropriate footer logo on mobile, display links vertically */
#footer-pattern { padding: 15px 10px !important; }
#footer-pattern-logo-desktop-container { padding: 0 !important; }
#footer-pattern-logo-desktop { width: 0 !important; height: 0 !important; }
#footer-pattern-logo-mobile {
padding-top: 10px !important;
width: 30px !important;
height: 27px !important;
display: inline !important;
}
#footer-pattern-text {
display: block !important;
}
#footer-pattern-links-container { line-height: 0 !important;}
.footer-pattern-links.mobile-resize-text,
.footer-pattern-links.mobile-resize-text,
#footer-pattern-text.mobile-resize-text,
#footer-pattern-links-container.no-footer-links {
font-size: 14px !important;
line-height: 20px !important;
}
.footer-link { display: block !important; }
#footer-pattern-links-container table { display: inline-block !important; float: none !important; }
#footer-pattern-links-container, #footer-pattern-text { text-align: center !important; }
#footer-pattern-links { padding-bottom: 5px !important; }
/** Team Calendar overrides, these should be removed when notifications are updated in Team Calendars. For now CSS
overrides are being used because the structure of the content can't change without rereleasing the plugin */
.mail-calendar-container .day-header + table tr td:first-child {
vertical-align: top !important;
padding-top: 5px !important;
}}
@media (min-width: 900px) {#center-content-table { width: 900px; }}
@media all {#outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
body{-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;}
.ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */
#background-table {margin:0; padding:0; width:100% !important; }
/* Needed to override highlighting on date and time links in iOS */
.grey a {color: #707070; text-decoration: none; }/* These styles are appended to the head element of a notification in order to prevent Apple Mail and similar
clients from underlining the due dates with a blue hyperlink */
/* a lozenge outside an inline task should always be #333, lozenges inside an inline task should be
colored according to their upcoming due dates, a completed task date lozenge or deleted task date
lozenge should always be #707070 */
.date-time-lozenge a {color: #333333; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-upcoming a {color: #DF6F00; text-decoration: none; }
.inline-task-text-container .date-time-lozenge.date-past a {color: #D04437; text-decoration: none; }
.inline-task-text-container.content-deleted-color .date-time-lozenge a,
.inline-task-text-container.checked .date-time-lozenge a {
color: #707070; text-decoration: none;
}}
</style>
</head>
<body>
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; background-color: #f5f5f5">
<tbody>
<tr>
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px">
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 9px"><a href="https://wiki.asterisk.org/wiki/display/~mmichelson?src=email" style="color: #3b73af; text-decoration: none"><img id="header-avatar-image" class="image_fix" src="cid:avatar_99ed0aa29d6f204db4785296f8170422" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /></a></td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">Mark Michelson <strong>edited</strong> a page</td>
</tr>
</tbody>
</table> </td>
</tr>
<!-- End Header pattern -->
<tr>
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px">
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; border-spacing: 0; border-collapse: separate">
<tbody>
<tr>
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px"> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff">
<table id="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td id="page-title-pattern-icon-image-container" valign="top" style="padding: 0px; border-collapse: collapse; width: 16px; vertical-align: top">
<table cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td id="page-title-pattern-icon-image-container-cell" style="padding: 0px; border-collapse: collapse; width: 16px; padding: 9px 8px 0px 0px; mso-text-raise: 5px; mso-line-height-rule: exactly"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?src=email" title="page icon" style="vertical-align: top;; color: #3b73af; text-decoration: none"><img style="vertical-align: top; display: block;" src="cid:page-icon" alt="page icon" title="page icon" height="16" width="16" border="0" /></a></td>
</tr>
</tbody>
</table> </td>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" id="page-title-pattern-header-container"><span id="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?src=email" title="Part 1: Recording" style="color: #3b73af; text-decoration: none">Part 1: Recording</a></span></td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff">
<table class="content-excerpt-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">
<tbody>
<tr>
<td class="content-excerpt-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 0 24px">
<table class="diff-macro diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/section.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Section</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse">
<table class="diff-macro" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/column.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Column</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <h1 id="Part1:Recording-TheRecordingAPI" style="margin: 10px 0 0 0; margin-top: 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0; margin-top: 0"> <span class="diff-html-changed" id="changed-diff-0" style="background-color: #d6f0ff;">The </span><span class="diff-html-added" id="added-diff-0" style="font-size: 100%; background-color: #ddfade;">Recording </span><span class="diff-html-changed" id="changed-diff-1" style="background-color: #d6f0ff;">API</span> </h1> <p style="margin: 10px 0 0 0"> <span class="confluence-link"><span class="diff-html-changed" id="changed-diff-2" style="background-color: #d6f0ff;">Recordings</span></span><span class="diff-html-changed" style="background-color: #d6f0ff;"> </span>in ARI are divided into two main categories: live and stored. Live recordings are <span class="diff-html-removed" id="removed-diff-0" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">recordings </span><span class="diff-html-added" id="added-diff-1" style="font-size: 100%; background-color: #ddfade;">those </span>that are currently being <span class="diff-html-removed" id="removed-diff-1" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">used </span><span class="diff-html-added" id="added-diff-2" style="font-size: 100%; background-color: #ddfade;">recorded </span>on a channel or bridge, and stored recordings are recordings that have been <span class="diff-html-removed" id="removed-diff-2" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">finished </span><span class="diff-html-added" id="added-diff-3" style="font-size: 100%; background-color: #ddfade;">completed </span>and <span class="diff-html-removed" id="removed-diff-3" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">stored on </span><span class="diff-html-added" id="added-diff-4" style="font-size: 100%; background-color: #ddfade;">saved to </span>the file system. The API for the <code style="font-family: monospace">/recordings</code> resource can be found <a class="confluence-link unresolved" href="#" style="color: #3b73af; text-decoration: none"><span class="diff-html-changed" id="changed-diff-3" style="background-color: #d6f0ff;">here</span></a>.</p> <p style="margin: 10px 0 0 0">Live recordings can be manipulated as they are being made, with options to manipulate the flow of audio such as muting, pausing, stopping, or canceling the recording. Stored recordings are simply files on the file system on which Asterisk is installed. The location of stored recordings is in the <code style="font-family: monospace">/recording</code> subdirectory of the configured <code style="font-family: monospace">astspooldir</code> in <code style="font-family: monospace">asterisk.conf</code>. By default, this places recordings in <code style="font-family: monospace">/var/spool/asterisk/recording</code>.</p> <p style="margin: 10px 0 0 0">Channels can have their audio recorded using the <a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Channels+REST+API#Asterisk13ChannelsRESTAPI-record" rel="nofollow" style="color: #3b73af; text-decoration: none"><code style="font-family: monospace"><span class="diff-html-changed" id="changed-diff-4" style="background-color: #d6f0ff;">/channels/{channelId}/record</span></code></a><span class="diff-html-changed" style="background-color: #d6f0ff;"> </span>resource, and Bridges can have their audio recorded using the <code style="font-family: monospace"><a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Bridges+REST+API#Asterisk13BridgesRESTAPI-record" rel="nofollow" style="color: #3b73af; text-decoration: none"><span class="diff-html-changed" id="changed-diff-5" style="background-color: #d6f0ff;">/bridges/{bridgeId}/record</span></a></code><span class="diff-html-changed" style="background-color: #d6f0ff;"> </span>resource.</p> <h1 id="Recording-RecordingVoicemails" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-removed" id="removed-diff-4" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Recording Voicemails</span> </h1> <span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Now that we have discussed the state machine in great depth, let's apply it to a very simple case. When a caller enters the application, the caller should be able to record a message</span> <h1 id="Part1:Recording-VoiceMailApplicationSkeleton" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" id="added-diff-5" style="font-size: 100%; background-color: #ddfade;">Voice Mail Application Skeleton</span> </h1> <p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Our application to record voice mails will be based on the following skeleton. As we add new features, we will create new states for our state machine, and add a few extra lines to our application skeleton in order to link the states together appropriately.</span> </p> </td>
</tr>
</tbody>
</table>
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/column.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Column</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse">
<table class="diff-macro diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">On this Page</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0"></p>
<table class="diff-macro bodyless diff-html-added" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/toc.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Table of Contents</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">maxLevel</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">2</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> <p style="margin: 10px 0 0 0"></p> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table>
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">vm-record.py</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">language</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">py</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">collapse</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">true</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">#!/usr/bin/env python
import ari
import logging
import time
import os
import sys
from event import Event
from state_machine import StateMachine
# As we add more states to our state machine, we'll import the necessary
# states here.
logging.basicConfig(level=logging.ERROR)
LOGGER = logging.getLogger(__name__)
client = ari.connect('http://localhost:8088', 'asterisk', 'asterisk')
class VoiceMailCall(object):
def __init__(self, ari_client, channel, mailbox):
self.client = ari_client
self.channel = channel
self.vm_path = os.path.join('voicemail', mailbox, str(time.time()))
self.setup_state_machine()
def setup_state_machine(self):
# This is where we will initialize states, create a state machine, add
# state transitions to the state machine, and start the state machine.
def stasis_start_cb(channel_obj, event):
channel = channel_obj['channel']
channel_name = channel.json.get('name')
mailbox = event.get('args')[0]
print("Channel {0} recording voicemail for {1}".format(
channel_name, mailbox))
channel.answer()
VoiceMailCall(client, channel, mailbox)
client.on_channel_event('StasisStart', stasis_start_cb)
client.run(apps=sys.argv[1])</span>
</pre> </td>
</tr>
</tbody>
</table>
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">vm-record.js</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">language</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">js</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">collapse</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">true</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">/*jshint node:true*/
'use strict';
var ari = require('ari-client');
var util = require('util');
var path = require('path');
var Event = require('./event');
var StateMachine = require('./state_machine');
// As we add new states to our state machine, this is where we will
// add the new required states.
ari.connect('http://localhost:8088', 'asterisk', 'asterisk', clientLoaded);
var VoiceMailCall = function(ari_client, channel, mailbox) {
this.client = ari_client;
this.channel = channel;
this.vm_path = path.join('voicemail', mailbox, Date.now().toString());
this.setup_state_machine();
}
VoiceMailCall.prototype.setup_state_machine = function() {
// This is where we will initialize states, create a state machine, add
// state transitions to the state machine, and start the state machine.
}
function clientLoaded(err, client) {
if (err) {
throw err;
}
client.on('StasisStart', stasisStart);
function stasisStart(event, channel) {
var mailbox = event.args[0]
channel.answer(function(err) {
if (err) {
throw err;
}
new VoiceMailCall(client, channel, mailbox);
});
}
client.start(process.argv[2]);
}
</span>
</pre> </td>
</tr>
</tbody>
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">With a few modifications, this same application skeleton can be adapted for use with non-voice mail applications. The biggest voice mail-specific thing being done here is the calculation of the path for voice mail recordings based on the application argument. The intended use of this application is something like the following:</span> </p>
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">[default]
exten => _3XX,1,NoOp()
same => n,Stasis(vm-record, ${EXTEN})
same => n,Hangup()</span>
</pre> </td>
</tr>
</tbody>
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">This way, when calling any three-digit extension that begins with the number '3', the user will call into the application with the mailbox dialled (e.g. dialling "305" will allow the user to leave a message for mailbox "305").</span> </p> <h1 id="Part1:Recording-BasicVoiceMailRecording" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Basic Voice Mail Recording</span> </h1> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">We've seen a lot of the underlying concepts for our application, so let's actually make something useful now. We'll start with a very simple application that allows callers to record a message upon entering the application</span><span class="diff-html-changed" id="changed-diff-6" style="background-color: #d6f0ff;">. When the caller has completed recording the message, the caller may press the '#' key or may hang up to </span> </p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-changed" style="background-color: #d6f0ff;"> </span><span class="diff-html-changed" id="changed-diff-7" style="background-color: #d6f0ff;">accept the recording. Here is a state machine diagram for the application:</span> </p> <p style="text-align: center;; margin: 10px 0 0 0" class="diff-block-target diff-block-context"></p>
<table class="diff-macro bodyless diff-html-changed" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-changed" style="background-color: #d6f0ff;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=gliffy" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Gliffy Diagram</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-changed" style="background-color: #d6f0ff;">name</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-changed" style="background-color: #d6f0ff;">record</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> <p style="margin: 10px 0 0 0"></p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-changed" style="background-color: #d6f0ff;">For this, we will be defining three states: recording, hungup, and ending. The following is the code for the three states:</span> </p>
<table class="diff-macro diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333"></table>
<table class="diff-macro diff-html-removed" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ffe7e7;border-color: #df9898;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-removed" id="removed-diff-6" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/column.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Column</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse">
<table class="diff-macro diff-html-removed" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ffe7e7;border-color: #df9898;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">title</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">On this Page</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0"></p>
<table class="diff-macro bodyless diff-html-removed" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;margin: 5px 0; padding: 0; width: auto;background-color: #ffe7e7;border-color: #df9898;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/toc.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Table of Contents</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">maxLevel</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">2</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> <p style="margin: 10px 0 0 0"></p> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> <span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<th>title</th>
<td style="padding: 0px; border-collapse: collapse">recording_state.py</td>
</tr>
<tr>
<th>language</th>
<td style="padding: 0px; border-collapse: collapse">py</td>
</tr>
<tr>
<th>collapse</th>
<td style="padding: 0px; border-collapse: collapse">true</td>
</tr>
</tbody>
</table> <pre style="margin: 10px 0 0 0">from event import Event
class RecordingState(object):
state_name = "recording"
def __init__(self, call):
self.call = call
self.hangup_event = None
self.dtmf_event = None
self.recording = None
def enter(self):
print "Entering recording state"
self.hangup_event = self.call.channel.on_event('ChannelHangupRequest',
self.on_hangup)
self.dtmf_event = self.call.channel.on_event('ChannelDtmfReceived',
self.on_dtmf)
self.recording = self.call.channel.record(name=self.call.vm_path,
format='wav',
beep=True,
ifExists='overwrite')
print "Recording voicemail at {0}".format(self.call.vm_path)
def cleanup(self):
print "Cleaning up event handlers"
self.dtmf_event.close()
self.hangup_event.close()
def on_hangup(self, channel, event):
print "Accepted recording {0} on hangup".format(self.call.vm_path)
self.cleanup()
self.call.state_machine.change_state(Event.HANGUP)
def on_dtmf(self, channel, event):
digit = event.get('digit')
if digit == '#':
rec_name = self.recording.json.get('name')
print "Accepted recording {0} on DTMF #".format(rec_name)
self.cleanup()
self.recording.stop()
self.call.state_machine.change_state(Event.DTMF_OCTOTHORPE)</pre> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p> <p class="diff-block-target" style="margin: 10px 0 0 0">When entered, the state sets up listeners for hangup and DTMF events on the channel, since those are the events that will cause the state to change. In all cases, before a state change occurs, the <code style="font-family: monospace">cleanup()</code> function is invoked to remove event listeners. This way, the event listeners set by the recording state will not accidentally still be set up when the next state is entered. <span class="diff-html-added" id="added-diff-6" style="font-size: 100%; background-color: #ddfade;">This same </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">cleanup()</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> method will be used for all states we create that set up ARI event listeners.</span> </p> <p class="diff-block-context" style="margin: 10px 0 0 0">The <code style="font-family: monospace">stop</code> method causes a live recording to finish and be saved to the file system. Notice that the <code style="font-family: monospace">on_hangup()</code> method does not attempt to stop the live recording. This is because when a channel hangs up, any live recordings on that channel are automatically stopped and stored.</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p> <p class="diff-block-target" style="margin: 10px 0 0 0">These two states are two sides to the same coin. The <code style="font-family: monospace">EndingState</code> is used to end the call by hanging up the channel, and the <code style="font-family: monospace">HungUpState</code> is used to terminate the state machine when the caller has hung up. <span class="diff-html-added" id="added-diff-7" style="font-size: 100%; background-color: #ddfade;">You may find yourself wondering why a </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">HungUpState</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> is needed at all. For our application, it does not do much, but it's a great place to perform post-call logic if your application demands it. See the second reader exercise on this page to see an example of that.</span> </p> <p class="diff-block-context" style="margin: 10px 0 0 0">Using the application skeleton we set up earlier, we can make the following modifications to accommodate our state machine:</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p>
<table class="diff-macro diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">vm-call.js</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">language</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">js</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">collapse</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">true</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">// At the top of the file
var RecordingState = require('./recording_state');
var EndingState = require('./ending_state');
var HungUpState = require('./hungup_state');
// Inside our VoiceMailCall prototype
VoiceMailCall.prototype.setup_state_machine = function() {
var hungup_state = new HungUpState(self)
var recording_state = new RecordingState(self)
var ending_state = new EndingState(self)
this.state_machine = new StateMachine()
this.state_machine.add_transition(recording_state, Event.DTMF_OCTOTHORPE, ending_state)
this.state_machine.add_transition(recording_state, Event.HANGUP, hungup_state)
this.state_machine.start(recording_state)
}</pre> </td>
</tr>
</tbody>
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-removed" id="removed-diff-7" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">We will create the following dialplan entry in </span><code style="font-family: monospace"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">extensions.conf</span></code><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> to be able to call into our voice mail recording application.</span> </p>
<table class="diff-macro diff-html-removed diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ffe7e7;border-color: #df9898;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/noformat.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>No Format</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">
<span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">[default]
exten => _3XX,1,NoOp()
same => n,Stasis(vm-record, ${EXTEN})
same => n,Hangup()</span>
</pre> </td>
</tr>
</tbody>
</table> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0"> <span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">This way, when calling any three-digit extension that begins with the number '3', the user will leave a voice mail message for the mailbox they dialled (e.g. dialling "305" will allow the user to leave a message for mailbox "305").</span> </p> <p class="diff-block-context" style="margin: 10px 0 0 0">The following is a sample output of a user calling the application and pressing the '#' key when finished recording</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p>
<table class="diff-macro diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">bgColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">silver</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleBGColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">seagreen</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">borderStyle</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">solid</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">Reader Exercise 2</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">black</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0"> <code style="font-family: monospace">EndingState</code> and <code style="font-family: monospace">HungUpState</code> don't do much of anything at the moment. States like these can be great in voice mail applications for updating the message-waiting state of mailboxes on a system. If you're feeling industrious, read the API for the <code style="font-family: monospace">/mailboxes</code> resource in ARI. Try to change <code style="font-family: monospace">HungUpState</code> and <code style="font-family: monospace">EndingState</code> to update the message-waiting status of a mailbox when a new message is left. To keep the exercise simple, for now you can assume the following:</p>
<ul style="margin: 10px 0 0 0">
<li>The number of "old" messages in a mailbox is always 0</li>
<li>Since you are more concerned with alerting the mailbox owner that there exist new messages, do not try to count the messages in the mailbox. Instead, just state that there is 1 new message.</li>
</ul> </td>
</tr>
</tbody>
</table> <h1 id="Part1:Recording-CancellingaRecording" class="diff-block-target" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-changed" id="changed-diff-8" style="background-color: #d6f0ff;">Cancelling a Recording</span> </h1> <p class="diff-block-context" style="margin: 10px 0 0 0">Now we have a simple application set up to record a message, but it's pretty bare at the moment. Let's start expanding some. One feature we can add is the ability to press a DTMF key while recording a voice mail to cancel the current recording and re-start the recording process. We'll use the DTMF '*' key to accomplish this. The updated state machine diagram looks like the following:</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p>
<table class="diff-macro diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">bgColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">silver</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleBGColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">seagreen</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">borderStyle</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">solid</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">Reader Exercise 3</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">black</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">We have covered the <code style="font-family: monospace">stop()</code> and <code style="font-family: monospace">cancel()</code> methods, but live recordings provide other methods as well. In particular, there are <code style="font-family: monospace">pause()</code>, which causes the live recording to temporarily stop recording audio, and <code style="font-family: monospace">unpause()</code>, which causes the live recording to resume recording audio.</p> <p style="margin: 10px 0 0 0"> <span class="diff-html-removed" id="removed-diff-8" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">Modify </span><code style="font-family: monospace"><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">RecordingState::on_dtmf()</span></code><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span><span class="diff-html-added" id="added-diff-8" style="font-size: 100%; background-color: #ddfade;">Modify the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">RecordingState</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> </span>to allow <span class="diff-html-removed" id="removed-diff-9" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">the DTMF '5' key </span><span class="diff-html-added" id="added-diff-9" style="font-size: 100%; background-color: #ddfade;">a DTMF digit of your choice </span>to toggle pausing and unpausing the live recording.</p> </td>
</tr>
</tbody>
</table>
<table class="diff-macro diff-html-added diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;background-color: #ddfade;border-color: #93c49f;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="diff-html-added" id="added-diff-10" style="font-size: 100%; background-color: #ddfade;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">bgColor</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">silver</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">titleBGColor</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">seagreen</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">borderStyle</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">solid</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">title</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Reader Exercise 4</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">titleColor</span></td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">black</span></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Our application provides the ability to cancel recordings and re-record them, but it gives no ability to cancel the recording and end the call.</span> </p> <p style="margin: 10px 0 0 0"> <span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">Modify the </span><code style="font-family: monospace"><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;">RecordingState</span></code><span class="diff-html-added" style="font-size: 100%; background-color: #ddfade;"> to allow for a DTMF digit of your choice to cancel the recording and end the call.</span> </p> </td>
</tr>
</tbody>
</table> <h1 id="Part1:Recording-OperatingonStoredRecordings" class="diff-block-target diff-block-context" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-changed" id="changed-diff-9" style="background-color: #d6f0ff;">Operating on Stored Recordings</span> </h1> <p class="diff-block-context" style="margin: 10px 0 0 0">So far, we've recorded a channel, stopped a live recording, and cancelled a live recording. Now let's turn our attention to operations that can be performed on stored recordings. An obvious operation to start with is to play back the stored recording. We're going to make another modification to our voice mail recording application that adds a "reviewing" state after a voicemail is recorded. In this state, a user that has recorded a voice mail will hear the recorded message played back to him/her. The user may press the '#' key or hang up in order to accept the recorded message, or the user may press '*' to erase the stored recording and record a new message in its place. Below is the updated state diagram with the new "reviewing" state added.</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p>
<table class="diff-macro diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/plugins/servlet/confluence/placeholder/macro-icon?name=code" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Code Block</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">reviewing_state.js</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">language</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">js</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">collapse</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">true</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <pre style="margin: 10px 0 0 0; margin-top: 0">var Event = require('./event');
function ReviewingState(call) {
this.state_name = "reviewing";
this.call = call;
}
ReviewingState.prototype.enter = function() {
var self = this;
var playback = self.call.client.Playback();
var url = "recording:" + self.call.vm_path;
console.log("Entering reviewing state");
self.call.channel.on("ChannelHangupRequest", on_hangup);
self.call.channel.on("ChannelDtmfReceived", on_dtmf);
self.call.client.on("PlaybackFinished", on_playback_finished);
self.call.channel.play({media: url}, playback);
function cleanup() {
self.call.channel.removeListener('ChannelHangupRequest', on_hangup);
self.call.channel.removeListener('ChannelDtmfReceived', on_dtmf);
self.call.client.removeListener('PlaybackFinished', on_playback_finished);
if (playback) {
playback.stop();
}
}
function on_hangup(event, channel) {
console.log("Accepted recording %s on hangup", self.call.vm_path);
playback = null;
cleanup();
self.call.state_machine.change_state(Event.HANGUP);
}
function on_playback_finished(event) {
if (playback && (playback.id === event.playback.id)) {
playback = null;
}
}
function on_dtmf(event, channel) {
switch (event.digit) {
case '#':
console.log("Accepted recording", self.call.vm_path);
cleanup();
self.call.state_machine.change_state(Event.DTMF_OCTOTHORPE);
break;
case '*':
console.log("Canceling recording", self.call.vm_path);
cleanup();
self.call.client.recordings.deleteStored({recordingName: self.call.vm_path});
self.call.state_machine.change_state(Event.DTMF_STAR);
break;
}
}
}
module.exports = ReviewingState;</pre> </td>
</tr>
</tbody>
</table> <p class="diff-block-target" style="margin: 10px 0 0 0"> <span class="diff-html-removed" id="removed-diff-10" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span> </p> <p class="diff-block-target diff-block-context" style="margin: 10px 0 0 0">The code for this state is similar to the code from <code style="font-family: monospace">RecordingState</code>. The big difference is that instead of recording a message, it is playing back a stored recording. Stored recordings can be played using the channel's <a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Channels+REST+API#Asterisk13ChannelsRESTAPI-play" rel="nofollow" style="color: #3b73af; text-decoration: none"><code style="font-family: monospace"><span class="diff-html-changed" id="changed-diff-10" style="background-color: #d6f0ff;">play()</span></code></a><span class="diff-html-changed" style="background-color: #d6f0ff;"> </span>method (or as we have used in the python code, <code style="font-family: monospace">playWithId()</code>). If the URI of the media to be played is prefixed with the "recording:" scheme, then Asterisk knows to search for the specified file where recordings are stored. More information on playing back files on channels, as well as a detailed list of media URI schemes can be found <a class="confluence-link unresolved" href="#" style="color: #3b73af; text-decoration: none"><span class="diff-html-changed" id="changed-diff-11" style="background-color: #d6f0ff;">here</span></a>. Note the method that is called when a DTMF '*' is received. The <code style="font-family: monospace">deleteStored()</code> method can be used on the <code style="font-family: monospace">/recordings</code> resource of the ARI client to delete a stored recording from the file system on which Asterisk is running.</p> <p class="diff-block-target" style="margin: 10px 0 0 0">One more thing to point out is the code that runs in <code style="font-family: monospace">on_playback_finished()</code>. When reviewing a voicemail recording, the message may finish playing back before the user decides what to do with it. If this happens, we detect that the playback has finished so that we do not attempt to stop <span class="diff-html-removed" id="removed-diff-11" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">it </span><span class="diff-html-added" id="added-diff-11" style="font-size: 100%; background-color: #ddfade;">an already-finished playback </span>once the user <span class="diff-html-removed" id="removed-diff-12" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">does decide what to do</span><span class="diff-html-added" id="added-diff-12" style="font-size: 100%; background-color: #ddfade;">decides how to proceed</span>.</p> <p class="diff-block-context" style="margin: 10px 0 0 0">We need to get this new state added into our state machine, so we make the following modifications to our code to allow for the new state to be added:</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p>
<table class="diff-macro diff-block-target diff-block-context" style="background-color: #f0f0f0;border: 1px solid #dddddd;margin: 10px 1px;padding: 0 2px 2px;width: 100%;; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<thead>
<tr>
<th class="diff-macro-title" style="background-color: transparent; text-align: left; font-weight: normal;padding: 5px;"><span class="icon macro-placeholder-icon" style="background-color: ;line-height: 20px;"><img src="https://wiki.asterisk.org/wiki/s/en_GB/5635/60fd2eb45debbf4ede2b669f4c9b96b4ce40a937.48/_/images/icons/macrobrowser/dropdown/panel.png" style="padding-right: 5px; vertical-align: text-bottom;" /> </span>Panel</th>
</tr>
</thead>
<tbody>
<tr>
<td class="diff-macro-properties" style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;padding: 0; border: 1px solid #dddddd;; padding: 0px; border-collapse: collapse">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">bgColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">silver</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleBGColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">seagreen</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">borderStyle</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">solid</td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">title</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">Reader Exercise <span class="diff-html-removed" id="removed-diff-13" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">4</span><span class="diff-html-added" id="added-diff-13" style="font-size: 100%; background-color: #ddfade;">5</span></td>
</tr>
<tr>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">titleColor</td>
<td style="background-color: #fafafa; padding: 0 0 0 5px; font-size: 12px; text-align: left;; padding: 0px; border-collapse: collapse">black</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
<tbody>
<tr>
<td class="diff-macro-body" style="background-color: #fff;border: 1px solid #dddddd;padding: 10px;; padding: 0px; border-collapse: collapse"> <p style="margin: 10px 0 0 0; margin-top: 0">In the previous section we introduced the ability to delete a stored recording. Stored recordings have a second operation available to them: <a href="https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Recordings+REST+API#Asterisk13RecordingsRESTAPI-copyStored" rel="nofollow" style="color: #3b73af; text-decoration: none"><span class="diff-html-changed" id="changed-diff-12" style="background-color: #d6f0ff;">copying</span></a>. The <code style="font-family: monospace">copy()</code> method of a stored recording can be used to copy the stored recording from one location to another.</p> <p style="margin: 10px 0 0 0">For this exercise modify <code style="font-family: monospace">ReviewingState<span class="diff-html-removed" id="removed-diff-14" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">::on_dtmf()</span></code><span class="diff-html-removed" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;"> </span>to let a DTMF key of your choice copy the message to a different mailbox on the system. When a user presses this DTMF key, the state machine should transition into a new state called "copying." The "copying" state should gather DTMF from the user to determine which mailbox the message should be copied to. If '#' is entered, then the message is sent to the mailbox the user has typed in. If '*' is entered, then the copying operation is <span class="diff-html-removed" id="removed-diff-15" style="font-size: 100%; background-color: #ffe7e7; text-decoration: line-through;">canceled</span><span class="diff-html-added" id="added-diff-14" style="font-size: 100%; background-color: #ddfade;">cancelled</span>. Both a '#' and a '*' should cause the state machine to transition back into <code style="font-family: monospace">ReviewingState</code>.</p> <p style="margin: 10px 0 0 0">As an example, let's say that you have set DTMF '0' to be the key that the user presses in <code style="font-family: monospace">ReviewingState</code> to copy the message. The user presses '0'. The user then presses '3' '2' '0' '#'. The message should be copied to mailbox "320", and the user should start hearing the message played back again. Now let's say the user presses '0' to copy the message again. The user then presses '3' '2' '1' '0' '*'. The message should not be copied to any mailbox, and the user should start hearing the message played back again.</p> </td>
</tr>
</tbody>
</table> <h1 id="Part1:Recording-RecordingBridges" class="diff-block-target" style="margin: 10px 0 0 0; font-size: 24px; font-weight: normal; line-height: 30px; margin: 40px 0 0 0"> <span class="diff-html-changed" id="changed-diff-13" style="background-color: #d6f0ff;">Recording Bridges</span> </h1> <p class="diff-block-context" style="margin: 10px 0 0 0">This discussion of recordings has focused on recording channel audio. It's important to note that bridges also have an option to be recorded. What's the difference? Recording a channel's audio records only the audio coming <strong>from</strong> a channel. Recording a bridge records the mixed audio coming from all channels into the bridge. This means that if you are attempting to do something like record a conversation between participants in a phone call, you would want to record the audio in the bridge rather than on either of the channels involved.</p> <p class="diff-context-placeholder" style="margin: 10px 0 0 0">...</p> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand action-padding last-row-padding" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 15px 16px; background-color: #fff; padding-bottom: 10px; padding-bottom: 10px">
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">
<tbody>
<tr>
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 15px 0 0 24px; vertical-align: middle">
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?src=email" title="View page Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="View page Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aview-page-email-adg-footer-item%3Aicon" alt="View page Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?src=email" title="View page" style="color: #3b73af; text-decoration: none">View page</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td>
</tr>
</tbody>
</table>
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Add comment Icon" src="cid:com.atlassian.confluence.plugins.confluence-email-resources%3Aadd-comment-to-content-email-adg-footer-item%3Aicon" alt="Add comment Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/display/AST/Part+1%3A+Recording?showComments=true&showCommentArea=true&src=email#addcomment" title="Add comment" style="color: #3b73af; text-decoration: none">Add comment</a></td>
<td class="actions-pattern-action-bull" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; color: #999; padding: 0 5px">•</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30277826&src=email" title="Like Icon" style="color: #3b73af; text-decoration: none"><img class="actions-pattern-action-icon-image" height="16" width="16" border="0" title="Like Icon" src="cid:com.atlassian.confluence.plugins.confluence-like%3Aview-email-adg-content-item%3Aicon" alt="Like Icon" style="vertical-align: middle" /></a></td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px; white-space: nowrap"><a href="https://wiki.asterisk.org/wiki/plugins/likes/like.action?contentId=30277826&src=email" title="Like" style="color: #3b73af; text-decoration: none">Like</a></td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; height: 5px; line-height: 5px; padding: 0 15px 0 16px; background-color: #fff; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; mso-line-height-rule: exactly"> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px">
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333">
<tbody>
<tr>
<td id="footer-pattern-links-container" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px">
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px">
<tbody>
<tr>
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=AST&src=email" title="" style="color: #3b73af; text-decoration: none">Stop watching space</a></td>
<td class="footer-pattern-links-bull" style="padding: 0px; border-collapse: collapse; padding: 0 5px; color: #999">•</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px">
<tbody>
<tr>
<td class="footer-pattern-links mobile-resize-text" style="padding: 0px; border-collapse: collapse"><a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action?src=email" title="" style="color: #3b73af; text-decoration: none">Manage notifications</a></td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px; display: none">This message was sent by Atlassian Confluence 5.6.1</td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table>
<table id="sealed-section" border="0" cellpadding="0" cellspacing="0" width="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; color: #333; display: none">
<tbody>
<tr>
<td style="padding: 0px; border-collapse: collapse; border: 0; font-size: 0px; line-height: 0; mso-line-height-rule: exactly"></td>
</tr>
</tbody>
</table>
</body>
</html>