How to test receiving a Stripe webhook using ngrok - meteor

I can successfully send a web hook from Stripe to my Meteor app in development using ngrok. For example, my test endpoint on the Stripe dashboard would be sent to something like https://f5f62fdf.ngrok.io. It responds with a successful notice. The ngrok inspector shows the stripe test object received. But in Meteor I'm a little unsure how the router should look with ngrok. On the server, my route would be something like:
Router.route( "<unsure what path to put here>", function() {
console.log('hello');
}, { where: "server" });
In my testing environment using ngrok, what would the path be?
Just trying to get the function to console.log() my 'hello' so I know it's working.

OK, I'm an idiot. It console.logs to the terminal, not the browser. Ouch. Given I'm working with Node, it makes sense. Just for posterity, the Stripe endpoint would be something like https://g4r62fdf.ngrok.io/stripe/webhook.
Make sure you're returning a response inside the function so the web hook won't timeout.
this.response.statusCode = 200;
this.response.end('10-4, good buddy');

Related

Next.JS - localhost is prepended when making external API call

I got a simple Next app where I'm making an external API call to fetch some data. This worked perfectly fine until a couple days ago - when the app is making an API request, I can see in the network tab that the URL that it's trying to call, got Next app's address (localhost:3000) prepended in front of the actual URL that needs to be called e.g.: instead of http://{serverAddress}/api/articles it is calling http://localhost:3000/{serverAddress}/api/articles and this request resolves into 404 Not Found.
To make the API call, I'm using fetch. Before making the request, I've logged the URL that was passed into fetch and it was correct URL that I need. I also confirmed my API is working as expected by making the request to the expected URL using Postman.
I haven't tried using other library like axios to make this request because simply it doesn't make sense considering my app was working perfectly fine only using fetch so I want to understand why is this happening for my future experience.
I haven't made any code changes since my app was working, however, I was Dockerizing my services so I installed Docker and WSL2 with Ubuntu. I was deploying those containers on another machine, now both, the API I'm calling and Next app are running on my development machine directly when this issue is happening.
I saw this post, I confirmed I don't have any whitespaces in the URL, however, as one comment mentions, I installed WSL2, however, I am not running the app via WSL terminal. Also, I've tried executing wsl --shutdown to see if that helps, unfortunately the issue still persists. If this is the cause of the issue, how can I fix it? Uninstall WSL2? If not, what might be another possible cause for the issue?
Thanks in advance.
EDIT:
The code I'm using to call fetch:
fetcher.js
export const fetcher = (path, options) =>
fetch(`${process.env.NEXT_PUBLIC_API_URL}${path}`, options)
.then(res => res.json());
useArticles.js
import { useSWRInfinite } from 'swr';
import { fetcher } from '../../utils/fetcher';
const getKey = (pageIndex, previousPageData, pageSize) => {
if (previousPageData && !previousPageData.length) return null;
return `/api/articles?page=${pageIndex}&limit=${pageSize}`;
};
export default function useArticles(pageSize) {
const { data, error, isValidating, size, setSize } = useSWRInfinite(
(pageIndex, previousPageData) =>
getKey(pageIndex, previousPageData, pageSize),
fetcher
);
return {
data,
error,
isValidating,
size,
setSize
};
}
You might be missing protocol (http/https) in your API call. Fetch by default calls the host server URL unless you provide the protocol name.
Either put it into env variable:
NEXT_PUBLIC_API_URL=http://server_address
Or prefix your fetch call with the protocol name:
fetch(`http://${process.env.NEXT_PUBLIC_API_URL}${path}`, options)

How do you initialize the Twilio Client in Meteor JS?

I'm having incredible difficulty setting up the Twilio Client in Meteor JS, and would really appreciate any help.
I have extracted the relevant code and error logs below. So far as I can tell, it should be simple. The code is just grabbing an authtoken which I have previously generated, and then trying to set up the device using that authtoken. But it's not working.
'click #initializeDevice'(event) {
var thisAuthToken = Session.get('myAuthToken');
console.log(thisAuthToken); // I have confirmed with Twilio support that these authtokens are correctly generated
const Device = require('twilio-client').Device;
Device.setup(thisAuthToken, { debug: true });
var myStatus = Device.status()
console.log(myStatus); //this is logging "offline"
Device.on('ready',function (device) {
log('Twilio.Device Ready!'); //this is not logging anything
});
},
When that code runs, it generates the following logs:
eyJhbGciDpvdXRnb2luZz9hcHBTaWQ9QVA2NDE2MzJmMzA1ZjJiY2I[Note:I have deleted part of the middle of the logged authtoken for the purpose of this public post]5YmMxOGQyOWVlNGU2ZGM0NjdmMzRiNDVhNCIsImV4cCI6MTU3Nz0ygbJKTx15GgNCWDkm-iUPjn_O1NZU6yovp4vjE
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 Setting up VSP
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 WSTransport.open() called...
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 Attempting to connect...
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 Closing and cleaning up WebSocket...
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 No WebSocket to clean up.
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 Could not connect to endpoint: ws does not work in the browser. Browser clients must use the native WebSocket object
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 Closing and cleaning up WebSocket...
modules.js?hash=69069bec9aeba9503ae3467590cf182be57d9e62:3605 No WebSocket to clean up.
calltemplate.js:31 offline
I'm doing this all from a local server, tunneled through NGROK. I've also set up the Twilio back end, linked the app, purchased a number, etc.
So far as I can tell, the issue, from the logs, appears to be something to do with the way that Meteor uses WebSockets.
Could not connect to endpoint: ws does not work in the browser. Browser clients must use the native WebSocket object
This is a not a Meteor related problem rather than browser issue.
Make sure your browser supports WebRTC
BTW, Your browser might be supporting it but you'd need to enable it.

