doPost appScript with webhook, Post request received but is not Running doPost - webhooks

I am setting up a appScript to run on a webhook that has been registered to a Trello api. I want the doPost function in to run every time the specific trello board performs a post.
Steps I have done to setup
Published as web app, selected "Anyone" as who is able to run
Used the code below to register the webhook with the proper keys, this successfully creates a webhook for trello
fetch('https://api.trello.com/1/webhooks/?key=XXX&token=XXX&callbackURL=https://script.google.com/macros/s/XXX/exec&idModel=XXX&description=Description', {
method: 'POST',
headers: {
'Accept': 'application/json'
}
})
.then(response => {
console.log(
`Response: ${response.status} ${response.statusText}`
);
return response.text();
})
.then(text => console.log(text))
.catch(err => console.error(err));
Republished web app, selected "Anyone, even anonymous" to be able to run
Other Notes:
I have created a doPost function and a doGet function, both have logging in them
I am using the "exec" callback URL in the webhook, this seemed to be the only thing that would be able to trigger the doPost function
When a post is performed by the trello api, the doPost function is properly triggered, but even with the logging present in the doPost, I am not able to see any results that the doPost function has actually been run. See
doPostCompletion
Am I missing something that needs to be deployed or adjusted?

Turns out Logger.log is properly respected in a synchronous manner with doPost.
Webhook was functional all along.
Sources:
doPost not working in Google app script
https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script#corsinwebapps

Related

Microsoft login: Curl, Postman, and Dotnet work but Node (axios) request returns 404

I'm trying to access a graph api (specifically bookings) that only allows the Delegated (work or school account) permission. We need to be able to allow anonymous users to schedule bookings, so we created a fake microsoft user for our server to interact with their api.
I'm able to successfully authorize my user with Postman, Curl, and Dotnet, but I can't get Axios to work for the life of me, even after generating the code from Postman itself. I'm using the same exact URL in each method.
Note: my environment variables don't have typos and I'm running the code in Azure Functions. I know this is a hacky solution, but it seems to be the only way to do it using Microsoft Bookings.
Here's my code:
let data = new FormData();
data.append('grant_type', 'password');
data.append('username', process.env.MICROSOFT_USERNAME);
data.append('password', process.env.MICROSOFT_PASSWORD);
data.append('client_id', process.env.MICROSOFT_CLIENT_ID);
data.append('client_secret', process.env.MICROSOFT_CLIENT_SECRET);
data.append('resource', 'https://graph.microsoft.com/');
data.append('scope', 'https://graph.microsoft.com/.default');
const config = {
method: 'post',
url: `https://login.microsoftonline.com/${process.env.MICROSOFT_TENANT}/oauth2/token`,
headers:
data.getHeaders(),
data: data
};
axios(config).then(resp => {
console.log(resp);
}).catch(e => {
console.log(e);
});

Cookie not being set from node typescript request

I'm trying to set a cookie in a node request. I have tried using packages like js-cookie, cookie-js, cookie and cookie-manager but none work.
The way I have tried it is very straight-forward, whenever my endpoint gets called i.e. https://develop.api/sess/init, I set the cookie at the very beggining of the endpoint with the following code
import * as Cookies from 'js-cookie';
export const init = async (event: APIGatewayEvent, context: Context) => {
...
Cookies.set('hello', 'hello');
...
}
As my endpoint has an auth header, I can not directly call it into my browser URL due to missing permissions, so I tried generating the fetch function with postman and pasting it into my browser's console. The function is the following
var myHeaders = new Headers();
myHeaders.append("Referer", "accepted.referer.com");
myHeaders.append("key", "somekey");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
fetch("https://develop.api/sess/init", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Once called, my request successfully returns the expected response, but it never shows a Set-Cookie header in the network section, neither shows my cookie in the Application section.
I have to mention that I also tried looking for the cookie when making the call within Postman, but it never sets it neither.
Also, I have tried starting the application in localhost, and I have a successful response, but my cookie is still not being set.
About the package showed in the code, I said I have tried it with different ones and their implementations, so I don't think a broken package is the problem.
I'm starting to think that I have a wrong idea about how cookies work, or that someway I am completely blocking the sending of cookies within my code.
Environment
If it helps in any way, my endpoint is being hosted in a AWS Lambda application.
I know this should be trivial, but being battling with it for a day now.
I finally answered my own issue. The key here is that I'm using AWS lambdas as the proxy, therefore, the headers I were using to send the cookies were wrong, I was sending the cookies with the endpoint instead of within the lambda. Let me explain myself.
I was adding 'Set-Cookie':'cookieKey:cookieVal' in the headers of the Postman Call that I was using to test both my local and develop environments.
Instead of that, I needed to send the request within the response of the lambda for the cookies to be registered.
Please check at the following links for similar cases ->
https://aws.amazon.com/blogs/compute/simply-serverless-using-aws-lambda-to-expose-custom-cookies-with-api-gateway/
https://forum.serverless.com/t/how-to-send-a-cookie-as-a-response/1312/7

Make an API request on call end in twilio

I am looking for a way to say 'Thank you' and also make an API call at the end of function execution in Twilio.
Something like this:
responseObject = {
"actions": [
{
"say": "Thank you!"
},
{
"redirect": {
"uri": "API_LINK",
"method": "POST"
}
}
]
}
Sadly, twilio ignores every other message if you have a redirect. I tried to solve this by redirecting to TwiML first:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Thank you!</Say>
<Redirect method="POST">API_LINK</Redirect>
</Response>
But the above also does not work - It says application error after 'Thank you!' at the end. Also, I am passing query parameters along with API call: https://example.link?a=value&b=value. Not sure, how to pass that with TwiML.
This API request is supposed to send message to microsoft teams channel.
Twilio developer evangelist here.
To start with, it seems like you are talking about the end of an Autopilot dialogue, not the end of function execution. If that is the case, you are getting errors because you are mixing Autopilot Actions and TwiML. When you are interacting with an Autopilot assistant you should only respond to it with Actions JSON, not with TwiML.
Also, Autopilot will expect all responses to requests that it makes, including via redirect, to respond with Actions JSON. So it's not recommended to make API requests using a redirect action.
Instead, I would recommend that you use a Twilio Function (or your own back-end) to make your API request from JavaScript and respond with the "say" action.
A Twilio Function might look something like this:
exports.handler = function (context, event, callback) {
// make request to Teams API
// I'm not sure the API method you are using, but use an http client like got, superagent or node-fetch, or a dedicated API client if there is one available
// create your actions
const actions = {
actions: [
{
"say": "Thank you!"
}
]
};
// return the actions JSON
callback(null, actions);
});
Alternatively, you can set up to receive an Autopilot webhook when a dialogue ends. This way you can respond to Autopilot with just the "say" action which will cause the end of the dialogue and trigger the webhook. Then in your webhook handler you can make the API request to Teams.
Let me know if that helps at all.

