Sendgrid inbound parse webhook is called twice - sendgrid

I'm returning a 200 code from my webhook with this code.
response.writeHead(200, { Connection: 'close', Location: '/' });
return response.end();
For some reason, my webhook is called twice per incoming email. Any idea why?
My webhook is a firebase HTTP function.

Related

Next.js webhook returns a 301 (redirect) instead of 200

I have a Next.js app and I created an endpoint to handle a webhook from a third-party payment application.
The code for that endpoint is very simple, it checks that the order was paid and updates my database:
export default async function WebhookHandler(req, res) {
if (req.method === 'POST') {
const requestData = JSON.parse(req)
if (requestData.status === "paid") {
// Code to update database
}
res.status(200).json({ received: true });
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method not allowed.');
}
}
The problem is that this webhook is falling. When I go to my payment application logs, I can see the webhook requests are going to the right endpoint, but my endpoint response is a 301 (redirect) and the payment application expects a 200.
Any ideas why Next.js is creating this redirect? I don't even know where to look for this...
After a lot of digging, I found that it was my server configuration. It was redirecting my www.site.com to site.com 🤦‍♂️

Post request to Pardot FormHandler with Axios, CORS issue

I am trying to do post request with Axios to Pardot FormHandler, but couldn't send the data. Pardot throws CORS error. I did some search and it's looks like pardot form doesn't take any data that is coming from Axios/Ajax. So to prevent this, I tried to send it as formdata which is like below...
submit(){
var bodyFormData = new FormData();
bodyFormData.append('LastName', "test");
bodyFormData.append('FirstName', "test");
bodyFormData.append('email', "example#gmail.com");
axios({
method: 'post',
url: 'https://go.pardot.com/l/pardotformurl',
data: bodyFormData,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
},
I am sending it as formdata but still an error. By the way. If I don't use axios and just send it as a <form actions="/" method="post" /> then it's goes without a problem. But, I need to use axios for this job. So is there anyway to achieve this problem..?
Pardot doesn't support submitting data to form handlers via axios, fetch or XHR. When attempting to submit data to a form handler using that, you will likely see errors like:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '{page from which form handler should be getting submitted on client's website}' is therefore not allowed access.
This is what's known as CORS (Cross-Origin Resource Sharing). Pardot doesn't currently support CORS or JSONP for form handlers. It is possible to simulate a JSONP response by setting the Success and Error URLs for the form handler to be JavaScript URLs that execute Success and Error callbacks, respectively.

Facebook Webhook Test Button not working as expected

I have successfully added my callback url in my webhooks setup. At that time, the callback url was called successfully with proper logs and everything in the server. But when I click on the TEST button for the respective name (leadgen in this case), nothing AT ALL is being received by the server when in fact it should at least log the very first line. Note that I am using post and get.
Additional note: for NetSuite experienced developers, I am using a suitelet as the callback url for the webhook.
Thanks.
Suitelets that are available externally without login will only work if the User-Agent header in the request mimics a browser. See for example SuiteAnswers # 38695.
I ran into a similar issue, and the workaround was to proxy the request using a Google Cloud Function that simply rewrote the User Agent:
const request = require('request');
exports.webhook = (req, res) => {
request.post(
{
url: process.env.NETSUITE_SUITELET_URL,
body: req.body,
json: true,
headers: {
'User-Agent': 'Mozilla/5',
Authorization: req.headers['authorization'],
},
},
function(error, response, body) {
res.send(body);
}
);
};

Can't resolve Dropbox.com redirects with Axios or D3-fetch

I'm trying to fetch data in the browser from a Dropbox link: https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1
Using Axios this works in Node:
axios.get('https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1').then(x => {
console.log('Received correctly')
console.log(x.data);
}).catch(error => {
console.log('Error', error.message);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
}
console.log(error)
});
https://runkit.com/stevebennett/5dc21d04bbc625001a38699b
However it doesn't work in the browser (click the "Console" tab):
https://codepen.io/stevebennett/pen/QWWmaBy
I just get a generic "Network Error". I see the 301 Redirect being retrieved, which seems perfectly normal, but for some reason, it is not followed.
Exactly the same happens with D3: "NetworkError when attempting to fetch resource."
https://codepen.io/stevebennett/pen/KKKoZYN
What is going on?
This appears to be failing because of the CORS policy. Trying this with XMLHttpRequest directly fails with:
Access to XMLHttpRequest at 'https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS isn't allowed on www.dropbox.com itself.

Google Action returning Empty Speech Response

I am receiving this response from my Google Action and I am unable to figure out why an empty response would be sent out. My Intents all seem to have the right webhooks and default responses where needed.
{
insertId: "hrf6g3f6f1zhg"
labels: {
channel: "production"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/math-164823/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2018-08-01T13:05:42.164452044Z"
resource: {
labels: {
action_id: "assistant.intent.action.TEXT"
project_id: "math-164823"
version_id: ""
}
type: "assistant_action"
}
severity: "DEBUG"
textPayload: "Received response from agent with body: HTTP/1.1 200 OK
Server: nginx/1.13.6
Date: Wed, 01 Aug 2018 13:05:42 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 494
X-Cloud-Trace-Context: f0727cf8856a9fa6cbf1f0e861c14836/7685757289520895586;o=0
Google-Assistant-API-Version: v1
Assistant-Interaction-Error-Code: -1
Assistant-Interaction-Error-Message: Failed to parse Dialogflow response into AppResponse because of Empty speech response
Via: 1.1 google
Alt-Svc: clear
{
"responseMetadata": {
"status": {
"code": 10,
"message": "Failed to parse Dialogflow response into AppResponse because of Empty speech response",
"details": [{
"#type": "type.googleapis.com/google.protobuf.Value",
"value": "{\"id\":\"c132e91a-4918-4720-ae54-8deacd5bd59e\",\"timestamp\":\"2018-08-01T13:05:41.908Z\",\"lang\":\"en\",\"result\":{},\"status\":{\"code\":200,\"errorType\":\"success\"},\"sessionId\":\"1533128627128\"}"
}]
}
}
}."
timestamp: "2018-08-01T13:05:42.106660479Z"
trace: "projects/368086278893/traces/1533128627128"
}
It is very difficult to diagnose the problem without seeing all of your Intents and the code you are using in your fulfillment, but a few things to look for in this case:
Make sure your Intents either have a Response set in the response section, or the switch saying to use a fulfillment webhook is turned on.
Make sure your Intents all have a function in the webhook that is supposed to return something.
If you are making asynchronous calls (such as calls to APIs that run on other servers), make sure you are using Promises and that you are returning a Promise as part of your intent handler.
Check the logs for your webhook. Make sure there are no errors logged when it runs. If necessary, add logging to make sure you're returning what you think you're returning.
You may wish to run your webhook with a proxy, such as ngrok, in between so you can get detailed request and response logs and see the exact JSON that your code is sending back.
Turn on Dialogflow's feature to log to Google Cloud's StackDriver.
Try and enable V2 for Google Assistant in Dialogflow integration. If your Dialogflow agent is Old while integrating enable as per the below-highlighted section.
If this is not working, update your question with Dialogflow intents, Settings, Webhook code and version of the client.