send grid & parse 502 Bad Gateway with nginx

I am trying to migrate my parse application over to digital ocean and followed this guide :
https://www.digitalocean.com/community/tutorials/how-to-migrate-a-parse-app-to-parse-server-on-ubuntu-14-04
Everything works perfectly fine until I get to the very end Test Parse Server ( Executing Example Cloud Code ) section
I tested the cloud code for the sample cloud code that was provided in the tutorial :
Parse.Cloud.define('hello', function(req, res) {
res.success('Hi');
});
so I got a Hi back in my browser as well as in postman.
See image here : https://cloudup.com/cH2dbBx1KTo

Then I test the function that uses sendgrid's service to send emails (http://blog.parse.com/announcements/introducing-the-sendgrid-cloud-module/), my cloud code file looks like this :
see image : https://cloudup.com/cD6MNRP3Tft
and now I try to run my post request from postman and I get an error even on my hello function that was working before
See image : https://cloudup.com/cIkwJ6552_5
So I look around and figure out that its an issue with my sendgrid import
var sendgrid = require("sendgrid");
sendgrid.initialize(“xxxxxx”, “xxxxx.”);
in these lines.
does anyone have any experience with digital ocean cloud code and send grid emailing service please help me out I will be grateful as this is the last step left and I will be done with my migration :)
cheers
Tanzeel
you have to specify server URL in parse config file. It is required and could be the reason why you cant run cloud code.
"PARSE_SERVER_URL": "http://localhost:1337/parse"
The url has be the same what you are using. There is also error in Nginx config in that tutorial, I explained it here https://serverfault.com/questions/765627/cannot-post-get-over-ssl/766428#766428
So I looked up at pm2 and to see real-time logs the command is
pm2 logs
at first when I ran the command I saw some errors, maybe they were there from before :
Then I tried the hello cloud function from postman app to test for its output in pm2 logs and I got the following :
Next I try to run my sendMail sendgrid function and I find out the the api-key I had used in my sendgrid function was throwing an error
ReferenceError: XXXXXXXXXXXX is not defined
So I went back to my cloud code and used quotes around my api-key parameter and passed it as a string in my send grid initialize function. Then I retry and get
[Error: The provided authorization grant is invalid, expired, or revoked]
So I went back to my sendgrid account and made sure that the api-key I was using was the correct one and it seemed to be just fine. I tested again and got the same error again so I decided to generate a new api-key just in case.
So I realize that I was not using the api-key but instead API KEY ID :
When we create a new api-key on sendgrid they give us the actual api key once and they ask us to store it in some secure place :
We can only display the key above one time. Please store it somewhere safe because as soon as you navigate away from this page, we will not be able to retrieve or restore this generated token.
So after I used an actual api-key I was able to send emails 😃
But one small issue still remains and I am not sure if its because of postman that I am using to run cloud code or something in the parse server or nginx that is still returning me with a 502 Bad Gateway as a response
But when I look at the logs for my parse server I do see a
parse-wrapper-0 { message: 'success' }
but it never gets back to me in my postman and instead I am getting a 502 error not sure why but the emails are being sent succesfully :)

External use of Meteor method? (to receive SMS from Nexmo)

In my Meteor application I want to receive text messages through Nexmo. How do I create the callback function? I'm thinking of something like
Meteor.methods
'receive_sms': (values) ->
console.log values
But http://hitchticker.meteor.com/receive_sms doesn't really work of course. I can see my method is working when I do Meteor.call('receive_sms', 'test') in my browser, but the network debugger is not really giving me a lot of useful information. The Meteor docs aren't very helpful either.
How do I access the method from elsewhere?
Iron Router and then server side routes. Something like:
Router.route('/download/:file', function () {
// NodeJS request object
var request = this.request;
// NodeJS response object
var response = this.response;
this.response.end('file download content\n');
}, {where: 'server'});
In order to receive sms from nexmo you should make the callback (incoming url) available over the internet. Nexmo won’t be able to call localhost to send the incoming sms messages.
Here are some resources to tunnel request over the internet to localhost.
https://ngrok.com/
http://localtunnel.me/
https://pagekite.net/

Accept post request with iron router

I'm trying to accept a post request from my twilio account to my application to get an xml response back. How do I respond to an incoming post request in iron router? I have read the docs and tried everything in there but I just get (Error: Not implemented on server yet). I have tried putting it on the server, on the client and in lib.:
Router (lib/router.coffee)
Router.route('/api/twilio/voice', where: 'server')
.post -> console.log 'hey'
This is due to having this.subscribe then .wait()s configured for both server and client. Look for .wait within your Router configuration scopes and make sure it only runs at the client.
Look at the code part where this happens at the iron-controller repo:
https://github.com/EventedMind/iron-controller/blob/devel/lib/controller_server.js
Also I think a better way to debug (instead of console.log) is to actually use this.response:
Router.route('/api/twilio/voice', { where: server })
.post(function() {
this.response.end('hey');
});
or even the classic format:
Router.route('/api/twilio/voice', { where: server })
.post(function(req, res, next) {
res.end('hey');
});
Edit: Issue filed here and PR here.

Resources