Hi I setting up my webhook build with express.js in this way (the webhook is hosted on Parse.com):
var Stripe = require('stripe');
Stripe.initialize('sk_test_...');
...
app.post("/stripe", function(request, response) {
console.log("Type: "+request.body.type);
console.log("Event id: "+ request.body.id);
// Retrieve the request's body and parse it as JSON
// Verify the event by fetching it from Stripe
Stripe.Events.retrieve(request.body.id, function(err, event) {
console.log("This string is not printed on the logs");
response.send(200);
});
});
Then the test request was this, generated with changing a test user subscription in the dashboard:
{
"id": "evt_16oKcXAEHouDaR4rj8m5AtcC",
"created": 1443043065,
"livemode": false,
"type": "customer.subscription.updated",
"data": {
"object": {
"id": "sub_71zTKb8dLfo3RX",
...
"start": 1443042949
}
},
"object": "event",
"pending_webhooks": 3,
"request": "req_72PRYW2FrgFkDr",
"api_version": "2015-04-07"
}
This is my webhook log:
E2015-09-23T22:36:40.864Z]v342 Ran custom endpoint with:
Input: {"method":"POST","url":"/stripe","headers":{"accept":"*/*; q=0.5, application/xml","cache-control":"no-cache","content- length":"1358","content-type":"application/json; charset=utf- 8","host":"sceglime.parseapp.com","user-agent":"Stripe/1.0 (+https://stripe.com/docs/webhooks)","version":"HTTP/1.1","x-forwarded-for":"54.241.31.102, 10.252.11.20","x-forwarded-port":"80","x-forwarded- proto":"http"}}
Result: success/error was not called
I2015-09-23T22:36:40.974Z]Type: customer.subscription.updated
I2015-09-23T22:36:40.975Z]Event id: evt_16oLqrAEHouDaR4rpAi8FWt2
E2015-09-23T22:36:43.246Z]v342 Ran custom endpoint with:
Input: {"method":"POST","url":"/stripe","headers":{"accept":"*/*; q=0.5, application/xml","cache-control":"no-cache","content-length":"1160","content-type":"application/json; charset=utf-8","host":"sceglime.parseapp.com","user-agent":"Stripe/1.0 (+https://stripe.com/docs/webhooks)","version":"HTTP/1.1","x-forwarded-for":"54.241.34.107, 10.252.7.139","x-forwarded-port":"80","x-forwarded-proto":"http"}}
Result: success/error was not called
I2015-09-23T22:36:43.332Z]Type: invoiceitem.created
I2015-09-23T22:36:43.333Z]Event id: evt_16oLqrAEHouDaR4rcj0syMGn
On stripe logs I get an error "500 pending". Why the webhook don't respond correctly?
Thanks
Related
I'm creating a feedback bot that will send out direct messages to individuals as soon as an event on their calendar ends. For this, i've developed most of the code using appscript. I got the calendar api trigger working and i can get the same functionality working using /slash commands, but what i want is to automate this process, in that, the bot will automatically send out the message on the calendar trigger.
I'm not sure how to get this to work as i didn't find any examples or documentation to do the same. I read somewhere that google chat api doesn't allow proactively sending messages directly to users, but i have seen examples of it working.
When i try to send the message using the appscript chat api sdk, it doesn't send any message, although the flow runs successfully as i can see from the logs.
When i try using google chat rest api i'm facing errors when trying to send out a message.
The error for rest api, the error i'm seeing is :
12:10:32 PM Error
Exception: Request failed for https://chat.googleapis.com returned code 400. Truncated server response: {
"error": {
"code": 400,
"message": "Message cannot have cards for requests carrying human credentials.",
"status": "INVALID_ARGUMEN... (use muteHttpExceptions option to examine full response)
showFeedbackMessageRest # feedback.gs:105
pubsub_subscribe # feedback.gs:42
the code for the pub/sub subscriber is :
function pubsub_subscribe(e){
var service = getService();
if (!service.hasAccess()) {
var authorizationUrl = service.getAuthorizationUrl();
console.log('Authorize PubSub Service First : !!!!!!!!!!!!!!!!');
console.log(authorizationUrl);
showFeedbackMessageRest(e, {'auth_url' : authorizationUrl});
}else{
console.log('PubSub has Access!')
var project_id = get_property('PROJECT_ID');
// var topic = get_property('TOPIC');
var subscriber = get_property('SUBSCRIBER');
var url = `https://pubsub.googleapis.com/v1/projects/${project_id}/subscriptions/${subscriber}:pull`
var body = {
returnImmediately: true,
maxMessages: 1
}
var response = UrlFetchApp.fetch(url, {
method: "POST",
contentType: 'application/json',
muteHttpExceptions: true,
payload: JSON.stringify(body),
headers: {
Authorization: 'Bearer ' + getService().getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
console.log(JSON.stringify(result));
console.log(Object.keys(result).length);
if (Object.keys(result).length > 0){
var decoded = Utilities.base64Decode(result.receivedMessages[0].message.data);
var event_details = JSON.parse(Utilities.newBlob(decoded).getDataAsString());
var popup_obj = {
'summary' : event_details.EventTitle
};
console.log(popup_obj);
return showFeedbackMessageRest(e, popup_obj);
}else{
console.log('No Recent Messages!');
}
}
}
and the code to send the message using chat rest api is :
function showFeedbackMessageRest(e, event) {
var chat_service = getChatService()
var message = {};
if (!chat_service.hasAccess()) {
var authorizationUrl = chat_service.getAuthorizationUrl();
console.log('Authorize Chat Service First : !!!!!!!!!!!!!!!!');
console.log(authorizationUrl);
}else{
console.log('Chat App Has Access!');
if (event.hasOwnProperty('summary')){
message = {
"text" : `Provide Feedback For : ${event.summary}`
};
}else{
message = {
"cards_v2": [{
"card_id": "feedbackMessage",
"card": {
"header": {
"title": `Provide Feedback For : ${event.summary}`,
"subtitle": `This meeting just ended, provide feedback for the organizers to organize meetings more effectively.`,
"imageUrl": "https://raw.githubusercontent.com/google/material-design-icons/master/png/social/poll/materialicons/24dp/2x/baseline_poll_black_24dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Give Feedback",
"onClick": {
"action": {
"function": "promptQuestion",
"interaction": "OPEN_DIALOG"
}
}
}
]
}
}
]
}
]
}
}]
};
}
}
var url = 'https://chat.googleapis.com/v1/' + `${user_dm_space_name}` + '/messages';
UrlFetchApp.fetch(url, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + chat_service.getAccessToken() },
contentType: 'application/json',
payload: JSON.stringify(message),
});
}
I even tried to send a simple text message as according to the error, the cards are not allowed to be sent, but i'm getting this error :
12:30:36 PM Error
Exception: Request failed for https://chat.googleapis.com returned code 403. Truncated server response: {
"error": {
"code": 403,
"message": "This API is not accessible for external HTTP caller.",
"status": "PERMISSION_DENIED"
}
}
(use muteHttpExceptions option to examine full response)
showFeedbackMessageRest # feedback.gs:105
pubsub_subscribe # feedback.gs:42
I'm trying to send a post request in a playwright test with the following:
const testSet = await request.post('https://url/sets.json', {
data: {
"type":"sets",
"attributes":{
"name":"DuaneDemo",
"priority":"highest"
},
"instances":{
"test-ids":[obj]
}
},
headers: {
'PTToken': 'token'
}
})
const response = await (await testSet.json());
I'm getting the following error:
422 error sending a post request in Playwright - param is missing or the value is empty: data\nDid you mean? action attributes suite format
When I run this post request in Postman it's successful. Here's my postman body:
{ "data": {
"type":"sets",
"attributes":{
"name":"DuaneDemo",
"priority":"highest"
},
"instances":{
"test-ids":["9163455", "9163685"]
}
}
}
Any help would be greatly appreciated. I think my formatting is wrong in my Playwright post but I don't know why.
Here's the correct format:
data: {
data: {
"type": "sets",
"attributes": {
"name": "DuaneDemo",
"priority": "highest"
},
"instances": {
"test-ids": [obj]
}
}
},
I am currently creating a bolt slack app with JavaScript that needs to send out an HTTP POST request to an external webhook when a button click occurs. Sending data to my slack app from external sources is simple enough using the slack webhook provided in the app settings, but I can't seem to figure out how to send a message from my app.js file. My app is currently in Socket Mode since I didn't want to set up a Request URL after my Ngrok url didn't seem to work with the verification in slack, and there doesn't seem to be a lot of documentation on this issue. Of the documentation I did find, https://api.slack.com/apis/connections/socket-implement#connect, I wasn't sure how to implement apps.connections.open into my JavaScript file. I am fairly new to JavaScript and HTTP Requests, so any help would be greatly appreciated. I am also using the Bolt app package for slack, below is my code.
const { App } = require('#slack/bolt');
// Initializes your app with your bot token and signing secret
const app = new App({
token: "xoxb-",
signingSecret: "",
appToken: "xapp-",
socketMode: true,
port: process.env.PORT || 3000
});
app.message('Hey bot', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say({
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `You made a request <#${message.user}>?`
}},
{
"type": "divider"
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Error Message",
"emoji": true
}
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"multiline": true,
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Description of Error",
"emoji": true
}
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Aditional notes?",
"emoji": true
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Submit",
"emoji": true
},
"value": "click_me_123",
"action_id": "button_click"
}
]
}
]
});
});
app.action('button_click', async ({ body, ack, say }) => {
// Acknowledge the action
await ack();
say("No Flagged Issues");
// My HTTP POST REQUEST would go here, IF I HAD ANY!
}
});
(async () => {
// Start your app
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
At the end of the day, Bolt apps are just plain old JS apps, so there's nothing particularly special you would need to do to make a HTTP POST from inside your app.action().
There's a bunch of libraries out there, but one of the more popular ones is Axios. After importing it, you'd just have code like this inside your app.action method
axios.get('https://www.nodesource.com/')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
// Using async/await
async function getUser() {
try {
const response = await axios.get('https://www.nodesource.com/');
console.log(response);
} catch (error) {
console.error(error);
}
}
This snippet is by no means idiomatic JS, but it's enough to get you going.
i am trying to send four points of data to a spread sheet from a website i am developing. name, email, subject, message.
function loadClient() {
gapi.client.setApiKey(myapikey);
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/sheets/v4/rest")
.then(function() {
console.log("GAPI client loaded for API");
}, function(error) {
console.error("Error loading GAPI client for API");
});
}
// Make sure the client is loaded before calling this method.
function execute() {
return gapi.client.sheets.spreadsheets.values.append({
"spreadsheetId": mysheetid,
"range": "a1",
"includeValuesInResponse": "false",
"insertDataOption": "INSERT_ROWS",
"responseDateTimeRenderOption": "SERIAL_NUMBER",
"responseValueRenderOption": "FORMATTED_VALUE",
"valueInputOption": "RAW",
"resource": {
"values": [
[
"test#text.com",
"jimmy clarke",
"subject",
"this is a test email"
]
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
}, function(error) {
console.error("Execute error", error);
});
}
gapi.load("client");
</script>
i expected it to send the data to the google sheet without error.
it tells me that this can only be sent using oauth.
i would prefer not to use oauth. my main pain point is that when i look at the (google made) templates it allows for the use of the api key, though when i run the code i recieve and i receive this error
Object {
result: {…},
body: "{\n \"error\":
{\n \"code\": 401,\n \"message\": \"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\n \"status\": "UNAUTHENTICATED\"\n }\n}\n", headers: {…}, status: 401, statusText: "Unauthorized" }
Could i have made a mistake in setting it up?
May have found the answer i believe it is due to the fact that i left the
spread sheet as private, which would require the use of the oauth.
I'm trying to catch a PUT/webhook request that is being made by the Aftership API in node.js. A PUT request is made each time a push notification is needed to be made, I am using Parse to send the notifications but I need some of the data from the webhook.
The header of the webhook looks like Content-Type: application/json And contains this data:
ts - UTC unix timestamp that the event occurred
event - the name of the event (for tracking update, the value will be
'tracking_update')
msg - details about the message for which the event occurred, in the
following format.
How would I go about getting the tracking number, slug and the value for token in the custom fields dictionary in node or js?
{
"event": "tracking_update",
"msg": {
"id": "53aa94fc55ece21582000004",
"tracking_number": "906587618687",
"title": "906587618687",
"origin_country_iso3": null,
"destination_country_iso3": null,
"shipment_package_count": 0,
"active": false,
"order_id": null,
"order_id_path": null,
"customer_name": null,
"source": "web",
"emails": [],
"custom_fields": {},
"tag": "Delivered",
"tracked_count": 1,
"expected_delivery": null,
"signed_by": "D Johnson",
"shipment_type": null,
"tracking_account_number": null,
"tracking_postal_code": "DA15BU",
"tracking_ship_date": null,
"created_at": "2014-06-25T09:23:08+00:00",
"updated_at": "2014-06-25T09:23:08+00:00",
"slug": "dx",
"unique_token": "xk7LesjIgg",
"checkpoints": [{
"country_name": null,
"country_iso3": null,
"state": null,
"city": null,
"zip": null,
"message": "Signed For by: D Johnson",
"coordinates": [],
"tag": "Delivered",
"created_at": "2014-06-25T09:23:11+00:00",
"checkpoint_time": "2014-05-02T16:24:38",
"slug": "dx"
}]
},
"ts": 1403688191
}
It can be done with Express framework, example:
var express = require('express'),
bodyParser = require('body-parser'),
app = express(),
port = 3000;
app.use(bodyParser.json());
app.post('/', function (req, res) {
var body = req.body;
var trackingNumber = body.msg.tracking_number;
var slug = body.msg.slug;
var token = body.msg.unique_token;
console.log(trackingNumber, slug, token);
res.json({
message: 'ok got it!'
});
});
var server = app.listen(port, function () {
var host = server.address().address
var port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
});
Here is the GIT repository, just clone it and do npm install and then npm start. The server will run on port 3000 :D
Note: I saw in Aftership Webhook's documentation, it said they will request POST HTTP method, not PUT so I create an example of post request. Just replace it with put if you want it to catch put request.
For inspecting webhooks data, I would suggest to store every request in database and then query database. As each request is different, easiest way would be creating API in sails.js (Node.js framework with easy to use ORM).
sudo npm install sails -g
sails new _project_name_
cd _project_name_
sails generate api Records
With last command, sails has generated controller and model to store your webhook data.
I suggest installing pm2 for running app. you can run it with
pm2 start app.js
Next you should configure your webhook in Aftership for following url:
YOUR_SERVER_IP:PORT/Records/create
you can inspect data by following url:
YOUR_SERVER_IP:PORT/Records/find
if you want to parse data, it can be done in RecordsController.js, for example:
Parsing: function(req, res) {
Records.find({}).exec(function(err, results) {
var output = [];
while (results.length) {
var result = results.pop();
//custom parsing goes here
//example:
output.push({
tracking_number: result.msg.tracking_number,
slug: result.msg.slug,
unique_token: result.msg.unique_token
});
}
return res.json(output);
});
},
You can call this method via following url:
YOUR_SERVER_IP:PORT/Records/Parsing
I have created project in Codeanywhere for demonstration
webhook endpoint is:
http://port-1337.zavtt4t8a0jm7vigncyo3txxmuhxgvix3yxk66pvydgqfr.box.codeanywhere.com/records/create
For inspecting data, just replace /create part of url to /find
git repo is here: https://github.com/dkatavic/webhook_for_aftership
you can just clone the project on your server and run it (or use my server for testing)
You can catch PUT request by
app.put('/someRouteToCatchWebHook', function(request, response) {
//webhook parsing goes here
});
(i'm sure that you use expressjs in your code - see http://expressjs.com/api.html#app.METHOD for details).
If the webhook data is in request body, you can use the https://www.npmjs.com/package/body-parser module for parsing it.