Twilio on Call-Connect or Hangup get call details - c#

I am using ASP.NET MVC Web calling with Twilio
Here is my Connect function
function callCustomer(phoneNumber) {
updateCallStatus("Calling " + phoneNumber + "...");
phoneNumber = phoneNumber.replace(/ /g, '');
var params = { To: phoneNumber };
Twilio.Device.connect(params);
}
Here is my Hangup function
function hangUp() {
Twilio.Device.disconnectAll();
}
Here is my TwiML Bin
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="++516xxx9999" record="record-from-answer">{{To}}</Dial>
</Response>
I am using Twilio client v1.6
//media.twiliocdn.com/sdk/js/client/v1.6/twilio.min.js
I want to collect complete information of each call as I connect to call or as I hang up the call like Call Duration, Call Sid, Record Sid, Call To, and other. Then with that information I would like implement play recorded call in my application.
I believe one way of doing it is set CALL STATUS CHANGES under Voice & Fax and receive all params.

This is how I ended up handling it.
/* Callback for when a call ends */
Twilio.Device.disconnect(function (connection) {
console.log(connection);
// Disable the hangup button and enable the call buttons
hangUpButton.prop("disabled", true);
callCustomerButtons.prop("disabled", false);
callSupportButton.prop("disabled", false);
updateCallStatus("Ready");
addCallLog(connection.parameters.CallSid);
});
addCallLog function
function addCallLog(id) {
var type = "";
var entityId = Number($("#Id").val());
$.ajax({
url: "/Phone/AddCallLog?callId=" + id,
type: "POST",
contentType: "application/json;",
success: function (data) {
// Handle Success Event
},
error: function (data) {
// Handle Error Event
}
});
}
Controller Method
[HttpPost]
public ActionResult AddCallLog(string callId,string type,int entityId)
{
TwilioClient.Init(_callSetting.Twilio.AccountSid, _callSetting.Twilio.Authtoken);
var records = CallResource.Read(parentCallSid: callId).ToList();
if (records.Any())
{
var callResource= records[0];
var parentRecord = CallResource.Fetch(pathSid: callId);
if (callResource.Status.ToString().Equals("completed", StringComparison.OrdinalIgnoreCase))
{
CallRecord callRecord = new CallRecord
{
EntityKey = entityId,
EntityType = type,
CallDateTimeUtc = callResource.DateCreated ?? DateTime.UtcNow,
CallSId = callResource.Sid,
ParentCallSId = callResource.ParentCallSid,
CalledById = _operatingUser.Id,
DurationInSeconds = parentRecord==null? Convert.ToDouble(callResource.Duration): Convert.ToDouble(parentRecord.Duration),
ToPhone = callResource.To,
CompanyId = _operatingUser.CompanyId
};
var callRecordResult= _callRecordService.Add(callRecord);
var recording = RecordingResource.Read(callSid: callId).ToList();
if (!recording.Any()) return Json(true);
foreach (RecordingResource recordingResource in recording)
{
using (var client = new WebClient())
{
var url =
"https://api.twilio.com" + recordingResource.Uri.Replace(".json", ".mp3");
var content = client.DownloadData(url);
CallRecordMedia callRecordMedia = new CallRecordMedia
{
CallRecordId = callRecordResult.Id,
ContentType = "audio/mpeg",
RecordingSId = recordingResource.Sid,
RecordingCallSId = recordingResource.CallSid,
FileType = "mp3",
Data = content,
Price = Convert.ToDouble(recordingResource.Price),
PriceUnit = recordingResource.PriceUnit,
DurationInSeconds = Convert.ToDouble(recordingResource.Duration)
};
_callRecordService.AddCallRecording(callRecordMedia);
}
}
}
}
return Json(true);
}

Related

OpenXML not creating document on production, but fine in Dev

