Why cant i use serveo instead of ngrok to tunnel connection to a mvc application hosted on EC2 server for receiving SMS on Twilio - c#

I have a simple asp.net mvc web application which listens for a message and replied back with a standard response. It uses the Twilio API and in
Here is the code:
// Code sample for ASP.NET MVC on .NET Framework 4.6.1+
// In Package Manager, run:
// Install-Package Twilio.AspNet.Mvc -DependencyVersion HighestMinor
using Twilio.AspNet.Common;
using Twilio.AspNet.Mvc;
using Twilio.TwiML;
namespace WebApplication1.Controllers
{
public class SmsController : TwilioController
{
public TwiMLResult Index(SmsRequest incomingMessage)
{
var messagingResponse = new MessagingResponse();
messagingResponse.Message("The copy cat says: " +
incomingMessage.Body);
return TwiML(messagingResponse);
}
}
}
For the code to run, Twilio suggests me "While there are a lot of ways to do this, like deploying your application to Azure or AWS, you'll probably want a less laborious way to test your Twilio like ngrok to allow Twilio to Talk to Your ASP.NET Application"
I have used ngrok, which allows me to expose my local environment to the whole public internet which can then be accessed by URL provided by ngrok,
but the free version keeps changing the subdomain whenever I restart my ec2 server (thus restarting the ngrok tunnel).
What I would like to know is I tried an alternate called serveo which allowed me to chose a subdomain for free, but the URL generated it given an error (400) when I send a message to Twilio.
Is there a way around? I m new to the world of asp.net mcv web application and Twilio and would really appreciate some guidance.
I just need this code to keep running so that it can listen for SMS and respond back.
If not, How can I deploy it on AWS? Which would provide me with an URL to feed to the Twilio's console

The reason 'serveo' isn't working is because (I believe) you are using IIS Express which doesn't allow requests with host header's other than localhost.
'ngrok' has a way around that, as does our free VS Extension called Conveyor. Conveyor at the moment has tunnelling in beta, but it is stable and subdomains are fixed. You can download it from the Extensions menu in VS or marketplace. Here's a tutorial for Twilio https://conveyor.cloud/Help/Writing_webhooks_on_localhost_with_Visual_Studio_and_IIS_Express

Related

403 Message: Legacy People API has not been used in project [duplicate]

This question already has an answer here:
Legacy People API has not been used in project
(1 answer)
Closed 1 year ago.
Google API is active but give error ;
Legacy People API has not been used in project before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/legacypeople.googleapis.com/overview?project= then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
You don't need to install any other APIs like Google Drive API, Google Sheets API or other except Google+ API,
The error is coming because of "passport-google-oauth": "^1.0.0"
Just change the version "passport-google-oauth": "^1.0.0" to "passport-google-oauth": "^2.0.0" and remove node_modules and package.lock.json file and run "npm i"
That's it
Before the Google+ API Shutdown on March 7, 2019, the people.get and people.getOpenIdConnect methods were available for requesting a person’s profile.
To avoid breaking existing integrations with these methods supporting sign-in, a new minimal implementation only returns basic fields necessary for that functionality, such as name and email address, if authorized by the user. The Legacy People API is where these methods will remain available for existing callers at the existing HTTP endpoints.
The Legacy People API serves a limited new implementation of the legacy Google+ API people.get and people.getOpenIdConnect methods necessary for maintaining sign-in functionality. It is available to existing callers of the original methods that haven't migrated to recommended replacements such as Google Sign-in or Google People API at the time of the Google+ API shutdown.
enter link description here
Thanks
In this case, I'm facing the same issue. This is what I've done to fix it.
Situation:
NodeJS ver 8
"passport-google-oauth": "^1.0.0"
Using Google+ API as Google Sign-in
When I run the apps and click Sign in with Google, what happened then?
Server error
Error log: Legacy People API has not been used in project "xxxx" before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/legacypeople.googleapis.com/overview?project=xxxx then retry.
How I solve it?
Go to Google Console
Click on Google+ API under Social APIs, then click Enable API
Click on Google Drive API under G Suite, then click Enable API
Click on Google Sheets API under G Suite, then click Enable API
Update "passport-google-oauth": "^1.0.0" to "passport-google-oauth": "^2.0.0"
in package.json
remove package-lock.json and node_modules folder (to ensure everything is clear)
run this command : npm install
It works now!
Note: my previous code still using profile._json.image.url to get profile image. Actually, this response was not there anymore. So I delete this code.
Goodbye Google+
Thank you Google People API.
Enabling the Google Contacts API and the Google+ API fixed this issue for me.
Hi I recently stumbeled on the same issue. As explained by Ilan Laloum, Google+ API as been decommissionned completely for new projects.
I found that Google People API works in a similar way. The following example is based on the Bookshelf tutorial in GCP. Source code can be seen here: https://github.com/GoogleCloudPlatform/golang-samples/tree/appengine/go111/cloudsql/getting-started/bookshelf (branch appengine/go111/cloudsql)
import people "google.golang.org/api/people/v1"
...
// retrieves the profile of the user associated with the provided OAuth token
func fetchProfile(ctx context.Context, tok *oauth2.Token) (*people.Person, error) {
peopleService, err := people.NewService(ctx, option.WithTokenSource(bookshelf.OAuthConfig.TokenSource(ctx, tok)))
if err != nil {
return nil, err
}
return peopleService.People.Get("people/me").
PersonFields("names,coverPhotos,emailAddresses").
Do()
}
This method needs a context and a OAuth token, just like Google+ API used to. The peopleService is initialized in a similar fashion.
The peopleService.People.Get("people/me") prepares a query that fetches the profile of the connected user. Then PersonFields("names,coverPhotos,emailAddresses") is a filter on profile fields. This part of the request is mandatory. Eventually Do() will execute the request.
This issue can be fixed using the passport-google-token
npm install passport-google-token
const GoogleStrategy = require('passport-google-token').Strategy;
// Google OAuth Strategy
passport.use('googleToken', new GoogleStrategy({
clientID: CLIENT_ID,
clientSecret: CLIENT_SECRET
}, async (accessToken, refreshToken, profile, done) => {
try {
console.log('creating a new user')
const newUser = new User({
google: {
id: profile.id,
email: profile.emails[0].value
}
});
await newUser.save();
done(null, newUser);
} catch (error) {
done(error, false, error.message);
}
}));
I was also having the same issue but with my Rails app. So I resolved it by upgrading the omniauth gems by running bundle update devise omniauth omniauth-google-oauth2 in terminal.
I also faced the same issue. This issue may occur for using the old library, enable the google people Api for your project, and download the library as per your php version from this link and integrate it.

