使用 C# 通过 PlumVoice IVR 创建呼出活动
Create an Outbound Campaign through PlumVoice IVR using C#
我使用 PlumVoice IVR 系统有一段时间了,现在需要利用他们的外呼功能。我需要在 C# 中执行此操作,但由于缺乏记录的 C# 支持,我很难弄清楚如何继续。以下是我的项目的细节:
- 我从文件中解析数据(例如 phone 号码),然后用文件数据调用 [那些] 号码。
- 它不是 MVC 项目(您可以看到如果它是 MVC 项目会更容易)
现在我需要:
- 使用 queuecall Web 服务创建呼叫 [Campaign]
- 创建
post-呼叫处理
的报告功能
我已经为我的项目编译并测试了必要的代码,并且它完全按预期工作(显然,直到客户更新需求)。
WebRequest 方法
public static void PlumOutboundQueuecall(ObjectModel model)
{
// Create a request for the URL.
WebRequest request = WebRequest.Create(Settings.IvrOutboundApi); //ease of editing/reusability //http://outbound.plumvoice.com/webservice/queuecall.php
request.Method = "POST";
//request.ContentType = "multipart/form-data"; //This is only if I choose to upload a [.csv] file of phone numbers
request.ContentType = "application/x-www-form-urlencoded";
// I used as reference for proper encoding
StringBuilder postData = new StringBuilder();
postData.Append(HttpUtility.UrlEncode("login") + "=" + HttpUtility.UrlEncode("<MY_EMAIL_FOR_PLUM>") + "&");
postData.Append(HttpUtility.UrlEncode("pin") + "=" + HttpUtility.UrlEncode("<MY_PIN_FOR_PLUM>") + "&");
postData.Append(HttpUtility.UrlEncode("phone_number") + "=" + HttpUtility.UrlEncode(model.PhoneNumber) + "&");
postData.Append(HttpUtility.UrlEncode("start_url") + "=" + HttpUtility.UrlEncode("<MY_vXML_AS_ASPX_PAGE_SHOWN_BELOW>") + "&"); //"http://ip_address/MY_ASPX_PAGE.aspx"
postData.Append(HttpUtility.UrlEncode("call_parameters") + "=" + HttpUtility.UrlEncode("<THE_PHONE_MESSAGE_TEXT_TO_BE_READ>") + "&"); //includes 'model' properties
postData.Append(HttpUtility.UrlEncode("result_url") + "=" + HttpUtility.UrlEncode("<MY_RESULT_URL_AS_ASMX_PAGE_SHOWN_BELOW>")); //"http://ip_address/MY_ASMX_PAGE.asmx/PlumOutboundCallback"
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postData.ToString());
// add post data to request
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
// Get response
// Used Fiddler to deconstruct/reverse-engineer
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream()); // Get the response stream
string result = reader.ReadToEnd(); // Read the contents and return as a string
if (result.Contains("failed"))
{
// Whatever error handling you want to do if your "result_url" page throws an error. I used this extensively while testing the proper way to set this up
}
}
}
我的 .vxml 文件作为 .aspx 页面。这是已发布并位于服务器上 ("ip_address/MY_ASPX_PAGE.aspx")
<%Response.ContentType = "text/xml"%>
<?xml version="1.0" ?>
<vxml version="2.0">
<form>
<block>
<prompt>
<%-- Set the "Custom Call Parameters" to be THE_PHONE_MESSAGE_TEXT_TO_BE_READ --%>
<%=request.form("call_parameters") %> <%-- This says "Cannot resolve symbol 'request'" but just ignore it --%>
</prompt>
</block>
</form>
</vxml>
我知道这似乎写错了但忽略它('request' 将显示为红色)
我的 "result_url" 是一个 .asmx 页面。这是已发布并位于服务器上 ("ip_address/MY_ASMX_PAGE.asmx/PlumOutboundCallback")
/// <summary>
/// Summary description for OutboundResultUrl
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class OutboundResultUrl : System.Web.Services.WebService
{
[WebMethod]
public string PlumOutboundCallback()
{
bool heartbeat = string.IsNullOrEmpty(HttpContext.Current.Request.Form["phone_number"]); //Plum implements a heartbeat and checks that this 'result_url' is working. A 'phone_number' has to exist in order for me to process the data FOR a call (duh) so I check to see if it is null or empty
if (!heartbeat)
{
//BusinessLayer.OutboundCallback model = new BusinessLayer.OutboundCallback { phone_number = HttpContext.Current.Request.Form["phone_number"], message_reference = HttpContext.Current.Request.Form["message_reference"], call_id = Convert.ToInt32(HttpContext.Current.Request.Form["call_id"]), result = HttpContext.Current.Request.Form["result"], callee_type = HttpContext.Current.Request.Form["callee_type"], attempts = Convert.ToInt32(HttpContext.Current.Request.Form["attempts"]), last_attempt_timestamp = HttpContext.Current.Request.Form["last_attempt_timestamp"], duration = Convert.ToInt32(HttpContext.Current.Request.Form["duration"]) }; //if you're into this sort of thing
BusinessLayer.OutboundCallback model = new BusinessLayer.OutboundCallback();
model.phone_number = HttpContext.Current.Request.Form["phone_number"];
model.message_reference = HttpContext.Current.Request.Form["message_reference"];
model.call_id = Convert.ToInt32(HttpContext.Current.Request.Form["call_id"]);
model.result = HttpContext.Current.Request.Form["result"];
model.callee_type = HttpContext.Current.Request.Form["callee_type"];
model.attempts = Convert.ToInt32(HttpContext.Current.Request.Form["attempts"]);
model.last_attempt_timestamp = HttpContext.Current.Request.Form["last_attempt_timestamp"];
model.duration = Convert.ToInt32(HttpContext.Current.Request.Form["duration"]);
string stringResultData = string.Format("Collecting parameters posted into here. <br />Phone Number = {0}, <br />Message Reference = {1}, <br />Call ID = {2}, <br />Result = {3}, <br />Callee Type = {4}, <br />Attempts = {5}, <br />Last Attempt Timestamp = {6}, <br />Duration = {7}",
model.phone_number, model.message_reference, model.callee_type, model.result, model.callee_type, model.attempts, model.last_attempt_timestamp, model.duration); //this is for debugging/testing purposes
try
{
// Whatever you want to do with this data! Send it in an email, Save it to the database, etc.
}
catch (Exception error)
{
Console.WriteLine("Error: " + error);
}
}
return "Plum Outbound API has posted back to this 'result_url' successfully.";
}
}
最后一步:记得将您的广告系列设置为 运行!更改 http://hosting.plumgroup.com/developer_tools_outbound.php
"Campaign Status" 单元格下的状态
我真的希望这对通过 C# 使用 PlumVoice 的每个人都有帮助。请评论并分享任何改进或问题!
我使用 PlumVoice IVR 系统有一段时间了,现在需要利用他们的外呼功能。我需要在 C# 中执行此操作,但由于缺乏记录的 C# 支持,我很难弄清楚如何继续。以下是我的项目的细节:
- 我从文件中解析数据(例如 phone 号码),然后用文件数据调用 [那些] 号码。
- 它不是 MVC 项目(您可以看到如果它是 MVC 项目会更容易)
现在我需要:
- 使用 queuecall Web 服务创建呼叫 [Campaign]
- 创建 post-呼叫处理 的报告功能
我已经为我的项目编译并测试了必要的代码,并且它完全按预期工作(显然,直到客户更新需求)。
WebRequest 方法
public static void PlumOutboundQueuecall(ObjectModel model)
{
// Create a request for the URL.
WebRequest request = WebRequest.Create(Settings.IvrOutboundApi); //ease of editing/reusability //http://outbound.plumvoice.com/webservice/queuecall.php
request.Method = "POST";
//request.ContentType = "multipart/form-data"; //This is only if I choose to upload a [.csv] file of phone numbers
request.ContentType = "application/x-www-form-urlencoded";
// I used as reference for proper encoding
StringBuilder postData = new StringBuilder();
postData.Append(HttpUtility.UrlEncode("login") + "=" + HttpUtility.UrlEncode("<MY_EMAIL_FOR_PLUM>") + "&");
postData.Append(HttpUtility.UrlEncode("pin") + "=" + HttpUtility.UrlEncode("<MY_PIN_FOR_PLUM>") + "&");
postData.Append(HttpUtility.UrlEncode("phone_number") + "=" + HttpUtility.UrlEncode(model.PhoneNumber) + "&");
postData.Append(HttpUtility.UrlEncode("start_url") + "=" + HttpUtility.UrlEncode("<MY_vXML_AS_ASPX_PAGE_SHOWN_BELOW>") + "&"); //"http://ip_address/MY_ASPX_PAGE.aspx"
postData.Append(HttpUtility.UrlEncode("call_parameters") + "=" + HttpUtility.UrlEncode("<THE_PHONE_MESSAGE_TEXT_TO_BE_READ>") + "&"); //includes 'model' properties
postData.Append(HttpUtility.UrlEncode("result_url") + "=" + HttpUtility.UrlEncode("<MY_RESULT_URL_AS_ASMX_PAGE_SHOWN_BELOW>")); //"http://ip_address/MY_ASMX_PAGE.asmx/PlumOutboundCallback"
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postData.ToString());
// add post data to request
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
// Get response
// Used Fiddler to deconstruct/reverse-engineer
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream()); // Get the response stream
string result = reader.ReadToEnd(); // Read the contents and return as a string
if (result.Contains("failed"))
{
// Whatever error handling you want to do if your "result_url" page throws an error. I used this extensively while testing the proper way to set this up
}
}
}
我的 .vxml 文件作为 .aspx 页面。这是已发布并位于服务器上 ("ip_address/MY_ASPX_PAGE.aspx")
<%Response.ContentType = "text/xml"%>
<?xml version="1.0" ?>
<vxml version="2.0">
<form>
<block>
<prompt>
<%-- Set the "Custom Call Parameters" to be THE_PHONE_MESSAGE_TEXT_TO_BE_READ --%>
<%=request.form("call_parameters") %> <%-- This says "Cannot resolve symbol 'request'" but just ignore it --%>
</prompt>
</block>
</form>
</vxml>
我知道这似乎写错了但忽略它('request' 将显示为红色)
我的 "result_url" 是一个 .asmx 页面。这是已发布并位于服务器上 ("ip_address/MY_ASMX_PAGE.asmx/PlumOutboundCallback")
/// <summary>
/// Summary description for OutboundResultUrl
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class OutboundResultUrl : System.Web.Services.WebService
{
[WebMethod]
public string PlumOutboundCallback()
{
bool heartbeat = string.IsNullOrEmpty(HttpContext.Current.Request.Form["phone_number"]); //Plum implements a heartbeat and checks that this 'result_url' is working. A 'phone_number' has to exist in order for me to process the data FOR a call (duh) so I check to see if it is null or empty
if (!heartbeat)
{
//BusinessLayer.OutboundCallback model = new BusinessLayer.OutboundCallback { phone_number = HttpContext.Current.Request.Form["phone_number"], message_reference = HttpContext.Current.Request.Form["message_reference"], call_id = Convert.ToInt32(HttpContext.Current.Request.Form["call_id"]), result = HttpContext.Current.Request.Form["result"], callee_type = HttpContext.Current.Request.Form["callee_type"], attempts = Convert.ToInt32(HttpContext.Current.Request.Form["attempts"]), last_attempt_timestamp = HttpContext.Current.Request.Form["last_attempt_timestamp"], duration = Convert.ToInt32(HttpContext.Current.Request.Form["duration"]) }; //if you're into this sort of thing
BusinessLayer.OutboundCallback model = new BusinessLayer.OutboundCallback();
model.phone_number = HttpContext.Current.Request.Form["phone_number"];
model.message_reference = HttpContext.Current.Request.Form["message_reference"];
model.call_id = Convert.ToInt32(HttpContext.Current.Request.Form["call_id"]);
model.result = HttpContext.Current.Request.Form["result"];
model.callee_type = HttpContext.Current.Request.Form["callee_type"];
model.attempts = Convert.ToInt32(HttpContext.Current.Request.Form["attempts"]);
model.last_attempt_timestamp = HttpContext.Current.Request.Form["last_attempt_timestamp"];
model.duration = Convert.ToInt32(HttpContext.Current.Request.Form["duration"]);
string stringResultData = string.Format("Collecting parameters posted into here. <br />Phone Number = {0}, <br />Message Reference = {1}, <br />Call ID = {2}, <br />Result = {3}, <br />Callee Type = {4}, <br />Attempts = {5}, <br />Last Attempt Timestamp = {6}, <br />Duration = {7}",
model.phone_number, model.message_reference, model.callee_type, model.result, model.callee_type, model.attempts, model.last_attempt_timestamp, model.duration); //this is for debugging/testing purposes
try
{
// Whatever you want to do with this data! Send it in an email, Save it to the database, etc.
}
catch (Exception error)
{
Console.WriteLine("Error: " + error);
}
}
return "Plum Outbound API has posted back to this 'result_url' successfully.";
}
}
最后一步:记得将您的广告系列设置为 运行!更改 http://hosting.plumgroup.com/developer_tools_outbound.php
"Campaign Status" 单元格下的状态我真的希望这对通过 C# 使用 PlumVoice 的每个人都有帮助。请评论并分享任何改进或问题!