I have launched a new application at work. We create letters using OpenXML which works flawlessly on Dev, but on production the solution is not returning.
$("#createLetter").on("click", CreateLetter);
function CreateLetter() {
$.ajax({
type: "POST",
url: "/Letters/CreateLetter",
data: {
EntityType: "#overview.EntityType",
EntityId: #overview.EntityId,
Recipient: $("#Recipient").val(),
TemplatesLocation: $("#templatePath").val(),
SaveAs: $("#saveAs").val()
},
async: false,
success: openLetter
});
}
function openLetter(data) {
openFile(data);
window.location.reload(false);
}
Controller Method:
[ValidateInput(false)]
[HttpPost]
public JsonResult CreateLetter(CreateLetter input)
{
Recipient obj = logic.SplitRecipientInput(input.Recipient);
input.RecipientId = obj.RecipientId;
input.RecipientType = obj.Type;
input.Username = Helpers.GetLoggedInUser();
var x = logic.CreateLetter(input);
if (x.Success == 1)
{
return Json(x.Data, JsonRequestBehavior.AllowGet);
}
else
{
return Json("Error", JsonRequestBehavior.AllowGet);
}
}
Consumption Logic:
public CreatedLetter CreateLetter(CreateLetter input)
{
CreatedLetter response = new CreatedLetter();
Parameters.Add("TemplatePath", GetApiValue(input.TemplatesLocation));
Parameters.Add("EntityType", GetApiValue(input.EntityType));
Parameters.Add("EntityId", GetApiValue(input.EntityId));
Parameters.Add("RecipientId", GetApiValue(input.RecipientId));
Parameters.Add("RecipientType", GetApiValue(input.RecipientType));
Parameters.Add("Username", GetApiValue(input.Username));
Parameters.Add("SaveAs", GetApiValue(input.SaveAs));
response = Api.WebRequest<CreatedLetter>("CreateLetters", Parameters, Method.POST) as CreatedLetter;
return response;
}
API Controller method:
[ActionName("CreateLetter")]
[HttpPost]
public ApiResponse CreateLetter(LetterCreateInput input)
{
try
{
LetterTemplateLogic logic = new LetterTemplateLogic();
Random r = new Random();
var randomId = r.Next(100000, 999999);
string fileName = string.Format("{0} - {1}", randomId, input.SaveAs);
input.SaveAs = fileName;
// Get all objects for Letter
List<object> objs = logic.TemplateObjectsRetriever(input.EntityId, input.EntityType, input.Username, randomId);
objs.Add(logic.GetRecipient(input.RecipientId, input.RecipientType));
// Get save location
string saveLocation = logic.LetterLocationResolver(input.EntityId, input.EntityType);
var data = logic.OpenAndUpdateTemplate(objs, input.TemplatePath, input.SaveAs, saveLocation, FileExtension);
AttachmentInput letterAttachment = new AttachmentInput();
letterAttachment.Id = input.EntityId;
letterAttachment.FileTypeId = 1;
letterAttachment.Path = data;
letterAttachment.Username = input.Username;
letterAttachment.Description = fileName;
letterAttachment.EntityType = input.EntityType;
logic.InsertLetterAttachment(letterAttachment);
return ApiResponse.Return(data);
}
catch (Exception ex)
{
return ApiResponse.Error(ex);
}
}
This returns literally nothing on production. No errors in the console, no errors from the API which logs erroneous calls. I was hoping someone could make a suggestion?
Thanks.

Live update map - Timer class - c#

I'm building a project with asp.net.
Part of the the project is a view (using google maps api) that is showing the the status of the parking lots with maerkers on the map.
Im using JSON file to create the markers.
Moreover, Im using arduino with some sensors that are indicated of the parking lot status.
I want that this Json will be update (override the previous) every 2 seconds (so that if a car enters the parking lot and now its full - it will present on the map as full)
I have 2 functions that creates this Json's and I want to call them every 2 seconds as I said before.
I could not do it. I'll be glad to receive your help.
The name of the view page: "TotalPs".
This is the controller in which the relevant function is located:
public ActionResult TotalPs()
{
ViewBag.Message = "TotalPs";
return View();
}
public ActionResult TotalPData()
{
ReadArduino(); //READ THE DATA FROM THE ARDUINO
callA(); // CREATES THE FIRST JSON
callB(); // CREATES THE 2ND JSON
var totalQueryParkingLot =
from lot in db.parkingLots
orderby lot.PricePerHour
select lot;
return Json(totalQueryParkingLot);
}
public void callA()
{
var totalQueryParkingLot =
from lot in db.parkingLots
orderby lot.PricePerHour
select lot;
var data2 = totalQueryParkingLot.ToList();
var jsonString2 = JsonConvert.SerializeObject(data2);
if (jsonString2 != null)
{
if (!Directory.Exists(Server.MapPath("~/Content/")))
{
Directory.CreateDirectory(Server.MapPath("~/Content/"));
}
}
System.IO.File.WriteAllText(Server.MapPath("~/Content/TotalJsonPL.json"), jsonString2);
}
public void callB()
{
var FreeQueryParkingLot =
from pub in db.publicParkings
orderby pub.PricePerHourpublicParking
select pub;
var data8 = FreeQueryParkingLot.ToList();
var jsonString3 = JsonConvert.SerializeObject(data8);
if (jsonString3 != null)
{
if (!Directory.Exists(Server.MapPath("~/Content/")))
{
Directory.CreateDirectory(Server.MapPath("~/Content/"));
}
}
System.IO.File.WriteAllText(Server.MapPath("~/Content/TotalJsonPU.json"), jsonString3);
}
public void ReadArduino()
{
SerialPort port = new SerialPort("COM3", 9600);
port.BaudRate = 9600;
port.PortName = "COM3";
port.Open();
bool status1 = true;
bool status2 = true;
bool status3 = true;
char[] arr = new char[4];
String data_arduino = port.ReadLine();
for (int i = 0; i < arr.Length; i++)
{
char first = data_arduino[i];
arr[i] = first;
}
int space = arr[0] - 48;
var arduinoQuery1 = from b in db.parkingLots where b.parkingLotID == 22 select b;
foreach (parkingLot parkingLot in arduinoQuery1)
{
parkingLot.freeSpaces = space;
}
db.SaveChanges();
}
In the view I call the function TotalPData() that is calling to the other functions.
Tnx!!
I am assuming that you are applying a ajax call to retrieve json data. So, you can assign interval using setInterval to execute ajax call periodically.
var interval = setInterval(ajaxCall, 5000); //5000 MS == 5 seconds
function ajaxCall() {
clearInterval(interval);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: 'Controller/TotalPData',
dataType: "json",
success: function (response) {
interval = setInterval(ajaxCall, 5000);
// Do something
},
error: function (a, b, c) {
}
});
}
Also, It could be better to use SignalR to perform this kind of requirements.
SignalR

