How to change webhook url of bots business for sending data to different users? - bots.business

How to change userid in webhook of bots business, so I can post different data to different users?
A normal bots business webhook looks like:
https://api.bots.business/v1/bots/185720/new-webhook?&command=BonusWebhook%24%40%25%23%5E&public_user_token=eb0943059fb548e9faf1283b536c594e&user_id=1775114
I tried to change UserId in that url, but it shows an error.
Error : {"errors" : ["You need to sign in or sign up before continuing." ]}
How to fix it or any other idea?

From doc:
let webhookUrl = Libs.Webhooks.getUrlFor({
command: "/onWebhook",
user_id: user.id
})
Bot.inspect(webhookUrl);
So you can change user.id in this code.

Related

Spotify JWT Flow

Tech stack: NodeJS backend Angular10 front end
I am implementing the Spotify API into my application. I'm having some issues with the flow.
To start off I have no issues authenticating or retrieving a token, but I am having an issue figuring out what to do with it. Assuming we understand the Spotify flow and are on the same page there is an issue presented for client-side rendered apps and that is how to get our JWT into the storage.
The reason this is an issue is because of the flow Spotify constrains us to, it requires a callback where the token is passed in as a query param.
This callback is on my backend NodeJS server, the endpoint is functioning fine but this issue starts here - I cannot pass in my user_id or any other user information it simply returns a JWT at this point the only thing I can do is send a template to the client but it's of a different domain.
Option (1)
Somehow use the Iframe hack to set a storage item in my other tab that's running my front end; I do not like this cause it's hacky and does not feel the right way to handle this.
Option (2)
Perform some kind of hack that maps user ids from the initial request and maps the correct user id to the correct token and then sending it to the client somehow ( database then GET ) I also don't like this it's hacky
What we don't want is to keep the client secret and other credentials on the front end like some examples I have seen, this is fine for personal stuff but not real apps for very obvious reasons.. All client secrets and passwords should be on the backend never sent to the client only their user JWT
So the issue here summarized, How do I return the JWT to the client without doing something hacky? the code below returns this to the client but brings us to option (1) above and obviously returns a template style which is undesirable cause I have a client-side rendered app!; I want something clean and professional, thank you.
router.get('/musicAuthCallback', function (req, res) {
const spotifyCode: string = req.query.code;
if (production.ROUTE_LOGGING) {
routeLogger.info('Spotify endpoint callback hit');
}
const _spotifyService = new SpotifyService();
_spotifyService.tradeSpotifyAuthToken(spotifyCode)
.then((jwt: any) => {
if (jwt === false) {
res.send({ "message": "Unable to get JWT for Spotify", "status": REQUEST_FAILED, "title": "Authentication Error" });
} else {
const template = `<h1> Success! </h1> <script>
var main=window.open("http://localhost:4200/");
main.setItem('spotify_jwt', ${jwt});
</script>`
res.send(template)
}
})
.catch((error) => {
logger.error(error);
res.send({ "message": "Something went really wrong..", "status": REQUEST_FAILED, "title": "Please Try Again.." });
});
})
This is silly but kind of illusive until you poke around the docs more.. the docs didnt make it clear to me I could use "state" as a query param.. in this i was able to pass the users ID into here so &state=600 and this is passed into the users callback URL which makes it possible to attach a user to a specific JWT given by Spotify
https://accounts.spotify.com/authorize?client_id=5fe01282e94241328a84e7c5cc169164&redirect_uri=http:%2F%2Fexample.com%2Fcallback&scope=user-read-private%20user-read-email&response_type=token&**state=123** <- this can be what you want! and can retrieve it in your callback URL sitting on your NodeJS server like this..
const spotifyCode: string = req.query.code; // jwt
const userID: string = req.query.state; // value you passed in

Stripe Elements not talking to stripe server - No such token: tok_xxxx

