I have a client in the healthcare space, that might need an IVR system to take patients through a simple six question survey (all of the "press 1 for I Strongly Agree, up to 5 for I Strongly Disagree" type). The factors involved...
Small client: We don't need enterprise-level firepower. We'd expect maybe 50-100 surveys per month.
Hosted: We will be setting up an ASP.NET server with a SQL Server database hosted at a co-location facility. We don't have our own server room and pipes to the internet. I'll want something already hosted that I can tie into. (It needn't be on my ASP.NET server, of course.)
Integration: The rest of their system will be .NET and SQL Server based, so I want to be able to automate pulling the data from the IVR system into my own
Ad-Hoc: We won't be robo-calling. A typical scenario for us: My client receives a live call from a patients...and at the end, will say "Do you have another minute? Can I have you take a phone survey?" If the patient says yes, then either...
they hang up, my client dials a few commands into the IVR system, at the IVR calls the patient...or...
my client doesn't hang up, but transfers the current phone call to the IVR system
Suggestions?
Check out twilio
I believe surveymonkey has an implementation over this API that might also work for you.
I've used Microsoft Speech Server 2007 (Part of Office Communications Server 2007) in the past and it will meet all of your requirements. You can find out more about it here: http://gotspeech.net/
It looks like Speech Server 2007 has been renamed Tellme and you can find out more here: http://www.microsoft.com/en-us/Tellme/developers/default.aspx
I have not used the new Tellme version, but Speech Server 2007 was great. You could implement an entire IVR system within Visual Studio using workflows and .NET code. I would expect Tellme probably makes it even easier.
Ricky from Twilio here.
We put together a C# tutorial for this exact use case I wanted to share:
https://www.twilio.com/docs/tutorials/walkthrough/automated-survey/csharp/mvc
There's a sample configuration that lets you set all the survey questions you want to ask:
protected override void Seed(AutomatedSurveysContext context)
{
context.Surveys.AddOrUpdate(
survey => new { survey.Id, survey.Title },
new Survey { Id = 1, Title = "Twilio" });
context.SaveChanges();
context.Questions.AddOrUpdate(
question => new { question.Body, question.Type, question.SurveyId },
new Question
{
Body = "Hello. Thanks for taking the Twilio Developer Education survey. On a scale of 0 to 9 how would you rate this tutorial?",
Type = QuestionType.Numeric,
SurveyId = 1
},
new Question
{
Body = "On a scale of 0 to 9 how would you rate the design of this tutorial?",
Type = QuestionType.Numeric,
SurveyId = 1
},
new Question
{
Body = "In your own words please describe your feelings about Twilio right now? Press the pound sign when you are finished.",
Type = QuestionType.Voice,
SurveyId = 1
},
new Question
{
Body = "Do you like my voice? Please be honest, I dislike liars.",
Type = QuestionType.YesNo,
SurveyId = 1
});
context.SaveChanges();
}
Related
Current Project:
ASP.NET 4.5.2
MVC 5
PayPal API
I am using this example to build myself a PayPal transaction (and yes, my code is virtually identical), as I do not know of any other method that will return the three values in the title.
My main problem is that, the example I am utilizing is much more concise and compact than the one I used for a much older Web Forms application, and as such, I am unsure as to where or even how to grab the three values I need.
My initial thought was to do so right after the ACK, and indeed I was able to obtain the CorrelationId as well as the TimeStamp, but because this was prior to the user being carted off to PayPal’s site (sandbox in this case -- see the return new PayPalRedirect contained within the if), the TransactionId was blank. And in this example, PayPal explicitly redirects the user to a Success page without returning to the Action that sent the user to PayPal in the first place, and I am not seeing any GET values in the URL at all aside from the Token and the PayerId, much less ones that could provide me with the TransactionId.
Suggestions?
I have also looked at the following examples:
For ASP.NET Core, was unsure how to adapt to my current project particularly due to appsettings.json, but it looked quite well done. I really liked how the values were rolled up in lists.
For MVC 4, but I couldn’t find where ACK was being used to determine success or successwithwarning so I couldn’t hook into that.
I have also found the PayPal content to be like trying to drink from a fire hose at full blast -- not only was the content was hopelessly outdated (Web Forms code, FTW!) but there was also so many different examples it would have taken me days to determine which one was most appropriate to use.
Any assistance would be greatly appreciated.
Edit: my initial attempt at modifying the linked code has this portion:
values = Submit(values);
var ack = values["ACK"].ToLower();
if(ack == "success" || ack == "successwithwarning") {
using(_db = new ApplicationDbContext()) {
var updateOrder = await _db.Orders.FirstOrDefaultAsync(x => x.OrderId == order.OrderId);
if(updateOrder != null) {
updateOrder.OrderProcessed = false;
updateOrder.PayPalCorrelationId = values["CORRELATIONID"];
updateOrder.PayPalTransactionId = values["TRANSACTIONID"];
updateOrder.PayPalTimeStamp = values["TIMESTAMP"];
updateOrder.IPAddress = HttpContext.Current.Request.UserHostAddress;
_db.Entry(updateOrder).State = EntityState.Modified;
await _db.SaveChangesAsync();
}
}
return new PayPalRedirect {
Token = values["TOKEN"],
Url = $"https://{PayPalSettings.CgiDomain}/cgi-bin/webscr?cmd=_express-checkout&token={values["TOKEN"]}"
};
}
Everything within and including the using() is my added content. As I mentioned, the CorrelationId and the TimeStamp come through just fine, but I have yet to successfully obtain the TransactionId.
Edit 2:
More problems -- the transactions that are “successful” through the sandbox site (the ReturnUrl is getting called) aren’t reflecting properly on my Facilitator and Buyer accounts, even when I do payments straight from the buyer’s PayPal account (not using the Credit Card). I know I am supposed to see transactions in the Buyer’s account, either through the overall Dev account (Accounts -> Profile -> balance or Accounts -> Notifications) or through the Buyer’s account in the sandbox front end. And yet -- multiple transactions returning me to the ReturnUrl path, and yet no transactions in either.
Edit 3:
Okay, this is really, really weird. I have gone over all settings with a fine-toothed comb, and intentionally introduced errors to see where things should crap out. It turns out that the entire process goes swimmingly - except nothing shows up in my notifications and no amounts get moved between my different accounts (Facilitator and Buyer). It’s like all my transactions are going into /dev/null, yet the process is successful.
Edit 4: A hint!
In the sandbox, where Buyer accepts the transaction, there is a small note, “You will be able to review the transaction before completing it” or something like that -- suggesting that an additional page is not coming up and that the user is being uncerimoniously dumped back to the success page. Why the success page? No clue. But it’s happening.
It sounds like you are only doing the first part of the process.
Express Checkout consists of 3 API calls:
SetExpressCheckout
GetExpressCheckoutDetails
DoExpressCheckoutPayment
SEC generates a token, and then you redirect to PayPal where the user signs in and reviews the transactions before agreeing to pay.
They are then sent to the ReturnURL included in your SEC request, and this is where you'll call GECD in order to obtain all the buyer details that are now available since they signed in.
Using that data you can complete the final DECP request, which is what finalizes the procedure. No money is actually processed until this final call is completed successfully.
I'm trying to get the a list of current hotel prices but I can't get my API Key to work. I've had it for a couple days so I know it isn't too new. I even tried the example in the docs (after fixing the dates):
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2/UK/EUR/en-GB/27539733/2016-12-04/2016-12-10/2/1?apiKey=myKey
While it worked for the demo key it wouldn't work for mine. I also tried it on the ec2 micro I'm using for testing with Python and get a response with u'{"errors":["ApiKey invalid"]}':
SKY_SCAN_URL = "http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2/"
sky_key = get_sky_scan_key()
def get_hotels(request):
entityid = request.GET['entityid']
checkindate = date_formatter(request.GET['start'])
checkoutdate = date_formatter(request.GET['end'])
rooms = request.GET['rooms']
guests = request.GET['guests']
FINAL_SKY_URL = "%s/%s/%s/%s/%s/%s/%s/%s/%s/?apiKey=%s" % (
SKY_SCAN_URL, 'US', 'USD', 'en-US', entityid, checkindate, checkoutdate, guests, rooms, sky_key)
sky_response = requests.get(FINAL_SKY_URL)
This function outputs a get request with a URL like this:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v2//US/USD/en-US/20.7983626,-156.3319253-latlong/2016-09-07/2016-09-14/1/1/?apiKey=myKey
Any advice on what the possible issue could be would be awesome, thanks!
Edit:
To be more specific I'm looking for reasons why my API Key is invalid. I'm not familiar with skyscan and while I've added an app from the skyscanner dashboard by clicking the travel api and copied the key into my project and directly into a valid url my key is showing as bad. Are there any additional steps or things that I need to take into account?
I don't know about how you're creating the URL but it seems like it shouldn't be built that way. (most likely due to their misleading documentation)
This:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/?apiKey=myKey&checkoutdate=2016-09-14&checkindate=2016-09-07¤cy=USD&rooms=1&entityid=20.7983626%2C-156.3319253-latlong&local=en-US&market=US&guests=1
Should be:
http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/US/USD/en-US/20.7983626,-156.3319253-latlong/2016-09-07/2016-09-14/1/1/?apiKey=myKey
Your code should be something like:
SKY_SCAN_URL = "http://partners.api.skyscanner.net/apiservices/hotels/liveprices/v3/"
FINAL_URL = "%s/%s/%s/%s/%s/%s/%s/%s/%s/?apiKey=%s" % (SKY_SCAN_URL, market, currency, locale, entityid, checkindate, checkoutdate, guests, rooms, apiKey)
sky_response = requests.get(FINAL_URL)
I also suggest you do some tests here.
From their help site as of 17 days ago -
https://support.business.skyscanner.net/hc/en-us/articles/209452689-Why-is-my-API-key-returning-no-results-for-hotels-
"Our Hotels API is currently being reworked, and access is not available at present. Apologies for any inconvenience, when the new API is ready for use we will update the Skyscanner for Business site, so please check back there for updates."
Unclear when this changes.
Since April 2017, skyScanner started re-working their Hotels API, thus stopping all ongoing API calls to LIVE Pricing APIs:
https://support.business.skyscanner.net/hc/en-us/articles/209452689-Why-is-my-API-key-returning-no-results-for-hotels-
Hotels and Flights Cached Pricing and Browse services still working, though I am not sure if it is enough for your business case.
It seems that Skyscanner has updated their Hotels API recently and the documentation can be found here: https://skyscanner.github.io/slate/#hotels-live-prices
Services like Uber provide users with masked phone numbers so that they can communicate directly with one another without exposing their actual phone number. It seems to me a form of network address translation?
Does anyone have services, OSS, API/code examples or SDK links that one might use to set up a similar system?
Primarily this would entail mapping/translating a generated phone number to a user's actual number (behind the scenes), but telemetry style analytics would also be desirable.
Preferably Node Javascript, C#, or Java... but anything is better than nothing!
Many thanks
Ricky from Twilio here.
We put together a tutorial on how to build masked phone numbers with Node.js, C#, Java, Python or Ruby:
https://www.twilio.com/docs/tutorials/walkthrough/masked-numbers/node/express
In this Node.js example, here's the block of code that masks a phone call:
router.post('/use-voice', twilio.webhook({ validate: false }), function (req, res) {
from = req.body.From;
to = req.body.To;
body = req.body.Body;
gatherOutgoingNumber(from, to)
.then(function (outgoingPhoneNumber) {
var twiml = new twilio.TwimlResponse();
twiml.play('http://howtodocs.s3.amazonaws.com/howdy-tng.mp3');
twiml.dial(outgoingPhoneNumber);
res.type('text/xml');
res.send(twiml.toString());
})
});
The gatherOutgoingNumber function uses the phone call from and to to determine who the user is intending to call, once that number is found this code forwards the call to the correct phone number.
It's MIT licensed and hopefully can help you get started.
I found what Uber uses... Twilio! So that's one option at least
Just wondering if it is at all possible in classic ASP/VBScript to launch a new window of the default mail client.
I have tried the following:
set objOutlk = createobject("Outlook.Application")
set objMail = objOutlk.createitem(olMailItem)
But got nothing but an error: ActiveX cannot create object: Outlook.Application.
Any advice is much appreciated.
Rob.
If you want to provide a simple way to open the default mail client message of a user viewing your (asp) page just add a mailto: hyperlink:
Send Msg
The mailto: will trigger the browser to open the default (or configured) mail client.
You can append a query string defining the subject line and the mail body - in my example the subject is "Hello World" and the body text is "Hi there".
Notice the blanks are url-encoded to %20
After a little thought (thanks to some of you guys for the prompt) it made sense to run this client side and I used the following JScript:
<script type="text/javascript">
function send() {
alert("clicked")
var recpt = "info#example.ccTLD"
var subj = "FASTER BETTER SOONER: Look at Monash Rowville rail now"
var text = "<Enter your name and address here> %0D%0DMelbourne is growing and more people need transport. With concern about climate change and rising petrol prices, Melbourne's growth is not sustainable without more and better public transport.%0D%0DVictorians want more people catching public transport, cycling and walking; fewer trucks on our roads, more freight on rail; and fewer kilometres travelled by car and truck.%0D%0DPublic transport should: be fast, frequent, reliable, affordable and safe; grow as Melbourne grows; be available to all Melbournians; and be managed as an integrated, co-ordinated network.%0D%0DThis means bringing forward existing public transport projects, committing to new projects and accelerating programs to move freight off our roads and onto rail.%0D%0DIt also means looking very closely at the impact on greenhouse gas emissions of any new transport projects like tunnels and freeways.%0D%0DWe especially urge you to look at a feasibility study for a Monash Rowville rail line. %0D%0DAs Melbourne's population grows, better public transport will both reduce traffic congestion and provide a much needed antidote to spiralling petrol prices. "
var bcc = "people#example.ccTLD"
var content = new Array()
content[0] = "mailto:"
content[1] = recpt
content[2] = "?subject="
content[3] = subj
content[4] = "&body="
content[5] = text
content[6] = "&bcc="
content[7] = bcc
content = content.join("")
window.location = content
}
This seems to the results I expected.
Rob
I've managed to implement the Name.NameCtrl.1 active x used in sharepoint in my own custom built apps for presence. All is working fine and I'm updating presence status correctly based on a users status on Office Comunication Server. However I'm not getting any other details on the user propulated in the presence control like it does in SharePoint. All I get is the sip address in the email field (rather than the real default email address in AD) and a link to schedule a meeting.
Can anyone tell me how to get the control to populate with details from AD (dept, email, phone etc) like it does in sharepoint?? Also I don't get an organization tab in the control like sharepoint.
Any ideas?
Thanks,
Keeney
NameCtrl gets the majority of its data from the running instance of Communicator (or Lync, if you're using that) on the client machine. No data is directly pulled back from SharePoint. To have NameCtrl work properly on your web pages, you need to make sure that:
Communicator (or Lync) is running on the client, and signed in
The web page you are calling NameCtrl from is in the Intranet or Trusted Sites zone in your browser
The recommended pattern is to call PresenceEnabled on the NameCtrl object before calling any other methods - if this returns false, then one (or both) of the above prereqs is false. The code below generally works for me
<script>
var sipUri = "your.contact#your.domain.com";
var nameCtrl = new ActiveXObject('Name.NameCtrl.1');
if (nameCtrl.PresenceEnabled)
{
nameCtrl.OnStatusChange = onStatusChange;
nameCtrl.GetStatus(sipUri, "1");
}
function onStatusChange(name, status, id)
{
// This function is fired when the contacts presence status changes.
// In a real world solution, you would want to update an image to reflect the users presence
alert(name + ", " + status + ", " + id);
}
function ShowOOUI()
{
nameCtrl.ShowOOUI(sipUri, 0, 15, 15);
}
function HideOOUI()
{
nameCtrl.HideOOUI();
}
</script>
<span onmouseover="ShowOOUI()" onmouseout="HideOOUI()" style="border-style:solid">Your Contact</span>
In case you haven't already seen it, there is a good(ish) NameCtrl reference here
I think in SharePoint, the control is populated with data that exists in the user profile service. If you want this in a non-sharepoint ASP.NET web app, then you'd have to build a repository of user profile details from AD (and cache it!) which your control will look to to display that information.