Twilio testing outbound call with ngrok

I'm trying to test my outbound calling via Twilio, using my Twilio "test" credentials. It's an ASP.NET MVC 4 Web app that is hosting the endpoints for Twilio to hit. Since I'm running on localhost, they will be hit via ngrok (public endpoint that routes to your localhost).
I have configured a [toll-free] phone number in twilio where voice requests route to my ngrok url.
When I try to execute my test outbound call in my web app, I navigate to a test controller. It fires off some code that ends up executing this:
var call = _client.InitiateOutboundCall(
new CallOptions
{
From = "+1" + _fromPhone, // twilio toll-free phone number with base site/ngrok url configured, ie http://{ngrokcode}.ngrok.io
To = "+1" + phoneNumber, // phone that I want to "answer" and listen to the message
Url = url, // ngrok url that points to my localhost endpoint to play message, ie http://{ngrokcode}.ngrok.io/message/{forCustomerId}
IfMachine = "Continue"
});
In this call, the "_fromPhone" is the phone number that I have purchased/configured in twilio, the toll-free number, which is what routes to my ngrok url.
The "phoneNumber" is the phone that I want to call
The "url" is the endpoint that I want twilio to hit so it can "Say" the message to the recipient.
But, using these test credentials, the phone call never goes out. I accidentally ran this same thing, but using the production credentials, and the phone call DID go out (and started ringing on my cell phone), but when I answered, it was silent for about 15 seconds, then it finally said twilio encountered an error.
Looking at the logs for the accidental production call, it said it couldn't connect to my [ngrok] url.
So, two questions, why isn't the phone call getting executed when using my test credentials? And, if/when the phone call goes out, why isn't it executing/hitting my endpoint that contains my "Say" verbs?
Twilio developer evangelist here.
Test credentials are not used to make test calls, they are used to ensure that calls to the API are working as expected and will not generate calls themselves. The docs say:
When you authenticate with your test credentials, we will not charge your account, update the state of your account, or connect to real phone numbers.
As for when you made the call with your real credentials, there's more to look into here.
15 seconds is the timeout that Twilio will wait for when trying to connect to an endpoint. This suggests to me that ngrok was working and proxying the request but that your web application was hanging or taking too long to respond.
Can you hit your ngrok endpoints from a browser (or Postman or curl)? Is your web application logging anything that might help when you do access it? Does the ngrok dashboard (available at http://127.0.0.1:4040 when ngrok is running) give you any more insight.
Let me know and I'll update my answer with more suggestions.

Azure Notification Hubs Register Device Error 404

This is the first time I'm using Azure Notification Hubs and I'm having some trouble getting it working properly with my application.
The part I'm stuck on (at the moment) is registering my device with the notification hub. I'm using the backend method to do the registration ... that is, I'm creating an Installation object and using the CreateOrUpdateInstallationAsync method to register the device via my Web API. I'm only testing it at this stage so I'm hitting my API endpoint with dummy data via Postman.
When I step through my code, I'm getting the following error when I execute CreateOrUpdateInstallationAsync ...
The remote server returned an error: (404) Not Found. Entity does not
exist.TrackingId:203cba37-007d-4dcb-ae25-ced33fa012aa_G1,TimeStamp:2/4/2018
10:24:02 PM
I've tested that I am connecting to the Notification Hub correctly by calling GetAllRegistrationsAsync. This returns an empty list (expected) and no error ... so I have my endpoints set up correctly. I'm wondering if there is a problem with my dummy data? For the installation Id, I've just created a random GUID (Guid.NewGuid). The Device ID and Push Notification Handle are random numbers and letters. And I'm testing this for the Android platform (NotificationPlatform.Gcm).
Has anyone seen this error before and know what it means? Am I able to just use random data for testing purposes (I'm only interested in registering devices at this stage) or do I need legitimate data (real device id's, etc)?
Thanks in advance.
The CreateOrUpdateInstallationAsync method would essentially invoke the REST API Create or Overwrite an Installation. When you register with a notification hub from your custom backend using the Installation, the core code would look like as follows:
NotificationHubClient hubclient = NotificationHubClient.CreateClientFromConnectionString(listenConnString, hubName);
await hubclient.CreateOrUpdateInstallationAsync(installation);
Note: You could install the Microsoft.Azure.NotificationHubs package for back end operations.
For a simpler way, I just created a console application and test this operation as follows:
Note: I just created a new Azure Notification Hub and did not set any notification settings. And I set a GUID as the InstallationId and a random string as the PushChannel, the rest operation could work as expected.
And I could retrieve the previous added registration as follows:
Has anyone seen this error before and know what it means? Am I able to just use random data for testing purposes (I'm only interested in registering devices at this stage) or do I need legitimate data (real device id's, etc)?
The operation could work on my side, I would recommend you debug your application and leverage fiddler to capture the network traces to narrow this issue. Moreover, you could follow Registration management for more details about registering devices with azure notification hubs.
Ok, it turns out that I had the wrong value for Hub Name when instantiating the NotificationHub object using NotificationHubClient.CreateClientFromConnectionString. I was using the namespace, instead of the hub name (visible on the Overview tab in the Azure Portal).

SignalR 2.0 - 400 Bad Request

Installed signalR sample nuget package into an existing MVC app. When negotiating connection I get the following error randomly:
NetworkError: 400 Bad Request - http://localhost:19000/signalr/connect?transport=serverSentEvents&clientProtocol=1.5&connectionToken=GXM1JG%2B8qT13Q5DRblCFTVqQL1OrRS9dvSJ2hoYTEo9aghcvO0aQbKPUW9hC%2Bw4%2FpKfpmLRNcpCeJEnS4WkON%2F3JxjUshiaRRBf5UzoAsjZSmJdn&connectionData=%5B%7B%22name%22%3A%22stockticker%22%7D%5D&tid=7"...
Other times, I'm able to establish connection just fine.
I've noticed this is due to ConnectionToken containing a "+" sign
Does not work:
"ConnectionToken":"+S981mX0eUA2mfsuMB2nFO9ufg/47e2RAjOA38BS5ZQ14mfdeb8uNyk28UEe+7RmLYKHIuWi+9dTo5v3r8G8j3u6rmTavzt87jqKabhlHTue6Wqi"
connectionToken=%2BS981mX0eUA2mfsuMB2nFO9ufg%2F47e2RAjOA38BS5ZQ14mfdeb8uNyk28UEe%2B7RmLYKHIuWi%2B9dTo5v3r8G8j3u6rmTavzt87jqKabhlHTue6Wqi
Works:
"ConnectionToken":"zBvrOSuqziot9pJXKfAxpXfPMYY4pI/069Ks/uDoOwm8YYydTParbim7o3YiyrM4NInLJ7wKzwc3YXAlb3sVUq/R0abV2OSOzMydbgUYMPfawEDv"
connectionToken=zBvrOSuqziot9pJXKfAxpXfPMYY4pI%2F069Ks%2FuDoOwm8YYydTParbim7o3YiyrM4NInLJ7wKzwc3YXAlb3sVUq%2FR0abV2OSOzMydbgUYMPfawEDv
In contrast, I've created a brand new MVC app and installed SignalR Nuget sample-this time however everything works just fine.
What could be potential causes of such behavior in my existing app?
This issue was related to one of the existing IHTTPModules that was rewriting URL in the http request cycle and it was not related to SignalR.

SignalR Negotiate 404 on Subdomain

I've created a small MVC SignalR app which I'm having trouble running on my server under a subdomain:
http://chat.mydomain.com, which maps to a folder called /chat.
I've also made a console program using SignalR Client which connects and works perfectly, strangely enough.
The error from the MVC app is a 404 from http://chat.mydomain.com/chat/signalr/negotiate?clientProtocol=[...]. I can see why this is happening but have no idea how to fix it. In my generated hubs file, the line
signalR.hub = $.hubConnection("/chat/signalr", { useDefaultPath: false });
is technically correct, but should read $.hubConnection("/signalr", { useDefaultPath: false });
Any ideas on how to alter this? Or should I just use the raw connection API.
Also why does it work properly from the console app?
Thanks in advance.
You can continue to use the generated hubs file. You just need to modify the hubConnection's url (which stored at $.connection.hub.url) before you start your SignalR connection.
// This is initially set to "/chat/signalr" as specified in the hubs file
$.connection.hub.url = "/signalr";
$.connection.hub.start()...

Categories