Here is what I want to do:
When an item is created within a certain app, a webhook sends the data contained within that item to an external application
Same thing happens what an item is edited or deleted
Naturally, I'm using the native Podio webhooks. I made a hook for item.create, item.update, and item.delete. The external URLs are correct and clicking the "verify" button sends a successful call to the external app.
However, none of the actions actually work. I've created, changed, and deleted items - nothing. Only clicking the "verify" button causes any communication with the external app.
What are some common reasons why this might not be working?
Have you activated that webhook? From Podio documentation https://developers.podio.com/examples/webhooks
Before your webhooks becomes active the URL must be verified. Immediately after the webhooks is created a hook.verify notification is sent to the URL endpoint. The endpoint must then return the code to the validation operation. Events will only be sent to the endpoint after a completed verification.
Example with command line curl:
Please remember to inject correct access_token, hook_id and verification_code
curl -H "Content-Type: application/json" -H "Authorization: OAuth2
[access_token]" -X POST -d "{'code': [verification_code]}"
https://api.podio.com/hook/[hook_id]/verify/validate
Here's how I managed to verify my Node.JS webhook endpoint and make it active using Express.JS:
const express = require("express");
const app = express();
const https = require('https');
app.use(express.urlencoded());
app.use(express.json());
app.post('/', function(request, response){
console.log( "POST", request.body);
// VERIFICATION >>
const postData = JSON.stringify({ code: request.body.code });
const options = {
hostname: 'api.podio.com',
port: 443,
path: '/hook/' + request.body.hook_id + '/verify/validate',
method: 'POST',
headers: {
'content-type': 'application/json',
'accept': 'application/json'
}
};
const req = https.request(options, (res) => {
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.write(postData);
req.end();
// << VERIFICATION
response.send(request.body);
});
app.listen(443);
Related
I'm trying to set up a Calendly webhook to retrieve real-time data as soon as the user submits a Calendly appointment
This is my nodejs express server code
const port = process.env.PORT || 5000;
const express = require('express');
const axios = require('axios');
const app = express();
const API_KEY = 'MY_API_KEY';
const TOKEN = 'MY_TOKEN';
app.post('/calendly-webhook', (req, res) => {
// Retrieve real-time data from the request payload
const data = req.body;
// Log the data to the console
console.log('Calendly webhook data:', data);
res.send('Webhook received');
});
app.listen(port, () => {
console.log('Server listening on port 5000');
// Create a new webhook
axios({
method: 'post',
url: 'https://api.calendly.com/webhooks',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'X-Token-Auth': TOKEN
},
data: {
url: 'http://localhost:5000/calendly-webhook',
events: ['invitee.created']
}
})
.then(response => {
console.log('Webhook created:', response.data);
})
.catch(error => {
console.error('Webhook creation failed:', error.response.data);
});
});
I'm getting this error
] Webhook creation failed: {
[0] title: 'Resource Not Found',
[0] message: 'The requested path does not exist'
I'm really not sure what I'm doing wrong and i'm pretty much new to this
You're calling the API endpoint for creating a webhook subscription incorrectly, please refer to the documentation: Create Webhook Subscription. The request path has to be different, and you're missing some parameters.
Example of a correct call:
axios({
method: 'post',
url: 'https://api.calendly.com/webhook_subscriptions',
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`
},
data: {
url: '<public internet URL>',
events: ['invitee.created'],
organization: 'https://api.calendly.com/organizations/AAAAAAAAAAAAAAAA',
user: 'https://api.calendly.com/users/BBBBBBBBBBBBBBBB',
scope: 'user'
}
})
Note 1: You can't specify a localhost callback URL. You must specify a public internet URL. Use a service like RequestBin to capture requests during development, or a tunneling service like ngrok if you want to send requests to your local machine.
Note 2: in real code you'll probably want to dynamically fetch the organization and user that you're creating a webhook subscription for. You can call Get Current User, for example, to get that information.
Note 3: you must use OAuth Access Tokens or Personal Access Tokens to call the current version of Calendly's API. Legacy API keys are deprecated.
function delete(id, response) {
var https = require('https');
var linkpath = "/v1/endpoint/" + id + "/?token=" + AUTH_KEY;
var req = https.request({
hostname: 'api.foo.com',
port: 443,
path: linkpath,
agent: false,
method: 'DELETE',
}, (res) => {
if (res.statusCode !== 200) {
response.send('HTTP ' + res.statusCode + ' ' + res.statusMessage);
}
res.on('error', function (err) {
response.send(err);
});
res.on('end', function (data) {
response.send(data);
});
});
req.on('error', function(e) {
response.send(e.message);
});
req.end();
}
This code, adapted from my (working) code that uses a POST request to do other things with this API, nets me a status code of 500 from the endpoint.
I don't know how to debug this. I can't send the URL manually to the server because it's a DELETE operation instead of a GET or POST.
Has anyone seen this problem? Or do you have ideas on how to debug it?
Postman (https://www.getpostman.com/) is a great tool for manually sending specific HTTP requests, including DELETE!
There are all sorts of tools that will let you manually send any HTTP to the server. For instance, you can get quite a bit of information with curl, which will happily send a DELETE request.
For example:
curl -v -X "DELETE" https://jsonplaceholder.typicode.com/posts/1
will return the request and response headers as well as the body of the return value if any.
I'm running a node express server on GAE flexible environment. One of my endpoint routes should, in addition to other things, send a push notification to some users. I don't want the requesting user to wait for the external Pushwoosh push API response before continuing/getting a response, so I am calling the below code in a separate function outside of my initial request/response promise-chain. So that when this code sends the async request to Pushwoosh, my users request-response promise chain continues off on it's own and leaves the remote API call to finish by itself.
I have tested this code running node locally, and it works fine. When I deploy this exact same code to GAE, the Pushwoosh request is never sent for some reason. I cannot see any console.log of neither response or error. I have verified that all request data is correct.
What is causing this request to not being sent? Node version is 6.9.4.
var https = require('https');
var headers = {
'Content-Type': 'application/json; charset=utf-8'
};
var options = {
host: 'cp.pushwoosh.com',
port: 443,
path: '/json/1.3/createMessage',
method: 'POST',
headers: headers
};
var message = {
request: {
application: process.env.PUSHWOOSH_APP_ID,
auth: process.env.PUSHWOOSH_REST_API_KEY,
notifications: [{
send_date: 'now',
ignore_user_timezone: true,
content: 'test',
ios_badges:'+1',
android_badges:'+1',
android_priority: 2,
android_vibration: 1,
data:{
key: 'value'
}
}]
}
};
var req = https.request(options, function(res) {
res.on('data', function(data) {
console.log('Response:');
console.log(JSON.parse(data));
});
});
req.on('error', function(e) {
console.log('Error:');
console.log(e);
});
req.write(JSON.stringify(message));
req.end();
I have one problem with HTTP GET/POST request.
When I use the DHC/Postman, send the parameters to the URL + endpoint, works perfectly. 200 is returned.
But with code, like my example, show one 401 error.
I have searched about that and the problem is with the auth, not sure, see... Maybe is the same.
With this explanation, need to set the Authorization, I think. But the problem is when I access the site, the auth is automatic, see:
My code:
var jsonObject = JSON.stringify({ "UserName": login});
// prepare the header
var postheaders = {
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
// the post options
var optionspost = {
host: "xxxxxxxxxx.com",
// path: '/Home/endpoint', //send the data for the endpoit with Postma works fine
method: 'POST',
headers : postheaders
};
console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');
// do the POST call
var reqPost = http.request(optionspost, function(res) {
console.log("statusCode: ", res.statusCode);
// uncomment it for header details
// console.log("headers: ", res.headers);
res.on('data', function(d) {
console.info('POST result:\n');
process.stdout.write(d);
console.info('\n\nPOST completed');
});
});
// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
console.error(e);
});
Obs.: This website it's from my Company (.NET) and is Integrated with IIS (Active Directory login users for authenticate), when I access, automatically is logged... I really don't know how to solve this.
Obs II.: I Try to use one anonymous new tab and use DHC online, and my post doesn't work. This application just works inside network company and with Client side (Using postman with my computer).
Obs III.: The request is from Server and the login from my server have all permissions to access this site, and when I request, is like I'm anonymous, but if I did the same with REST Client/Postman, works perfectly. I need that it works with http request from my Server.
You can use a module like ntlm-webapi which will allow you to use NTLM auth. That way the request will go through. Just make sure the user you use is authorized for that server.
var Request = require('ntlm-webapi');
var request = new Request({
url: "http://some.restful.api.org/you/want/to/call",
username: 'username',
password: 'password',
domain: 'company_domain'
});
request.get(function(err, result){
if (err) console.log (err);
console.log (result);
});
It seems that you forgot to add the Authorization header in your code
// prepare the header
var postheaders = {
'Authorization' : 'Negotiate '+ yourAccessKey,
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
I have been working with node.js to set up a proxy server that will handle incoming client request and will verify that they have the proper certificates to get connected to the server.
What I want to do is to be able to add the client's certificate to their header to craft a user name, that I will pass on to the server.
function (req, res) {
//Here is the client certificate in a variable
var clientCertificate = req.socket.getPeerCertificate();
// Proxy a web request
return this.handle_proxy('web', req, res);
};
What I want to be able to do is this : req.setHeader('foo','foo')
I know that the proxy.on('proxyReq) exist, but the way the code is set up, I need to be able to use the req parameter.
Is there a way to do this?
Please let me know if I need to clarify my question.
You can craft your own http request with the headers provided in the original request plus any extra headers that you'd like by using http.request. Just receive the original request, copy the headers into the new request headers, add the new headers and send the new request.
var data = [];
var options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
data.push(chunk);
});
res.on('end', function() {
console.log(data.join(""));
//send the response to your original request
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// Set headers here i.e. req.setHeader('Content-Type', originalReq.getHeader('Content-Type'));
// write data to request body
req.write(/*original request data goes here*/);
req.end();