So I'm migrating from the stripe checkout to elements so that I can register and charge a customer in a single form.
I'm following their documentation:
https://stripe.com/docs/stripe-js/elements/quickstart
Specifically in Step 3 where the token is created with the following code:
// Create a token or display an error when the form is submitted.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the customer that there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
The documentation states:
The handler sends the fields to Stripe for tokenization...
However, it seems nothing is being sent to Stripe at all!
The bottom two requests show the two api calls made using the old checkout: First the card info is sent to /tokens and then my server handles this and makes the /customers request fine.
But when using the elements code nothing seems to be sent to stripe, even though a token is generated and sent to my server. So then I get the 'No such token' error!?
I can't for the life of me workout why stripe.createToken(card) isn't sending the details to their server and yet generates a token?? I've triple checked api keys and everything I can think of. Please help!!
What the actual heck... I got it to work but I don't know why this fixed it.
I'm using stripe elements on a .net mvc website and i'm initializing the Stripe class in a view so I can easily pass the key from my viewmodel like so:
var stripe = Stripe('#Model.StripePublicKey');
Which should work fine, right? No JS errors or anything and it was creating the token, just not posting to stripe's servers....
Anyway, I moved that line into the JS file so it's directly above the other stripe related JS and now it works!?

How to query how many gmail accounts are logged in?

For a webExtension I'm trying to check the gmail inboxes by sending a xmlhttprequest to:
https://mail.google.com/mail/u/0/feed/atom
https://mail.google.com/mail/u/1/feed/atom
https://mail.google.com/mail/u/2/feed/atom
... and so on for each account. I want to do this for all currently logged in accounts, but I dont know how to find out that number.
Of course, there is a dumb way, in that I just keep incrementing the u/#/ until I loop back to /u/0/, and do a check there.
But that is slow, since I'd then have to wait for the async to return, hopfully there will be a better way.
Not sure about gmail specifically, but you could use browser.cookies.getAll to read all the user cookies for "mail.google.com" (or accounts.google.com or similar).
This assumes you know the name of the cookie(s) you are looking for, so that you can infer on how many accounts the user is logged in.
Also, make sure to add the cookies permission to your manifest.json
browser.cookies.getAll({ domain: 'mail.google.com' })
.then(cookies => {
// do something with the cookies
});
If instead you can assume that each gmail inbox is open in some tab, then you could just query all the current tabs:
browser.tabs.query({ url: "https://mail.google.com/mail/u/*" })
.then(tabs => {
tabs.forEach(tab => {
// do an XHR request to tab.url or just extract the inbox ID for later use
});
})

Getting Agent Info from API.ai fulfilment request

Is there a way that I can get the API.ai agent information from the fulfillment request?
I am trying to capture any unique parameter from Node.js code that can be passed from Agent. This will be utilized for proceeding with the logic for multiple agents using a single code base.
For Amazon Alexa I could get the Skill Application Id from the session. Is there something similar in API.ai?
If you want to get agent id you can make something like this (using express framework):
app.post(`/:agent_id/webhook`, (req, res) => {
const apiai_agent_id = req.params.agent_id;
// webhook code...
});
And on fulfillment page in this case for each agent you have to specify it's own webhook URL like
https://mywebhooks.com/55982e7c-db17-47ee-92bb-176476228942/webhook
(you can get agent id for webhook URL from browser's address bar)
You can use the API.AI's sessionId or intentId which will be unique across agents. The sessionId and intentId* is sent with every fulfillment webhook request. The of the JSON sent are similar to this:
{
"id": "1a4b6209-51ec-47a1-a797-2e2f71926ac8",
"sessionId": "1503343146047"
...
}
but will contain other elements as well.
*intentId may include additional numeric identifier after the intent ID if you are using slot filling
Source: https://api.ai/docs/fulfillment#request

Facebook login name field missing

I have a server, writtien in NodeJS and in it I'm requesting for some facebook user info given his access_token with the fbgraph module (version 1.1.0).
return Promise.promisify(graph.get)('me', {
fields: 'picture,id,birthday,email,first_name,last_name,name,middle_name,link,timezone,updated_time,verified, ...
access_token: token
});
The access token is sent by the client side (android).
The problem I'm facing is, that for a very small percentage of requests, the "name" field is missing in the response, although I get some other info like email, profile picture, ...
I thought that the "name" field was a part of the public_profile and is always provided, or can a user somehow set is as hidden?

Resources