Informizely customer feedback surveys
By using the Aculab site, you agree with our use of cookies.

voicemail Sample

An inbound application that handles answered inbound calls and offers the choice of recording a message or playing existing messages. An identity number is used to prevent unauthorised access to recorded messages. The recorded messages can be repeated, deleted or saved for later.

Uses actions: Run Menu, Play, Get Number, Redirect, Record, Delete File

    • {
          "actions" :
          [
              {
                  "run_menu" :
                  {
                      "prompt" :
                      {
                          "play" :
                          {
                              "play_list" :
                              [
                                  {
                                      "text_to_say" : "Press 1 to leave a message. Press 2 to listen to all messages."
                                  }
                              ]
                          }
                      },
                      "menu_options" :
                      [
                          {
                              "digit" : "1",
                              "next_page" :
                              {
                                  "url" : "RecordMessage"
                              }
                          },
                          {
                              "digit" : "2",
                              "next_page" :
                              {
                                  "url" : "GetPasswordNumber"
                              }
                          }
                      ]
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "-1",
          "api_version": "2.0"
      }
      
      
      
      
    • {
          "actions" :
          [
              {
                  "get_number":
                  {
                      "prompt" :
                      {
                          "play" :
                          {
                              "play_list" :
                              [
                                  {
                                      "text_to_say" : "Please enter your password number followed by the hash key."
                                  }
                              ]
                          }
                      },
                      "end_digit" : "#",
                      "next_page" :
                      {
                          "url" : "CheckPasswordNumber"
                      }
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "0",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "redirect" :
                  {
                      "next_page" :
                      {
                          "url" : "PlayMessage"
                      }
                  }
              }
          ],
          "token" : "0",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Sorry, that password is not correct. Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "0",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "file_to_play" : "<message file name>"
                          }
                      ]
                  }
              },
              {
                  "run_menu" :
                  {
                      "prompt" :
                      {
                          "play" :
                          {
                              "play_list" :
                              [
                                  {
                                      "text_to_say" : "Press 1 to hear the message again. Press 2 to delete it, or press 3 to save it."
                                  }
                              ]
                          }
                      },
                      "menu_options" :
                      [
                          {
                              "digit" : "1",
                              "next_page" :
                              {
                                  "url" : "MessageReplay"
                              }
                          },
                          {
                              "digit" : "2",
                              "next_page" :
                              {
                                  "url" : "MessageDelete"
                              }
                          },
                          {
                              "digit" : "3",
                              "next_page" :
                              {
                                  "url" : "MessageKeep"
                              }
                          }
                      ]
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "0",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "End of messages. Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Playing the message again."
                          }
                      ]
                  }
              },
              {
                  "redirect" :
                  {
                      "next_page" :
                      {
                          "url" : "PlayMessage"
                      }
                  }
              }
          ],
          "token" : "0",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "delete_file" :
                  {
                      "filename" : "/2014/08/12/12_30_01_04f01fb92e8913a8.65433.wav"
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Message deleted."
                          },
                          {
                              "text_to_say" : "Next message."
                          }
                      ]
                  }
              },
              {
                  "redirect" :
                  {
                      "next_page" :
                      {
                          "url" : "PlayMessage"
                      }
                  }
              }
          ],
          "token" : "1",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "delete_file" :
                  {
                      "filename" : "/2013/08/12/12_30_01_04f01fb92e8913a8.65433.wav"
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Message deleted."
                          }
                      ]
                  }
              },
              {
                  "redirect" :
                  {
                      "next_page" :
                      {
                          "url" : "PlayMessage"
                      }
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Message saved."
                          }
                      ]
                  }
              },
              {
                  "play" :
                  {
                      "play_list":
                      [
                          {
                              "text_to_say" : "Next message."
                          }
                      ]
                  }
              },
              {
                  "redirect" :
                  {
                      "next_page" :
                      {
                          "url" : "PlayMessage"
                      }
                  }
              }
          ],
          "token" : "1",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Message saved."
                          }
                      ]
                  }
              },
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "End of messages. Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Please leave a message after the beep. Press hash to end the recording or press star to cancel."
                          }
                      ]
                  }
              },
              {
                  "record" :
                  {
                      "beep_on_start" : true,
                      "milliseconds_max_silence" : 5000,
                      "barge_in_digits" : "#*",
                      "next_page" :
                      {
                          "url" : "RecordComplete"
                      }
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Thanks for leaving a message. Goodbye."
                          }
                      ]
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "Message recording cancelled. Goodbye."
                          }
                      ]
                  }
              },
              {
                  "delete_file":
                  {
                      "filename": "/rest_api/recordings/2018/10/06/rest_16_39_23_058d242936dcc5f9.4460.wav"
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          "actions" :
          [
              {
                  "play" :
                  {
                      "play_list" :
                      [
                          {
                              "text_to_say" : "There was no message recorded. Goodbye."
                          }
                      ]
                  }
              },
              {
                  "delete_file":
                  {
                      "filename": "/rest_api/recordings/2018/10/06/rest_16_39_23_058d242936dcc5f9.4460.wav"
                  }
              }
          ],
          "token" : "",
          "api_version": "2.0"
      }
      
    • {
          [
          ],
          "token" : "Error for Action: xxxx  ActionIndex: xxxx  Result: xxxx",
          "api_version": "2.0"
      }
      
    • {
          "api_version": "2.0"
      }
      
      
    • Implementing this sample as an ASP.Net Web Form application:

      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class Voicemail : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
        
                // Create the menu action
                Play menuPrompt = Play.SayText("Press 1 to leave a message. " + 
                                               "Press 2 to listen to all messages.");
                List<MenuOption> menuOptions = new List<MenuOption>
                {
                    new MenuOption('1', new WebPageRequest("RecordMessage.aspx")),
                    new MenuOption('2', new WebPageRequest("GetPasswordNumber.aspx"))
                };
                RunMenu runMenuAction = new RunMenu(menuOptions, menuPrompt);
                actions.Add(runMenuAction);
        
                // And add a final message
                actions.Add(Play.SayText("Goodbye."));
        
                // Respond
                String token = "-1";
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // GetPasswordNumber page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class GetPasswordNumber : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
        
                Play prompt = Play.SayText("Please enter your password number followed by the hash key.");
                GetNumber getNumberAction = new GetNumber(new WebPageRequest("CheckPasswordNumber.aspx"), prompt)
                {
                    EndDigit = '#'
                };
                actions.Add(getNumberAction);
        
                actions.Add(Play.SayText("Goodbye."));
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // CheckPasswordNumber page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class CheckPasswordNumber : System.Web.UI.Page
        {
            private static String myPassword = "1234";
        
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
                GetNumberResult getNumberResult = (GetNumberResult)ourRequest.InstanceInfo.ActionResult;
        
                // Set up the actions, depending on the entered password
                List<TelephonyAction> actions = new List<TelephonyAction>();
                if (getNumberResult.EnteredNumber.Equals(myPassword))
                {
                    actions.Add(new Redirect(new WebPageRequest("PlayMessage.aspx")));
                }
                else
                {
                    actions.Add(Play.SayText("Sorry, that password is not correct. Goodbye."));
                }
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // PlayMessage
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class PlayMessage : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                string token = ourRequest.InstanceInfo.Token;
                int messageId = Convert.ToInt32(token);
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
        
                MessageFilenameDatabase db = new MessageFilenameDatabase();
                string filename = db.GetMessageFilename(messageId);
                if (filename != null)
                {
                    actions.Add(Play.PlayFile(filename));
        
                    List<MenuOption> menuOptions = new List<MenuOption>
                    {
                        new MenuOption('1', new WebPageRequest("MessageReplay.aspx")),
                        new MenuOption('2', new WebPageRequest("MessageDelete.aspx")),
                        new MenuOption('3', new WebPageRequest("MessageKeep.aspx"))
                    };
                    actions.Add(new RunMenu(menuOptions, Play.SayText("Press 1 to hear the message again. " + 
                                                         "Press 2 to delete it, " + 
                                                         "or press 3 to save it.")
                                                         ));
                    actions.Add(Play.SayText("Goodbye."));
                }
                else
                {
                    actions.Add(Play.SayText("End of messages. Goodbye."));
                    token = "";
                }
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // MessageReplay page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class MessageReplay : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>
                {
                    Play.SayText("Playing the message again."),
                    new Redirect(new WebPageRequest("PlayMessage.aspx"))
                };
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // MessageDelete page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class MessageDelete : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                // The token should be the ID of the message file to delete
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
                int messageId = Convert.ToInt32(token);
        
                MessageFilenameDatabase db = new MessageFilenameDatabase();
                String filename = db.GetMessageFilename(messageId);
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
        
                int nextMessageId = -1;
                if (filename != null)
                {
                    // Delete action
                    actions.Add(new DeleteFile(filename));
                    Play msg = Play.SayText("Message deleted.");
        
                    // Get the next message ID
                    List<int> ids = db.GetIds();
                    for (int index = 0; index < ids.Count - 1; index++)
                    {
                        if (ids[index] == messageId)
                        {
                            nextMessageId = ids[index + 1];
                            msg.AddText("Next message.");
                            actions.Add(msg);
                            actions.Add(new Redirect(new WebPageRequest("PlayMessage.aspx")));
                            break;
                        }
                    }
        
                    if (nextMessageId == -1)
                    {
                        msg.AddText("End of messages. Goodbye.");
                        actions.Add(msg);
                    }
        
                    // Remove the entry from the DB
                    db.DeleteMessageFilename(messageId);
                }
        
                // Respond
                token = nextMessageId.ToString();
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // MessageKeep page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class MessageKeep : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                // The token should be the id of the message file to keep
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
                int messageId = Convert.ToInt32(token);
        
                MessageFilenameDatabase db = new MessageFilenameDatabase();
                String filename = db.GetMessageFilename(messageId);
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
                int nextMessageId = -1;
                if (filename != null)
                {
                    actions.Add(Play.SayText("Message saved."));
        
                    // Get the next message ID
                    List<int> ids = db.GetIds();
                    for (int index = 0; index < ids.Count - 1; index++)
                    {
                        if (ids[index] == messageId)
                        {
                            nextMessageId = ids[index + 1];
                            Play msg = Play.SayText("Next message.");
                            actions.Add(msg);
                            actions.Add(new Redirect(new WebPageRequest("PlayMessage.aspx")));
                            break;
                        }
                    }
        
                    if (nextMessageId == -1)
                    {
                        actions.Add(Play.SayText("End of messages. Goodbye."));
                    }
                }
        
                // Respond
                token = nextMessageId.ToString();
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // This prompts the caller to leave a message and starts a record action.
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class RecordMessage : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>
                {
                    Play.SayText("Please leave a message after the beep. Press hash to end the " +
                                 "recording or press star to cancel.")
                };
        
                Record recordAction = new Record(new WebPageRequest("RecordComplete.aspx"))
                {
                    BeepOnStart = true,
                    BargeInDigits = "#*",
                    MillisecondsMaxSilence = 5000
                };
                actions.Add(recordAction);
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • // CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // RecordComplete page
        
        using System;
        using System.Collections.Generic;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class RecordComplete : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                String token = ourRequest.InstanceInfo.Token;
                RecordResult result = (RecordResult)ourRequest.InstanceInfo.ActionResult;
        
                // Setup the actions
                List<TelephonyAction> actions = new List<TelephonyAction>();
        
                if (result.Reason.Equals("bargein") && result.BargeInDigit.Equals('*'))
                {
                    actions.Add(Play.SayText("Message recording cancelled. Goodbye."));
                    actions.Add(new DeleteFile(result.Filename));
                }
                else if (result.ContainsSound)
                {
                    // Store the filename in our message file
                    MessageFilenameDatabase db = new MessageFilenameDatabase();
                    db.AppendMessageFilename(result.Filename);
                    actions.Add(Play.SayText("Thanks for leaving a message. Goodbye."));
                }
                else
                {
                    actions.Add(Play.SayText("There was no message recorded. Goodbye."));
                    actions.Add(new DeleteFile(result.Filename));
                }
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • using System;
        using System.IO;
        using System.Collections.Generic;
        
        // File DB of voicemail message filenames
        //
        // Each row:  int Id, string Filename
        //
        public class MessageFilenameDatabase
        {
            private int nextId = 1;
        
            public MessageFilenameDatabase()
            {
                DbFilename = Path.GetTempPath() + "CSharpVoicemailMessages.tmp";
        
                // Initialise the id counter to the next highest int
                Dictionary<int, string> rows = GetRows();
                List<int> ids = new List<int>(rows.Keys);
                foreach (int id in ids)
                {
                    if (id > nextId)
                    {
                        nextId = id;
                    }
                }
            }
        
            public int Size()
            {
                if (!File.Exists(DbFilename))
                {
                    return 0;
                }
                String[] messageLines = File.ReadAllLines(DbFilename);
                return messageLines.Length;
            }
        
            public List<int> GetIds()
            {
                if (!File.Exists(DbFilename))
                {
                    return new List<int>();
                }
        
                Dictionary<int, string> rows = GetRows();
                return new List<int>(rows.Keys);
            }
        
            public String GetMessageFilename(int id)
            {
                if (!File.Exists(DbFilename))
                {
                    return null;
                }
        
                Dictionary<int, string> rows = GetRows();
                try
                {
                    string filename = rows[id];
                    return filename;
                }
                catch (KeyNotFoundException)
                {
                    return null;
                }
            }
        
            public int AppendMessageFilename(String filename)
            {
                Dictionary<int, string> rows;
                if (File.Exists(DbFilename))
                {
                    rows = GetRows();
                }
                else
                {
                    rows = new Dictionary<int, string>();
                }
        
                int newId = nextId++;
                rows.Add(newId, filename);
                SaveDatabaseFile(rows);
        
                return newId;
            }
        
            public void DeleteMessageFilename(int id)
            {
                if (!File.Exists(DbFilename))
                {
                    return;
                }
        
                Dictionary<int, string> rows = GetRows();
                try
                {
                    rows.Remove(id);
                }
                catch (KeyNotFoundException)
                {
                    return;
                }
        
                SaveDatabaseFile(rows);
            }
        
            private void SaveDatabaseFile(Dictionary<int, String> rows)
            {
                List<string> lines = new List<string>(rows.Count);
                foreach (KeyValuePair<int, string> entry in rows)
                {
                    lines.Add(String.Format("{0},{1}", entry.Key, entry.Value));
                }
                File.WriteAllLines(DbFilename, lines.ToArray());
            }
        
            public String DbFilename
            {
                get
                {
                    return dbFilename;
                }
                private set
                {
                    dbFilename = value;
                }
            }
        
            public Dictionary<int, string> GetRows()
            {
                Dictionary<int, string> rows = new Dictionary<int, string>();
        
                if (File.Exists(DbFilename))
                {
                    String[] messageLines = File.ReadAllLines(DbFilename);
                    foreach (string line in messageLines)
                    {
                        string[] splits = line.Split(',');
                        int id = Int32.Parse(splits[0]);
                        string filename = splits[1].Trim();
                        rows.Add(id, filename);
                    }
                }
                return rows;
            }
        
            private String dbFilename;
        }
        
        
        
      • using System;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class ErrorPage : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
                ErrorResult result = ourRequest.InstanceInfo.ErrorResult;
        
                String token = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}",
                    result.Action, result.ActionIndex, result.Result);
        
                // Respond
                TelephonyResponse ourResponse = new TelephonyResponse(null, token);
                ourResponse.ToHttpResponse(Response);
            }
        }
        
        
      • using System;
        using Aculab.Cloud.RestAPIWrapper;
        
        public partial class FinalPage : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                // Unpack the request
                TelephonyRequest ourRequest = new TelephonyRequest(Request);
            }
        }
        
        
    • Implementing this sample as an ASP.Net Mvc application:

      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        {
            [Route("Voicemail")]
            public class VoicemailController : RESTSampleController
            {
                private static readonly String myPassword = "1234";
        
                // Process the GET or POST request, set up the actions and construct the json response.
                [Route("FirstPage")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult Voicemail()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>();
        
                        // Create the menu action
                        Play menuPrompt = Play.SayText("Press 1 to leave a message. " +
                                                       "Press 2 to listen to all messages.");
                        List<MenuOption> menuOptions = new List<MenuOption>()
                        {
                            new MenuOption('1', new WebPageRequest("Voicemail/RecordMessage")),
                            new MenuOption('2', new WebPageRequest("Voicemail/GetPasswordNumber"))
                        };
                        RunMenu runMenuAction = new RunMenu(menuOptions, menuPrompt);
                        actions.Add(runMenuAction);
        
                        // And add a final message
                        actions.Add(Play.SayText("Goodbye."));
        
                        // Create response
                        String token = "-1";
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                // Process the GET or POST request, extract the transcription results and write to a file
                [Route("GetPasswordNumber")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult GetPasswordNumber()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>();
        
                        var prompt = Play.SayText("Please enter your password number followed by the hash key.");
                        var nextPage = new WebPageRequest("Voicemail/CheckPasswordNumber");
                        var getNumberAction = new GetNumber(nextPage, prompt)
                        {
                            EndDigit = '#'
                        };
                        actions.Add(getNumberAction);
        
                        actions.Add(Play.SayText("Goodbye."));
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                // Process the GET or POST request, set up the actions and construct the json response.
                [Route("CheckPasswordNumber")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult CheckPasswordNumber()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
                        GetNumberResult getNumberResult = (GetNumberResult)telephonyRequest.InstanceInfo.ActionResult;
        
                        // Set up the actions, depending on the entered password
                        List<TelephonyAction> actions = new List<TelephonyAction>();
                        if (getNumberResult.EnteredNumber.Equals(myPassword))
                        {
                            actions.Add(new Redirect(new WebPageRequest("Voicemail/PlayMessage")));
                        }
                        else
                        {
                            actions.Add(Play.SayText("Sorry, that password is not correct. Goodbye."));
                        }
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("PlayMessage")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult PlayMessage()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        string token = telephonyRequest.InstanceInfo.Token;
                        int messageId = Convert.ToInt32(token);
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>();
        
                        MessageFilenameDatabase db = new MessageFilenameDatabase();
                        string filename = db.GetMessageFilename(messageId);
                        if (filename != null)
                        {
                            actions.Add(Play.PlayFile(filename));
        
                            List<MenuOption> menuOptions = new List<MenuOption>
                            {
                                new MenuOption('1', new WebPageRequest("Voicemail/MessageReplay")),
                                new MenuOption('2', new WebPageRequest("Voicemail/MessageDelete")),
                                new MenuOption('3', new WebPageRequest("Voicemail/MessageKeep"))
                            };
                            actions.Add(new RunMenu(menuOptions, Play.SayText("Press 1 to hear the message again. " +
                                                                              "Press 2 to delete it, " +
                                                                              "or press 3 to save it.")));
                            actions.Add(Play.SayText("Goodbye."));
                        }
                        else
                        {
                            actions.Add(Play.SayText("End of messages. Goodbye."));
                            token = "";
                        }
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("MessageReplay")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult MessageReplay()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>()
                        {
                            Play.SayText("Playing the message again."),
                            new Redirect(new WebPageRequest("Voicemail/PlayMessage"))
                        };
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("MessageDelete")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult MessageDelete()
                {
                    try
                    {
                        // Unpack the request
                        // The token should be the ID of the message file to delete
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
                        int messageId = Convert.ToInt32(token);
        
                        var db = new MessageFilenameDatabase();
                        String filename = db.GetMessageFilename(messageId);
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>();
        
                        int nextMessageId = -1;
                        if (filename != null)
                        {
                            // Delete action
                            actions.Add(new DeleteFile(filename));
                            Play msg = Play.SayText("Message deleted.");
        
                            // Get the next message ID
                            List<int> ids = db.GetIds();
                            for (int index = 0; index < ids.Count - 1; index++)
                            {
                                if (ids[index] == messageId)
                                {
                                    nextMessageId = ids[index + 1];
                                    msg.AddText("Next message.");
                                    actions.Add(msg);
                                    actions.Add(new Redirect(new WebPageRequest("Voicemail/PlayMessage")));
                                    break;
                                }
                            }
        
                            if (nextMessageId == -1)
                            {
                                msg.AddText("End of messages. Goodbye.");
                                actions.Add(msg);
                            }
        
                            // Remove the entry from the DB
                            db.DeleteMessageFilename(messageId);
                        }
        
                        // Create response
                        token = nextMessageId.ToString();
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("MessageKeep")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult MessageKeep()
                {
                    try
                    {
                        // Unpack the request
                        // The token should be the id of the message file to keep
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
                        int messageId = Convert.ToInt32(token);
        
                        MessageFilenameDatabase db = new MessageFilenameDatabase();
                        String filename = db.GetMessageFilename(messageId);
        
                        // Setup the actions
                        List<TelephonyAction> actions = new List<TelephonyAction>();
                        int nextMessageId = -1;
                        if (filename != null)
                        {
                            actions.Add(Play.SayText("Message saved."));
        
                            // Get the next message ID
                            List<int> ids = db.GetIds();
                            for (int index = 0; index < ids.Count - 1; index++)
                            {
                                if (ids[index] == messageId)
                                {
                                    nextMessageId = ids[index + 1];
                                    Play msg = Play.SayText("Next message.");
                                    actions.Add(msg);
                                    actions.Add(new Redirect(new WebPageRequest("Voicemail/PlayMessage")));
                                    break;
                                }
                            }
        
                            if (nextMessageId == -1)
                            {
                                actions.Add(Play.SayText("End of messages. Goodbye."));
                            }
                        }
        
                        // Create response
                        token = nextMessageId.ToString();
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("RecordMessage")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult RecordMessage()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>()
                        {
                            Play.SayText("Please leave a message after the beep. Press hash to end the " +
                                                 "recording or press star to cancel.")
                        };
        
                        Record recordAction = new Record(new WebPageRequest("Voicemail/RecordComplete"))
                        {
                            BeepOnStart = true,
                            BargeInDigits = "#*",
                            MillisecondsMaxSilence = 5000
                        };
                        actions.Add(recordAction);
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
        
                [Route("RecordComplete")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult RecordComplete()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
                        RecordResult result = (RecordResult)telephonyRequest.InstanceInfo.ActionResult;
        
                        // Setup the actions required
                        List<TelephonyAction> actions = new List<TelephonyAction>();
        
                        if (result.Reason.Equals("bargein") && result.BargeInDigit.Equals('*'))
                        {
                            actions.Add(Play.SayText("Message recording cancelled. Goodbye."));
                            actions.Add(new DeleteFile(result.Filename));
                        }
                        else if (result.ContainsSound)
                        {
                            // Store the filename in our message file
                            MessageFilenameDatabase db = new MessageFilenameDatabase();
                            db.AppendMessageFilename(result.Filename);
                            actions.Add(Play.SayText("Thanks for leaving a message. Goodbye."));
                        }
                        else
                        {
                            actions.Add(Play.SayText("There was no message recorded. Goodbye."));
                            actions.Add(new DeleteFile(result.Filename));
                        }
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
            }
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        //
        // Voicemail:
        // An application that responds to inbound calls by prompting either
        // to leave a message or listen to all messages.
        // Recorded messages are saved to a simple file database.
        // Listening to messages requires a numeric password to be entered.
        using System;
        using System.Collections.Generic;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        }
        
      • using System;
        using System.IO;
        using System.Collections.Generic;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples
        {
            // File DB of voicemail message filenames
            //
            // Each row:  int Id, string Filename
            //
            public class MessageFilenameDatabase
            {
                private int nextId = 1;
        
                public MessageFilenameDatabase()
                {
                    DbFilename = Path.GetTempPath() + "CSharpNetCoreVoicemailMessages.tmp";
        
                    // Initialise the id counter to the next highest int
                    Dictionary<int, string> rows = GetRows();
                    List<int> ids = new List<int>(rows.Keys);
                    foreach (int id in ids)
                    {
                        if (id > nextId)
                        {
                            nextId = id;
                        }
                    }
                }
        
                public int Size()
                {
                    if (!File.Exists(DbFilename))
                    {
                        return 0;
                    }
                    String[] messageLines = File.ReadAllLines(DbFilename);
                    return messageLines.Length;
                }
        
                public List<int> GetIds()
                {
                    if (!File.Exists(DbFilename))
                    {
                        return new List<int>();
                    }
        
                    Dictionary<int, string> rows = GetRows();
                    return new List<int>(rows.Keys);
                }
        
                public String GetMessageFilename(int id)
                {
                    if (!File.Exists(DbFilename))
                    {
                        return null;
                    }
        
                    Dictionary<int, string> rows = GetRows();
                    try
                    {
                        string filename = rows[id];
                        return filename;
                    }
                    catch (KeyNotFoundException)
                    {
                        return null;
                    }
                }
        
                public int AppendMessageFilename(String filename)
                {
                    Dictionary<int, string> rows;
                    if (File.Exists(DbFilename))
                    {
                        rows = GetRows();
                    }
                    else
                    {
                        rows = new Dictionary<int, string>();
                    }
        
                    int newId = nextId++;
                    rows.Add(newId, filename);
                    SaveDatabaseFile(rows);
        
                    return newId;
                }
        
                public void DeleteMessageFilename(int id)
                {
                    if (!File.Exists(DbFilename))
                    {
                        return;
                    }
        
                    Dictionary<int, string> rows = GetRows();
                    try
                    {
                        rows.Remove(id);
                    }
                    catch (KeyNotFoundException)
                    {
                        return;
                    }
        
                    SaveDatabaseFile(rows);
                }
        
                private void SaveDatabaseFile(Dictionary<int, String> rows)
                {
                    List<string> lines = new List<string>(rows.Count);
                    foreach (KeyValuePair<int, string> entry in rows)
                    {
                        lines.Add(String.Format("{0},{1}", entry.Key, entry.Value));
                    }
                    File.WriteAllLines(DbFilename, lines);
                }
        
                public String DbFilename
                {
                    get
                    {
                        return dbFilename;
                    }
                    private set
                    {
                        dbFilename = value;
                    }
                }
        
                public Dictionary<int, string> GetRows()
                {
                    Dictionary<int, string> rows = new Dictionary<int, string>();
        
                    if (File.Exists(DbFilename))
                    {
                        String[] messageLines = File.ReadAllLines(DbFilename);
                        foreach (string line in messageLines)
                        {
                            string[] splits = line.Split(',');
                            int id = Int32.Parse(splits[0]);
                            string filename = splits[1].Trim();
                            rows.Add(id, filename);
                        }
                    }
                    return rows;
                }
        
                private String dbFilename;
            }
        }
        
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        
        using System;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        {
            public class RESTSampleController : Controller
            {
                // Process the GET or POST request for the Error condition
                [Route("ErrorPage")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult ErrorPage()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        ErrorResult result = telephonyRequest.InstanceInfo.ErrorResult;
        
                        String token = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}",
                            result.Action, result.ActionIndex, result.Result);
        
                        // Create response
                        TelephonyResponse ourResponse = new TelephonyResponse(null, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
            }
        }
        
      • // ASP.NET Core CSharp Wrapper sample for the Aculab Telephony REST API.
        
        using System;
        using Microsoft.AspNetCore.Mvc;
        using Aculab.Cloud.RestAPIWrapper;
        using System.Net;
        
        namespace Aculab.Cloud.RESTAPI.NETCoreCSharpSamples.Controllers
        {
            public class RESTSampleController : Controller
            {
                // Process the GET or POST request for the Final Page
                [Route("FinalPage")]
                [HttpGet]
                [HttpPost]
                [ProducesResponseType(200)]
                [ProducesResponseType(400)]
                [ProducesResponseType(500)]
                public IActionResult FinalPage()
                {
                    try
                    {
                        // Unpack the request
                        var telephonyRequest = new TelephonyRequest(Request);
                        String token = telephonyRequest.InstanceInfo.Token;
        
                        // Create response
                        // Only very limited actions can be returned here
                        TelephonyResponse ourResponse = new TelephonyResponse(null, token);
                        return ourResponse.ToJson(this);
                    }
                    catch (ArgumentException)
                    {
                        return BadRequest();
                    }
                    catch (Exception e)
                    {
                        return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
                    }
                }
            }
        }
        
  • Implemented as ASP.Net Web Forms:

    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' The first page for the Voicemail sample:
      ' An application that responds to inbound calls by prompting either
      ' to leave a message or listen to all messages.
      ' Recorded messages are saved to a simple file database.
      ' Listening to messages requires a numeric password to be entered.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class Voicemail
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
      
              ' Create the menu action
              Dim menuPrompt As Play = Play.SayText("Press 1 to leave a message. " +
                                                    "Press 2 to listen to all messages.")
      
              Dim menuOptions As List(Of MenuOption) = New List(Of MenuOption) From {
                  New MenuOption("1", New WebPageRequest("RecordMessage.aspx")),
                  New MenuOption("2", New WebPageRequest("GetPasswordNumber.aspx"))
              }
              Dim runMenuAction As RunMenu = New RunMenu(menuOptions, menuPrompt)
              actions.Add(runMenuAction)
      
              ' And add a final message
              actions.Add(Play.SayText("Goodbye."))
      
              ' Set to first message index
              Dim token As String = "-1"
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This prompts the caller for a password number.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class GetPasswordNumber
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
      
              Dim prompt As Play = Play.SayText("Please enter your password number followed by the hash key.")
              Dim getNumberAction As GetNumber = New GetNumber(New WebPageRequest("CheckPasswordNumber.aspx"), prompt)
              getNumberAction.EndDigit = "#"
              getNumberAction.NextPage = New WebPageRequest("CheckPasswordNumber.aspx")
              actions.Add(getNumberAction)
      
              actions.Add(Play.SayText("Goodbye."))
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This checks the password that has been entered.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class CheckPasswordNumber
          Inherits System.Web.UI.Page
      
          Shared myPassword As String = "1234"
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
      
              Dim token As String = ourRequest.InstanceInfo.Token
              Dim result As GetNumberResult = ourRequest.InstanceInfo.ActionResult
      
              ' Set up the actions, depending on the entered password
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
              If result.EnteredNumber.CompareTo(myPassword) = 0 Then
                  actions.Add(New Redirect(New WebPageRequest("PlayMessage.aspx")))
              Else
                  actions.Add(Play.SayText("Sorry, that password is not correct. Goodbye."))
              End If
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This plays the message then prompts the caller for a further option.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class PlayMessage
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
              Dim messageId As Integer = -1
              messageId = Convert.ToInt32(token)
      
              Dim db As MessageFilenameDatabase = New MessageFilenameDatabase()
              Dim filename As String = db.GetMessageFilename(messageId)
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
              If filename IsNot Nothing Then
                  actions.Add(Play.PlayFile(filename))
      
                  Dim menuOptions As List(Of MenuOption) = New List(Of MenuOption)
                  menuOptions.Add(New MenuOption("1", New WebPageRequest("MessageReplay.aspx")))
                  menuOptions.Add(New MenuOption("2", New WebPageRequest("MessageDelete.aspx")))
                  menuOptions.Add(New MenuOption("3", New WebPageRequest("MessageKeep.aspx")))
                  Dim prompt As Play = Play.SayText("Press 1 to hear the message again. " +
                                                    "Press 2 to delete it, " +
                                                    "or press 3 to save it.")
                  actions.Add(New RunMenu(menuOptions, prompt))
                  actions.Add(Play.SayText("Goodbye."))
              Else
                  actions.Add(Play.SayText("End of messages. Goodbye."))
                  token = ""
              End If
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This replays the selected message.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class MessageReplay
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
              actions.Add(Play.SayText("Playing the message again."))
              actions.Add(New Redirect(New WebPageRequest("PlayMessage.aspx")))
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Simple Play With Interrupt sample:
      ' This acknowledges the interrupt to play by saying some text
      ' before the call is hung up.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class MessageDelete
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              ' The token should be the index of the message file to delete
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
      
              Dim token As String = ourRequest.InstanceInfo.Token
              Dim messageId As Integer = -1
              messageId = Convert.ToInt32(token)
      
              Dim db As MessageFilenameDatabase = New MessageFilenameDatabase()
              Dim filename As String = db.GetMessageFilename(messageId)
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
      
              Dim nextMessageId As Integer = -1
              If filename IsNot Nothing Then
                  ' Delete action
                  actions.Add(New DeleteFile(filename))
                  Dim msg As Play = Play.SayText("Message deleted.")
      
                  ' Get the next message ID
                  Dim ids As List(Of Integer) = db.GetIds()
                  For index As Integer = 0 To (ids.Count - 2)
                      If ids(index) = messageId Then
                          nextMessageId = ids(index + 1)
                          msg.AddText("Next message.")
                          actions.Add(msg)
                          actions.Add(New Redirect(New WebPageRequest("PlayMessage.aspx")))
                          Exit For
                      End If
                  Next
      
                  If nextMessageId = -1 Then
                      msg.AddText("End of messages. Goodbye.")
                      actions.Add(msg)
                  End If
      
                  ' Remove the entry from the DB
                  db.DeleteMessageFilename(messageId)
              End If
      
              ' Respond
              token = nextMessageId.ToString()
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This saves the selected message.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class MessageKeep
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              ' The token should be the id of the message file to keep
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
              Dim messageId As Integer = Convert.ToInt32(token)
      
              Dim db As MessageFilenameDatabase = New MessageFilenameDatabase()
              Dim filename As String = db.GetMessageFilename(messageId)
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
              Dim nextMessageId As Integer = -1
              If filename IsNot Nothing Then
                  actions.Add(Play.SayText("Message saved."))
      
                  ' Get the next message ID
                  Dim ids As List(Of Integer) = db.GetIds()
                  For index As Integer = 0 To (ids.Count - 2)
                      If ids(index) = messageId Then
                          nextMessageId = ids(index + 1)
                          Dim msg As Play = Play.SayText("Next message.")
                          actions.Add(msg)
                          actions.Add(New Redirect(New WebPageRequest("PlayMessage.aspx")))
                          Exit For
                      End If
                  Next
      
                  If nextMessageId = -1 Then
                      actions.Add(Play.SayText("End of messages. Goodbye."))
                  End If
              End If
      
              ' Respond
              token = nextMessageId.ToString()
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This prompts the caller to leave a message and starts a record action.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class RecordMessage
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction) From
              {
                  Play.SayText("Please leave a message after the beep. Press hash to end the " +
                               "recording or press star to cancel.")
              }
      
              Dim recordAction As Record = New Record(New WebPageRequest("RecordComplete.aspx")) With {
                  .BeepOnStart = True,
                  .BargeInDigits = "#*",
                  .MillisecondsMaxSilence = 5000
              }
              actions.Add(recordAction)
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A page from the Voicemail sample:
      ' This is called when recording completes. It plays one of two messages to
      ' the caller depending on whether the recording contains significant sound.
      Imports System.Collections.Generic
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class RecordComplete
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim token As String = ourRequest.InstanceInfo.Token
              Dim result As RecordResult = ourRequest.InstanceInfo.ActionResult
      
              ' Setup the actions
              Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
      
              Dim helpDigit As Char = "*"
              If result.Reason.Equals("bargein") And result.BargeInDigit.Equals(helpDigit) Then
                  actions.Add(Play.SayText("Message recording cancelled. Goodbye."))
                  actions.Add(New DeleteFile(result.Filename))
              ElseIf result.ContainsSound Then
                  ' Store the filename in our message file
                  Dim db As MessageFilenameDatabase = New MessageFilenameDatabase()
                  db.AppendMessageFilename(result.Filename)
                  actions.Add(Play.SayText("Thanks for leaving a message. Goodbye."))
              Else
                  actions.Add(Play.SayText("There was no message recorded. Goodbye."))
                  actions.Add(New DeleteFile(result.Filename))
              End If
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • Imports System.IO
      Imports System.Collections.Generic
      
      ' File DB of voicemail message filenames
      '
      ' Each row:  int Id, string Filename
      '
      Public Class MessageFilenameDatabase
      
          Private nextId As Integer = 1
      
          Public Sub New()
              dbFilename = Path.GetTempPath() + "VBVoicemailMessages.tmp"
      
              ' Initialise the id counter to the next highest int
              Dim rows As Dictionary(Of Integer, String) = GetRows()
              Dim ids As List(Of Integer) = New List(Of Integer)(rows.Keys)
              For Each id As String In ids
                  If id > nextId Then
                      nextId = id
                  End If
              Next
          End Sub
      
          Public Function Size() As Integer
              If Not File.Exists(dbFilename) Then
                  Return 0
              End If
      
              Dim lines As Array = File.ReadAllLines(dbFilename)
              Return lines.Length
          End Function
      
          Public Function GetIds() As List(Of Integer)
              If Not File.Exists(dbFilename) Then
                  Return New List(Of Integer)
              End If
      
              Dim rows As Dictionary(Of Integer, String) = GetRows()
              Return New List(of integer)(rows.Keys)
          End Function
      
          Public Function GetMessageFilename(id As Integer) As String
              If Not File.Exists(dbFilename) Then
                  Return Nothing
              End If
      
              Dim rows As Dictionary(Of Integer, String) = GetRows()
              Try
                  Return rows(id)
              Catch ex As KeyNotFoundException
                  Return Nothing
              End Try
          End Function
      
          Public Function AppendMessageFilename(filename As String) As Integer
              Dim rows As Dictionary(Of Integer, String)
              If File.Exists(dbFilename) Then
                  rows = GetRows()
              Else
                  rows = New Dictionary(Of Integer, String)
              End If
      
              Dim newId As Integer = nextId
              nextId += 1
              rows.Add(newId, filename)
              SaveDatabaseFile(rows)
          End Function
      
          Public Sub DeleteMessageFilename(id As Integer)
              If Not File.Exists(dbFilename) Then
                  Return
              End If
      
              Dim rows As Dictionary(Of Integer, String) = GetRows()
              Try
                  rows.Remove(id)
              Catch ex As KeyNotFoundException
                  Return
              End Try
      
              SaveDatabaseFile(rows)
          End Sub
      
          Private Sub SaveDatabaseFile(rows As Dictionary(Of Integer, String))
              Dim lines As List(Of String) = New List(Of String)(rows.Count)
              For Each entry As KeyValuePair(Of Integer, String) In rows
                  lines.Add(String.Format("{0},{1}", entry.Key, entry.Value))
              Next
              File.WriteAllLines(dbFilename, lines)
          End Sub
      
          Public Function GetRows() As Dictionary(Of Integer, String)
              Dim rows As Dictionary(Of Integer, String) = New Dictionary(Of Integer, String)
      
              If File.Exists(dbFilename) Then
                  Dim messageLines As String() = File.ReadAllLines(dbFilename)
                  For Each line As String In messageLines
                      Dim splits As String() = line.Split(",")
                      Dim id As Integer = Int32.Parse(splits(0))
                      Dim filename As String = splits(1).Trim()
                      rows.Add(id, filename)
                  Next
              End If
              Return rows
          End Function
      
          Private dbFilename As String
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A generic error page for all the samples.
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class ErrorPage
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
              Dim result As ErrorResult = ourRequest.InstanceInfo.ErrorResult
      
              Dim token As String = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}", _
                  result.Action, result.ActionIndex, result.Result)
      
              ' Respond
              Dim ourResponse As TelephonyResponse = New TelephonyResponse(token)
              ourResponse.ToHttpResponse(Response)
          End Sub
      End Class
      
      
    • ' Visual Basic Wrapper sample for the Aculab Telephony REST API.
      '
      ' A generic final page for all the samples:
      Imports Aculab.Cloud.RestAPIWrapper
      
      Partial Class FinalPage
          Inherits System.Web.UI.Page
      
          Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
      
              ' Unpack the request
              Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
      
              ' Do application tidying up
              ' ...
          End Sub
      End Class
      
      
  • Implemented as Java Servlets:

    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      // Voicemail:
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class Voicemail extends HttpServlet
      {
          private static final long serialVersionUID = -216367273425731462L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
      
              // Create the menu action
              Play menuPrompt = Play.sayText("Press 1 to leave a message. " + 
                                             "Press 2 to listen to all messages.");
              List<MenuOption> menuOptions = new ArrayList<MenuOption>();
              menuOptions.add(new MenuOption('1', new WebPageRequest("RecordMessage")));
              menuOptions.add(new MenuOption('2', new WebPageRequest("GetPasswordNumber")));
              RunMenu runMenuAction = new RunMenu(menuPrompt, menuOptions);
              actions.add(runMenuAction);
      
              // And add a final message
              actions.add(Play.sayText("Goodbye."));
      
              //Get the first message id in the filename database
              MessageFilenameDatabase db = new MessageFilenameDatabase();
              String token = Integer.toString(db.getFirstMessageId());
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class GetPasswordNumber extends HttpServlet
      {
          private static final long serialVersionUID = -7217763794925626580L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
              
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
      
              Play prompt = Play.sayText("Please enter your password number followed by the hash key.");
              GetNumber getNumberAction = new GetNumber(new WebPageRequest("CheckPasswordNumber"));
              getNumberAction.setPrompt(prompt);
              getNumberAction.setEndDigit('#');
              actions.add(getNumberAction);
      
              actions.add(Play.sayText("Goodbye."));
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class CheckPasswordNumber extends HttpServlet
      {
          private static final long serialVersionUID = 2185118085479932134L;
      
          private static String myPassword = "1234";
          
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
              GetNumberResult getNumberResult = (GetNumberResult)ourRequest.getInstanceInfo().getActionResult();
      
              // Set up the actions, depending on the entered password
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              if (getNumberResult.getEnteredNumber().compareTo(myPassword) == 0)
              {
                  actions.add(new Redirect(new WebPageRequest("PlayMessage")));
              }
              else
              {
                  actions.add(Play.sayText("Sorry, that password is not correct. Goodbye."));
              }
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class PlayMessage extends HttpServlet
      {
          private static final long serialVersionUID = 6018322048224034139L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
      
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
      
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              // The token should be the index of the next message file to play
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              MessageFilenameDatabase db = new MessageFilenameDatabase();
              String token = ourRequest.getInstanceInfo().getToken();
      
              int messageId = Integer.parseInt(token);
      
              String filename = db.getMessageFilename(messageId);
              if (filename != null)
              {
                  actions.add(Play.playFile(filename));
      
                  List<MenuOption> menuOptions = new ArrayList<MenuOption>();
                  menuOptions.add(new MenuOption('1', new WebPageRequest("MessageReplay")));
                  menuOptions.add(new MenuOption('2', new WebPageRequest("MessageDelete")));
                  menuOptions.add(new MenuOption('3', new WebPageRequest("MessageKeep")));
                  actions.add(new RunMenu(Play.sayText("Press 1 to hear the message again. " +
                                                       "Press 2 to delete it, " +
                                                       "or press 3 to save it."),
                                                       menuOptions));
                  actions.add(Play.sayText("Goodbye."));
      
                  token = Integer.toString(messageId);
              }
              else
              {
                  actions.add(Play.sayText("End of messages. Goodbye."));
                  token = "";
              }
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class MessageReplay extends HttpServlet
      {
          private static final long serialVersionUID = -6227827216303408130L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
      
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              actions.add(Play.sayText("Playing the message again."));
              actions.add(new Redirect(new WebPageRequest("PlayMessage")));
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class MessageDelete extends HttpServlet
      {
          private static final long serialVersionUID = 5011613038036857392L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              // The token should be the index of the message file to delete
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
              int messageId = Integer.parseInt(token);
              MessageFilenameDatabase db = new MessageFilenameDatabase();
              String filename = db.getMessageFilename(messageId);
      
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              int nextMessageId = -1;
              if (filename != null)
              {
                  actions.add(new DeleteFile(filename));
                  Play msg = Play.sayText("Message deleted.");
                  
                  nextMessageId = db.getNextMessageId(messageId);
                  
                  if (nextMessageId != -1)
                  {
                      msg.addText("Next message.");
                      actions.add(msg);
                      actions.add(new Redirect(new WebPageRequest("PlayMessage")));
                  }
                  else
                  {
                      msg.addText("End of messages. Goodbye.");
                      actions.add(msg);
                  }
                  db.deleteMessageFilename(messageId);
              }
              
              // Respond
              token = Integer.toString(nextMessageId);
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class MessageKeep extends HttpServlet
      {
          private static final long serialVersionUID = 4847733899330443860L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              // The token should be the index of the message file to keep
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
              int messageId = Integer.parseInt(token);
              MessageFilenameDatabase db = new MessageFilenameDatabase();
              String filename = db.getMessageFilename(messageId);
              
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              int nextMessageId = -1;
              if (filename != null)
              {
                  actions.add(Play.sayText("Message saved."));
                  
                  nextMessageId = db.getNextMessageId(messageId);
                  
                  if (nextMessageId != -1)
                  {
                      actions.add(Play.sayText("Next message."));
                      actions.add(new Redirect(new WebPageRequest("PlayMessage")));
                  }
                  else
                  {
                      actions.add(Play.sayText("End of messages. Goodbye."));
                  }
              }
              
              // Respond
              token = Integer.toString(nextMessageId);
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class RecordMessage extends HttpServlet
      {
          private static final long serialVersionUID = -3436973162929428486L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
      
              // Setup the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
      
              actions.add(Play.sayText("Please leave a message after the beep. Press hash to end the recording or press star to cancel."));
      
              Record recordAction = new Record(new WebPageRequest("RecordComplete"));
              recordAction.setBeepOnStart(true);
              recordAction.setBargeInDigits("#*");
              recordAction.setMillisecondsMaxSilence(5000);
              actions.add(recordAction);
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class RecordComplete extends HttpServlet
      {
          private static final long serialVersionUID = 3418571655744931314L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              String token = ourRequest.getInstanceInfo().getToken();
              RecordResult result = (RecordResult)ourRequest.getInstanceInfo().getActionResult();
              
              // Set up the actions
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
      
              if ( result.getReason().equals("bargein") && result.getBargeInDigit().equals("*"))
              {
                  actions.add(Play.sayText("Message recording cancelled. Goodbye."));
                  actions.add(new DeleteFile(result.getFilename()));
              }
              else if (result.containsSound())
              {
                  // Store the filename in our message file
                  String filename = result.getFilename();
      
                  MessageFilenameDatabase db = new MessageFilenameDatabase();
                  db.appendMessageFilename(filename);
      
                  actions.add(Play.sayText("Thanks for leaving a message. Goodbye."));
              }
              else
              {
                  actions.add(Play.sayText("There was no message recorded. Goodbye."));
                  actions.add(new DeleteFile(result.getFilename()));
              }
      
              // Respond
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • package com.aculab.telephonyrestapi.samples;
      
      import java.io.BufferedWriter;
      import java.io.File;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.nio.charset.Charset;
      import java.nio.file.Files;
      import java.util.Iterator;
      import java.util.LinkedHashMap;
      import java.util.List;
      import java.util.Map;
      import java.util.Map.Entry;
      
      
      public class MessageFilenameDatabase
      {
          public MessageFilenameDatabase() throws IOException
          {
              File temp = File.createTempFile("temp-file", ".tmp");
              String absolutePath = temp.getAbsolutePath();
              String tempFilePath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator) + 1);
              temp.delete();
      
              dbFile = new File(tempFilePath + "JavaVoicemailMessages.tmp");
              if (dbFile.exists())
              {
                  LinkedHashMap<Integer, String> rows = getRows();
      
                  for (Entry<Integer, String> row : rows.entrySet())
                  {
                      int id = row.getKey();
                      if (id >= nextId)
                      {
                          nextId = id + 1;
                      }
                  }
              }
          }
      
          public Integer getFirstMessageId() throws IOException
          {
              LinkedHashMap<Integer, String> rows = getRows();
              
              Iterator<Entry<Integer, String>> it = rows.entrySet().iterator();
              
              if(it.hasNext())
              {
                  Map.Entry<Integer, String> row = (Map.Entry<Integer, String>)it.next();
                  return row.getKey();
              }
      
              return -1;
          }
          
          public Integer getNextMessageId(Integer id) throws IOException
          {
              LinkedHashMap<Integer, String> rows = getRows();
      
              Iterator<Entry<Integer, String>> it = rows.entrySet().iterator();
      
              while(it.hasNext())
              {
                  Map.Entry<Integer, String> row;
      
                  row = (Map.Entry<Integer, String>)it.next();
                  if (row.getKey() == id)
                  {
                      if (it.hasNext())
                      {
                          row = (Map.Entry<Integer, String>)it.next();
                          return row.getKey();
                      }
                  }
              }
      
              return -1;
          }
      
          public String getMessageFilename(int id) throws IOException
          {
              LinkedHashMap<Integer, String> rows = getRows();
              
              for (Entry<Integer, String> row : rows.entrySet())
              {
                  if (id == row.getKey())
                  {
                      return row.getValue();
                  }
              }
              
              return null;
          }
          
          public void appendMessageFilename(String filename) throws IOException
          {    	
              LinkedHashMap<Integer, String> rows = getRows();
              
              rows.put(nextId, filename);
              nextId++;
              saveDatabaseFile(rows);
          }
      
          public void deleteMessageFilename(int id) throws IOException
          {
              LinkedHashMap<Integer, String> rows = getRows();
              
              if (rows.remove(id) != null)
              {
                  saveDatabaseFile(rows);
              }
          }
         
          private void saveDatabaseFile(LinkedHashMap<Integer, String> rows) throws IOException
          {
              BufferedWriter writer = new BufferedWriter(new FileWriter(dbFile, false));
              
              for (Entry<Integer, String> row : rows.entrySet())
              {
                  writer.write(row.getKey() + "," + row.getValue());
                  writer.newLine();
              }
              writer.close();
          }
          
          public LinkedHashMap<Integer, String> getRows() throws IOException
          {
              LinkedHashMap<Integer, String> rows = new LinkedHashMap<Integer, String>();
      
              if (dbFile.exists())
              {
                  List<String> messageLines;
      
                  messageLines = Files.readAllLines(dbFile.toPath(), Charset.defaultCharset());
      
                  for(String line : messageLines)
                  {
                      String[] splits = line.split(",");
                      int id = Integer.parseInt(splits[0]);
                      String filename = splits[1].trim();
                      rows.put(id, filename);
                  }
              }
              return rows;
          }
      
          private int nextId = 1;
          private File dbFile;
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      import com.aculab.telephonyrestapi.*;
      
      public class ErrorPage extends HttpServlet
      {
          private static final long serialVersionUID = -4842873371047361437L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
      
              ErrorResult result = ourRequest.getInstanceInfo().getErrorResult();
      
              String token = String.format("Action: %s\nActionIndex: %d\nResult: %s", result.getAction(), result.getActionIndex(), result.getResult());
              
              // Respond
              List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
              TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
              ourResponse.setHttpServletResponse(response);
          }
      }
      
      
    • // Java Servlet sample for the Aculab Telephony REST API.
      //
      
      package com.aculab.telephonyrestapi.samples;
      
      import javax.servlet.http.*;
      import javax.servlet.ServletException;
      import java.io.IOException;
      import com.aculab.telephonyrestapi.*;
      
      public class FinalPage extends HttpServlet
      {
          private static final long serialVersionUID = 5940620014313056844L;
      
          @Override
          public void doGet(HttpServletRequest request,
                            HttpServletResponse response)
              throws IOException, ServletException
          {
             	handleRequest(request, response);
          }
          
          @Override
          public void doPost(HttpServletRequest request,
                  HttpServletResponse response)
                          throws IOException, ServletException
          {
          	handleRequest(request, response);
          }
          
          private void handleRequest(HttpServletRequest request,
                                     HttpServletResponse response) throws IOException
          {
              // Unpack the request
              TelephonyRequest ourRequest = new TelephonyRequest(request);
          }
      }
      
      
  • Implemented as a Flask web application:

    • @app.route('/Voicemail', methods=['GET','POST'])
      def handle_Voicemail():
      
          # Here we begin to create our action list in response to the query
          my_request = TelephonyRequest(request)
          app_inst_id = my_request.get_application_instance_id()
          print("Voicemail: app_inst_id='{}'".format(app_inst_id))
      
          db = MessageFilenameDatabase()
      
          # Set a next_page for each of the options
          menu_options = []
          menu_options.append(MenuOption('1', WebPage(url='RecordMessage')))
          menu_options.append(MenuOption('2', WebPage(url='GetPasswordNumber')))
      
          # Create the menu action
          my_menu = RunMenu(menu_options)
          my_menu.set_prompt(Play(text_to_say= ('Press 1 to leave a message. Press 2 to listen to all messages.')))
      
          list_of_actions = []
      
          # Append the menu action to the action list.
          list_of_actions.append(my_menu)
          list_of_actions.append(Play(text_to_say="Goodbye."))
      
          # Get the first message id in the filename database
          db = MessageFilenameDatabase()
          msg_id = db.getFirstMessageId()
      
          my_response = TelephonyResponse(list_of_actions, str(msg_id))
          return my_response.get_json()
      
      
    • @app.route('/GetPasswordNumber', methods=['GET','POST'])
      def handle_GetPasswordNumber():
      
          my_request = TelephonyRequest(request)
          my_token = my_request.get_token()
      
          # Option 2 is to listen to all the recorded messages. 
          # First we need to check that the caller is authorised to do this.
          # We configure an IVR to ask for a PIN, we use GetNumber to do this.
      
          my_number = GetNumber(WebPage(url='CheckPasswordNumber'))
          my_number.set_end_digit('#')
          # As with RunMenu, we provide an initial prompt.
          my_number.set_prompt(Play(text_to_say='Please enter your password number followed by the hash key.'))
      
          list_of_actions = []
          list_of_actions.append(my_number)
          list_of_actions.append(Play(text_to_say="Goodbye."))
      
          my_response = TelephonyResponse(list_of_actions, my_token)
          return my_response.get_json()
      
      
    • @app.route('/CheckPasswordNumber', methods=['GET','POST'])
      def handle_CheckPasswordNumber():
      
          my_request = TelephonyRequest(request)
          action_result = my_request.get_action_result()
          my_token = my_request.get_token()
      
          id_digits = ""
          if(action_result.get('action') == 'get_number'):
              id_digits = action_result.get('result').get('entered_number')
      
          list_of_actions = []
      
          # For our purposes the PIN is hard-coded to 1234
          if id_digits == '1234':
              # Redirect to the PlayMessage page, where the first message will be played.
              list_of_actions.append(Redirect(next_page=WebPage(url='PlayMessage')))
          else:
              # The PIN is not correct, say sorry and hang up. The application will
              # automatically hang up after this action since there is no redirection
              # to a next page.
              list_of_actions.append(Play(text_to_say='Sorry, that password is not correct. Goodbye.'))
      
          my_response = TelephonyResponse(list_of_actions, my_token)
          return my_response.get_json()
      
      
    • @app.route('/PlayMessage', methods=['GET','POST'])
      def handle_PlayMessage():
      
          my_request = TelephonyRequest(request)
          msg_id = int(my_request.get_token())
      
          db = MessageFilenameDatabase()
          filename = db.getMessageFilename(msg_id)
      
          list_of_actions = []
      
          if filename != "":
              list_of_actions.append(Play(file_to_play=filename))
      
              # Here we set a next_page for each of the three options
              menu_options = []
              menu_options.append(MenuOption('1', WebPage(url='MessageReplay')))
              menu_options.append(MenuOption('2', WebPage(url='MessageDelete')))
              menu_options.append(MenuOption('3', WebPage(url='MessageKeep')))
      
              my_menu = RunMenu(menu_options)
              my_menu.set_prompt(Play(text_to_say= ('Press 1 to hear the message again. '
                                                        'Press 2 to delete it, '
                                                        'or press 3 to save it.')))
      
              list_of_actions.append(my_menu)
      
              list_of_actions.append(Play(text_to_say="Goodbye."))
      
          else:
              list_of_actions.append(Play(text_to_say='End of messages. Goodbye.'))
      
          my_response = TelephonyResponse(list_of_actions, token=str(msg_id)) 
          return my_response.get_json()
      
      
    • @app.route('/MessageReplay', methods=['GET','POST'])
      def handle_MessageReplay():
      
          my_request = TelephonyRequest(request)
      
          my_token = my_request.get_token()
      
          list_of_actions = []
      
          list_of_actions.append(Play(text_to_say='Playing the message again.'))
          list_of_actions.append(Redirect(next_page=WebPage(url='PlayMessage')))
      
          my_response = TelephonyResponse(list_of_actions, my_token)
          return my_response.get_json()
      
      
    • @app.route('/MessageDelete', methods=['GET','POST'])
      def handle_MessageDelete():
      
          my_request = TelephonyRequest(request)
          msg_id = int(my_request.get_token())
      
          db = MessageFilenameDatabase()
          msg_filename =  db.getMessageFilename(msg_id)
          next_msg_id = db.getNextMessageId(msg_id)
          db.deleteMessage(msg_id)
      
          list_of_actions = []
      
          list_of_actions.append(DeleteFile(msg_filename))
      
          play_action = Play(text_to_say='Message deleted.')
      
          if next_msg_id != -1:
              play_action.append_text('Next message.')
              list_of_actions.append(play_action)
              list_of_actions.append(Redirect(next_page=WebPage(url='PlayMessage')))
          else:
              play_action.append_text('End of messages. Goodbye.')
              list_of_actions.append(play_action)
      
          my_response = TelephonyResponse(list_of_actions, token=str(next_msg_id)) 
          return my_response.get_json()
      
    • @app.route('/MessageKeep', methods=['GET','POST'])
      def handle_MessageKeep():
      
          my_request = TelephonyRequest(request)
          msg_id = int(my_request.get_token())
      
          db = MessageFilenameDatabase()
          next_msg_id = db.getNextMessageId(msg_id)
      
          list_of_actions = []
      
          list_of_actions.append(Play(text_to_say='Message saved.'))
          if next_msg_id != -1:
              list_of_actions.append(Play(text_to_say='Next message.'))
              list_of_actions.append(Redirect(next_page=WebPage(url='PlayMessage')))
          else:
              list_of_actions.append(Play(text_to_say='End of messages. Goodbye.'))
      
          my_response = TelephonyResponse(list_of_actions, token=str(next_msg_id)) 
          return my_response.get_json()
      
      
    • @app.route('/RecordMessage', methods=['GET','POST'])
      def handle_RecordMessage():
      
          my_request = TelephonyRequest(request)
          my_token = my_request.get_token()
      
          list_of_actions = []
          
          # Option 1 is to leave a message. We create two actions, the first is to use TTS to
          # ask the caller to begin the message after a beep, and to press # to end the recording.
          list_of_actions.append(Play(text_to_say='Please leave a message after the beep. Press hash to end the recording or press star to cancel.'))
      
          # The next action it to start recording. When the recording has completed, the application
          # will be directed to the my_recorded_file_page.
          list_of_actions.append(Record(barge_in_digits="#*",             # pressing # will stop the recording
                                milliseconds_max_silence=5000,            # five seconds of silence will stop the recording
                                next_page=WebPage(url='RecordComplete'),  # when recording completes, go to this page
                                beep_on_start=True))                      # before recording begins, play a beep
      
          my_response = TelephonyResponse(list_of_actions, my_token)
          return my_response.get_json()
      
      
    • @app.route('/RecordComplete', methods=['GET','POST'])
      def handle_RecordComplete():
      
          my_request = TelephonyRequest(request)
          my_token = my_request.get_token()
          action_result = my_request.get_action_result()
          record_result = action_result.get('result')
      
          list_of_actions = []
      
          if (record_result.get("reason") == "bargein") and (record_result.get("barge_in_digit") == "*"):
      
              list_of_actions.append(Play(text_to_say='Message recording cancelled. Goodbye.'))
              list_of_actions.append(DeleteFile(record_result.get("filename")))
      
          elif record_result.get("contains_sound"):
      
              filename = record_result.get("filename")
              print ("Recorded file is {0}".format(filename))
      
              # Store the filename in our messages file
              db = MessageFilenameDatabase()
              db.appendMessageFilename(filename)
      
              list_of_actions.append(Play(text_to_say='Thanks for leaving a message. Goodbye.'))
      
          else:
      
              list_of_actions.append(Play(text_to_say='There was no message recorded. Goodbye.'))
              list_of_actions.append(DeleteFile(record_result.get("filename")))
      
          my_response = TelephonyResponse(list_of_actions, my_token)
          return my_response.get_json()
      
      
    • class MessageFilenameDatabase:
      
          # Class to store message entries that are read from the database file.
          class Row:
              def __init__(self, id, filename):
                  self.id = id
                  self.filename = filename
      
          # Create the database file if it does not already exist
          def __init__(self):
              self.db_filename = tempfile.gettempdir() + '/' + "PythonVoicemailMessages.tmp"
              fh = open(self.db_filename, "a")
              fh.close()
      
          # Read the database file, parse each line into
          # a list of 'Row' classes
          def getRows(self):
              fh = open(self.db_filename, "r")
              rows = []
              for x in fh:
                  id_and_filename = x.split(",")
                  id = int(id_and_filename[0])
                  filename = id_and_filename[1].strip()
                  rows.append(self.Row(id,filename))
              fh.close()
              return rows
      
          # Return the id of the first (top most) message that
          # is stored in the database file.
          # Returns -1 if the first message id could not be found.
          def getFirstMessageId(self):
              rows = self.getRows()
              if len(rows) > 0:
                  return rows[0].id
              return -1
      
          # Return the id of the message that is stored below this_id in 
          # the database file.
          # Returns -1 if the next message id could not be found.
          def getNextMessageId(self, this_id):
              rows = self.getRows()
              return_next_id = False
              for row in rows:
                  if return_next_id == True:
                      return row.id
                  elif row.id == this_id:
                      return_next_id = True
              return -1
      
          # Return a message filename given its id.
          def getMessageFilename(self, id):
              rows = self.getRows()
              for row in rows:
                  if row.id == id:
                      return row.filename
              return ""
      
          # Add another message entry to the database file
          def appendMessageFilename(self, filename):
              new_id = 1
              rows = self.getRows()
              
              for row in rows:
                  if new_id <= row.id:
                      new_id = row.id + 1
              
              fh = open(self.db_filename, "a")
              fh.write("{0},{1}\n".format(new_id, filename))
              fh.close()
      
          # Delete a message from the database file given its id.
          def deleteMessage(self, id):
              rows = self.getRows()
              new_rows = []
      
              # Clear the file contents. Re-write the entries but
              # miss out the one we want to delete.
              fh = open(self.db_filename, "w")
              for row in rows:
                  if id != row.id:
                      fh.write("{0},{1}\n".format(row.id, row.filename))
              fh.close()
      
    • @app.route('/ErrorPage', methods=['GET','POST'])
      def handle_ErrorPage():
          
          my_request = TelephonyRequest(request)
          token = my_request.get_token()
          app_inst_id = my_request.get_application_instance_id()
          error_result_dict = my_request.get_error_result()
          action_string = error_result_dict.get('action', "?")
          result_string = error_result_dict.get('result', "?")
          print("ErrorPage: app_inst_id='{}' token='{}' action='{}' result='{}'".format(app_inst_id, token, action_string, result_string))
          
          my_response = TelephonyResponse([Play(text_to_say='An error has occurred')])
          return my_response.get_json()
      
      
    • @app.route('/FinalPage', methods=['GET','POST'])
      def handle_FinalPage():
          # The FinalPage handler follows the guidelines on:
          # https://www.aculab.com/cloud/voice-and-fax-apis/rest-api/rest-api-version-2/writing-a-rest-application
          # The guidelines are:
          #   "Your final page should return an empty response, a 204 is preferable, but empty JSON is acceptable."
          my_request = TelephonyRequest(request)
          token = my_request.get_token()
          app_inst_id = my_request.get_application_instance_id()
          print("FinalPage: app_inst_id='{}' token='{}'".format(app_inst_id, token))
          empty_json = '{}'.encode('utf-8')
          return empty_json, 204
          
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      require __DIR__ . "/MessageFilenameDatabase.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\RunMenu;
      
      $resp = new Response();
      $resp->setToken( (string)getFirstMessageId() );
      
      // Create the menu action
      $menuPrompt = Play::sayText("Press 1 to leave a message. Press 2 to listen to all messages.");
      $menu = new RunMenu();
      $menu->setPrompt($menuPrompt);
      $menu->addMenuOption('1', 'RecordMessage.php');
      $menu->addMenuOption('2', 'GetPasswordNumber.php');
      
      $resp->addAction($menu);
      
      $resp->addAction(Play::sayText('Goodbye.'));
      
      print $resp;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\GetNumber;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      // Create the get number action
      $prompt = Play::sayText("Please enter your password number followed by the hash key.");
      $getNumberAction = new GetNumber("CheckPasswordNumber.php");
      $getNumberAction->setPrompt($prompt);
      $getNumberAction->setEndDigit('#');
      
      $response->addAction($getNumberAction);
      
      
      $response->addAction(Play::sayText('Goodbye.'));
      
      print $response;
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\Redirect;
      
      $info = InstanceInfo::getInstanceInfo();
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      $enteredNumber = '';
      // Get the result of the run_menu action
      $result = $info->getActionResult();
      if ($result != null && is_a($result, '\Aculab\TelephonyRestAPI\GetNumberResult')) {
          $enteredNumber = $result->getEnteredNumber();
      }
      
      if ($enteredNumber == '1234') {
          $response->addAction(new Redirect('PlayMessage.php'));
      } else {
          $response->addAction(Play::sayText('Sorry, that password is not correct. Goodbye.'));
      }
      
      print $response;
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      require __DIR__ . "/MessageFilenameDatabase.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\RunMenu;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      $midstr = $info->getToken();
      $mid = (int)$midstr;
      $fname = getMessageFilename($mid);
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      if (is_null($fname)) {
          $response->addAction(Play::sayText('End of messages. Goodbye.'));
      } else {
          $response->addAction(Play::playFile($fname));
          
          // Create the menu action
          $menuPrompt = Play::sayText("Press 1 to hear the message again. Press 2 to delete it, or press 3 to save it.");
          $menu = new RunMenu();
          $menu->setPrompt($menuPrompt);
          $menu->addMenuOption('1', 'MessageReplay.php');
          $menu->addMenuOption('2', 'MessageDelete.php');
          $menu->addMenuOption('3', 'MessageKeep.php');
      
          $response->addAction($menu);
      
          $response->addAction(Play::sayText('Goodbye.'));
      }
      
      print $response;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\Redirect;
      
      $info = InstanceInfo::getInstanceInfo();
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      $response->addAction(Play::sayText('Playing the message again.'));
      $response->addAction(new Redirect('PlayMessage.php'));
      
      print $response;
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      require __DIR__ . "/MessageFilenameDatabase.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\DeleteFile;
      use \Aculab\TelephonyRestAPI\Redirect;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      $midstr = $info->getToken();
      $mid = (int)$midstr;
      $next = getNextMessageId($mid);
      
      $response = new Response();
      
      $response->addAction(Play::sayText('Message saved.'));
      
      if ($next != -1) {
          $response->addAction(Play::sayText('Next message.'));
          $response->addAction(new Redirect('PlayMessage.php'));
      } else {
          $response->addAction(Play::sayText('End of messages. Goodbye.'));
      }
      
      $response->setToken((string)$next);
      
      
      print $response;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      require __DIR__ . "/MessageFilenameDatabase.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\DeleteFile;
      use \Aculab\TelephonyRestAPI\Redirect;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      $midstr = $info->getToken();
      $mid = (int)$midstr;
      
      // get file to delete
      $fname = getMessageFilename($mid);
      // get next before delete, otherwise it can't find the current one
      $next = getNextMessageId($mid);
      deleteMessageId($mid);
      
      $response = new Response();
      if (!is_null($fname)) {
          $response->addAction(new DeleteFile($fname));
      }
      
      $play = Play::sayText('Message deleted.');
      
      if ($next != -1) {
          $play->addText('Next message.');
          $response->addAction($play);
          $response->addAction(new Redirect('PlayMessage.php'));
      } else {
          $play->addText('End of messages. Goodbye.');
          $response->addAction($play);
      }
      
      $response->setToken((string) $next);
      
      print $response;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\Record;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      $response->addAction(Play::sayText("Please leave a message after the beep. Press hash to end the recording or press star to cancel."));
      
      $record = new Record('RecordComplete.php');
      $record->setBeepOnStart(true);
      $record->setBargeInDigits('#*');
      $record->setMillisecondsMaxSilence(5000);
      $response->addAction($record);
      
      print $response;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      require __DIR__ . "/MessageFilenameDatabase.php";
      
      header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
      header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
      header("Content-Type: application/json; charset=UTF-8");
      
      use \Aculab\TelephonyRestAPI\Response;
      use \Aculab\TelephonyRestAPI\DeleteFile;
      use \Aculab\TelephonyRestAPI\Play;
      use \Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      $recordResult = $info->getActionResult();
      $fname = $recordResult->getFilename();
      
      $response = new Response();
      $response->setToken($info->getToken()); // NB not really needed as we are not changing the token
      
      if ($recordResult->getReason() == "bargein" and $recordResult->getBargeInDigit() == "*") {
          $response->addAction(Play::sayText('Message recording cancelled. Goodbye.'));
          $response->addAction(new DeleteFile($fname));
      } else if ($recordResult->getContainsSound()) {
          appendMessageFilename($fname);
          $response->addAction(Play::sayText('Thanks for leaving a message. Goodbye.'));
      } else {
          $response->addAction(Play::sayText('There was no message recorded. Goodbye.'));
          $response->addAction(new DeleteFile($fname));
      }
          
      print $response;
      
      
    • <?php
      function loadMessageDatabase() {
          $message_list_filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "PHPVoicemailMessages.tmp";
          $msgs = [];
          if (file_exists($message_list_filename)) {
              $messagelist = file($message_list_filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
              if ($messagelist) {
                  foreach($messagelist as $mline) {
                      list($id, $fname) = explode(',', $mline, 2);
                      $msgs[(int)$id] = $fname;
                  }
              }
          }
          return $msgs;
      }
      
      function saveMessageDatabase($msgs) {
          $messagelist = [];
          foreach($msgs as $id => $fname) {
              $messagelist[] = $id . ',' . $fname;
          }
          $message_list_filename = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "PHPVoicemailMessages.tmp";
          $f = fopen($message_list_filename, 'w');
          if ($f !== false) {
              fwrite($f, implode("\n", $messagelist));
              fclose($f);
          }
      }
      
      function getFirstMessageId() {
          $msgs = loadMessageDatabase();
          if (count($msgs) > 0) {
              return array_keys($msgs)[0];
          }
          return -1;
      }
      
      function getMessageFilename($msg_id) {
          $msgs = loadMessageDatabase();
          if (isset($msgs[$msg_id])) {
              return $msgs[$msg_id];
          }
          return null;
      }
      
      function getNextMessageId($msg_id) {
          $msgs = loadMessageDatabase();
          $return_next = false;
          foreach($msgs as $id => $fname) {
              if ($return_next) {
                  return $id;
              }
              if ($id == $msg_id) {
                  $return_next = true;
              }
          }
          return -1;
      }
      
      function appendMessageFilename($fname) {
          $msgs = loadMessageDatabase();
          $msgs[] = $fname;
          saveMessageDatabase($msgs);
      }
      
      function deleteMessageId($msg_id) {
          $msgs = loadMessageDatabase();
          if (isset($msgs[$msg_id])) {
              unset($msgs[$msg_id]);
              saveMessageDatabase($msgs);
          }
      }
      
      
    • <?php
      header("Content-Type: application/json; charset=UTF-8");
      
      require __DIR__ . "/../../autoload.php";
      
      use Aculab\TelephonyRestAPI\Play;
      use Aculab\TelephonyRestAPI\Response;
      use Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      
      $error = $info->getErrorResult();
      $action = $error->getAction();
      $desc = $error->getResult();
      if (!is_null($action)) {
          error_log("Error from action \"$action\" with result:" . PHP_EOL . "$desc" . PHP_EOL);
      } else {
          error_log("Error result:" . PHP_EOL . "$desc" . PHP_EOL);
      }
      
      $response = new Response();
      $response->setToken('Error');
      
      $play = new Play();
      $play->addText('An error has occurred.');
      $response->addAction($play);
      
      print $response;
      
      
    • <?php
      require __DIR__ . "/../../autoload.php";
      
      http_response_code(204);
      header("Content-Type: application/json; charset=UTF-8");
      
      use Aculab\TelephonyRestAPI\InstanceInfo;
      
      $info = InstanceInfo::getInstanceInfo();
      $call = $info->getThisCallInfo();
      $callid = $call->getCallId();
      $duration = $call->getSecondsCallDuration();
      error_log("This call id: $callid" . PHP_EOL . "This call duration: $duration" . PHP_EOL);