Trying to use oauth flow in Electron desktop app (with spotify API)?

I have a React app in Electron, and I'm trying to access the spotify API using the spotify-web-api-node library. However, I'm not sure exactly how the oauth flow is meant to work inside of an Electron app... Firstly, for the redirect URL, I used this question and added a registerFileProtocol call to my file. Then I added a specific ipcMain.on handler for receiving the spotify login call from a page, which I've confirmed works with console logs. However, when I get to actually calling the authorizeURL, nothing happens?
This is part of my main.js:
app.whenReady().then(() => {
...
protocol.registerFileProtocol(
"oauthdesktop",
(request, callback) => {
console.log("oauthdesktop stuff: ", request, callback);
//parse authorization code from request
},
(error) => {
if (error) console.error("Failed to register protocol");
}
);
});
ipcMain.on("spotify-login", (e, arg) => {
const credentials = {
clientId: arg.spotifyClientId,
clientSecret: arg.spotifySecret,
redirectUri: "oauthdesktop://test",
};
const spotifyApi = new SpotifyWebApi(credentials);
console.log("spapi: ", spotifyApi);
const authorizeURL = spotifyApi.createAuthorizeURL(
["user-read-recently-played", "playlist-modify-private"],
"waffles"
);
console.log("spurl: ", authorizeURL);
axios.get(authorizeURL);
}
I'd expect the typical spotify login page popup to show up, but that doesn't happen. I'd also expect (possibly) the registerFileProtocol callback to log something, but it doesn't. What am I meant to be doing here? The authorization guide specifically mentions doing a GET request on the auth url, which is what I'm doing here...
In a desktop app it is recommended to open the system browser, and the Spotify login page will render there, as part of creating a promise. The opener library can be used to invoke the browser.
When the user has finished logging in, the technique is to receive the response via a Private URI Scheme / File Protocol, then to resolve the promise, get an authorization code, then swap it for tokens. It is tricky though.
RESOURCES OF MINE
I have some blog posts on this, which you may be able to borrow some ideas from, and a couple of code samples you can run on your PC:
Initial Desktop Sample
Final Desktop Sample
The second of these is a React app and uses a Private URI scheme, so is fairly similar to yours. I use the AppAuth-JS library and not Spotify though.

Making a POST request in webhook in an Actions on Google app.intent [duplicate]

This question already has an answer here:
Making an HTTP POST request from fulfillment in Dialogflow
(1 answer)
Closed 4 years ago.
We are creating an action that will take user's input and create an entity in our database (datastore).
Ideally, we would like to be able to access the user's raw input audio, but it doesn't seem that is possible.
As a work around we are going to send the speech-to-text of user's utterance to our backend services. We are using firebase cloud functions for our fulfillment and an external rest api for our crud operations.
We are trying to make a post request in a webhook to create an entity based on user's input, but when I check my logs it doesn't seem like the post request is reaching our service. I'm not able to debug what or if we are getting a response back
app.intent('favorite color', (conv, {color}) => {
const options = {
// options
};
function callback(error, response, body) {
// log response or error
}
request(options, callback);
const luckyNumber = color.length;
// Respond with the user's lucky number and end the conversation.
conv.close('This word has ' + luckyNumber + ' letters.');
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
This question is not the same as the one that it was marked as a duplicate because the solution was the account type not supporting POST requests to an external API and not the HTTP Client we were using
The Inline Editor in the Dialogflow console uses Firebase Cloud Functions, as you already know.
Unfortunately, Firebase Cloud Functions DOESN'T support external API calls in it's free plan. You may need to switch to blaze plan or deploy your fulfillment elsewhere.

Resources