Success callback not running

Can anyone tell me why my success callback in this jQuery isn't being called?
$(document).ready(function () {
var queueid = $('#hidqueueid').val();
var queuemax = $('#hidqueuemax').val();
var queuenext = $('#hidqueuenext').val();
var sid = $('#hidsid').val();
var acc = $('#hidacc').val();
var key = getCookie('account_key');
var processNext = function() {
var url = "functions.aspx?sid=" + sid + "&acc=" + acc + "&func=processqueue&id=" + queueid + "&next=" + queuenext + '&key=' + key;
showProgress();
$.post(url, function (data) {
alert(data); // <== never happens :(
var result = $(data).attr('result');
if (result == 'ok') {
queuenext = $(data).attr('next');
if (queuenext > 0) {
$('#hidqueuenext').val(queuenext);
processNext();
} else {
var newurl = 'Data.aspx?sid=' + sid + '&acc=' + acc;
location.href = newurl;
}
}
}, function() {
// error
alert('Oops!');
});
};
var showProgress = function() {
var output = "<div>" + queuenext + " of " + queuemax + "</div>";
$('#divprogress').html(output);
};
processNext();
});
The C# which returns the result is working fine and looks like this:
string xml = new Queue(sid, acc, queueId).ProcessItem(queueNext, key);
Response.ClearContent();
Response.ContentType = "text/xml";
Response.Write(xml);
System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest();
The XML looks fine when I debug the C#
Thanks for any help! All suggestions welcome.
post has three initial parameters, first one is a address, second is data, which should be null in your case, and third is success callback.
If you need a fail callback, use fail method:
$.post('', null, null).fail(function(data) {} );
Also, if you feel more comfortable working with that XMLRequest object, you might want to use complete method:
$.post('/do/action', { Id: 120 }, null).fail(function(data) {
// code
}).complete(function(data) {
// code for complete, which is the same as success callback.
});
There is also .always() method which is being called back always, hehe. And others.

Issues with HttpContext.Current.Response.Redirect in a class

I have written a class which gets the post data using jquerypost and then perform some crud operations. Its works fine adding stuff to the database , but it doesnt redirects to the page when passing certain data , below is the code :
$('#clickme').click(function (e) {
e.preventDefault();
indx = $("#DropDownList1 option:selected").index();
indx += 1;
var test = $("#DropDownList" + (indx + 1));
var url = "/Base/performOperations/shootme/"
jQuery.post(url, { name: jQuery("#name").val(), email: jQuery("#email").val(), federation: jQuery(test).val(), selectedscheme: jQuery("#DropDownList1").val() },
function (data) {
if (data == scheme1) {
window.location = "http://www.openme.com"
}
});
});
namespace pw
{
public class performOperations
{
public static string ShootMe() {
HttpRequest post = HttpContext.Current.Request;
string name = post["name"];
string email = post["email"];
string selectedscheme = post["selectedscheme"];
string federation = post["federation"];
string conn = System.Configuration.ConfigurationManager.AppSettings["mydb"];
string sql = "INSERT INTO dbo.mydb(Email,Name,schemes,LoginDate,schemeType) VALUES(#email,#name,#scheme,#dateTime,#federation)";
SqlHelper.ExecuteNonQuery(conn, CommandType.Text, sql,
new SqlParameter("#email", email),
new SqlParameter("#name", name),
new SqlParameter("#scheme", selectedscheme),
new SqlParameter("#dateTime", DateTime.Now),
new SqlParameter("#federation", federation));
return selectedscheme;
}
}
}
Any ideas why the redirect doesnt takes place, or am i doing it in a wrong way , i need to redirect to a particular page once the data is injected to the db.
Any assistance will be appreciated
If you are calling the POST method using AJAX, redirection at server side will not work.
You will have to redirect it at client side after request completion using javascript the request.
$('#clickme').click(function (e) {
e.preventDefault();
indx = $("#DropDownList1 option:selected").index();
indx += 1;
var test = $("#DropDownList" + (indx + 1));
var url = "/Base/sample/Hello/"
jQuery.post(url, { name: jQuery("#name").val(), email: jQuery("#email").val(), federation: jQuery(test).val(), selectedscheme: jQuery("#DropDownList1").val() },
function (data) {
if (data == "shoothim") {
window.location = "http://www.cuthishead.com"
}
else if(data == "shoother")
{
window.location = "http://www.chopherbody.com"
}
else if(data == "shootboth")
{
window.location = "http://www.fulldeath.tv"
}
});
return selectedscheme or URL from your page method
set window.location based on web method result on jquery
need to set WebMethod attribute for your C# method
Check Using jQuery to Call ASP.NET AJAX Page Methods – By Example

Return data from jQuery callback ASP.NET 2.0

I am new to jQuery and I am implementing an example I found on CodeProjects.
What I need is to get a string with an imagename and new image index returned from the PageMethod I am calling.
However each time I try to return something else than a number via Response.Write the callback fails and I go into the error function.
$(document).ready(function() {
var imageIndex = $("[id$='hdn_imageIndex']");
var app_path = $("[id$='hdn_app_path']");
$("#btn_next").click(function() {
var json = "{'Index':'" + imageIndex.val() + "'}";
var ajaxPage = app_path.val() + "/JSONProcessor.aspx?NextImage=1"; //this page is where data is to be retrieved and processed
var options = {
type: "POST",
url: ajaxPage,
data: json,
contentType: "application/json;charset=UTF-8",
dataType: "json",
async: false,
success: function(result) {
alert("success: " + result.d);
// I want my return value from my PageMethod HERE.
},
error: function(msg) { alert("failed: " + msg.d); }
};
var returnText = $.ajax(options).responseText;
});
});
The PageMethod in JSONProcessor.aspx looks like this:
public void NextImage()
{
System.IO.StreamReader sr = new System.IO.StreamReader(Request.InputStream);
string line = "";
line = sr.ReadToEnd();
JObject jo = JObject.Parse(line);
int newImageIndex = -1;
int oldImageIndex = int.Parse(Server.UrlDecode((string)jo["Index"]));
List<string> images = (List<string>)Session["ShowHouseImages"];
int noOfImages = images.Count;
if (noOfImages > 0)
{
if (oldImageIndex == noOfImages - 1)
{
newImageIndex = 0;
}
else
{
newImageIndex = oldImageIndex + 1;
}
string[] result = ChangeImage(newImageIndex, images);
Response.StatusCode = 200;
Response.Write("1");
// What I REALLY WANT TO RETURN IS THIS
// Response.Write(string.Format("{0};{1};{2}", result[0], result[1], result[2]));
}
Response.Write("0");
}
JSON return from WebMethods does not seem to be a part of .NET 2.0. That is why I do it like this. Hope somebody can help me out.
To my understanding in the line
Response.Write(string.Format("{0};{1};{2}", result[0], result[1], result[2]));
you are not returning a correct JSON object. It should probably look something like
Response.Write(string.Format("{{images:[{0},{1},{2}]}}", result[0], result[1], result[2]));
This returns you an array with three elements. The produced output should be:
{images:[1,2,3]}
In JavaScript you can access data using result.images[0],result.images1, etc.
I'm not sure if you need to specify array object name (images).
I suggest you take a look at JSON website to get a better understanding of the syntax. This way you will be able to construct complex object by yourself.

Categories

Resources