Q&A: How to setup Quickbooks OAuth2 on Zapier - api

Zapier has been a handy way to connect to API's like quickbooks. However there is very little documentation on how to set this up, which caused me to spend weeks figuring it out (hopefully for you this will help!). This is a Q&A post, however if anyone has input that will improve this information please feel free to share here.
If you find yourself in a situation like mine and you are looking on how to also make an 'action' or 'trigger' for quickbooks just leave a comment and I can work on a tutorial for those as well.
If I have posted this in the wrong format for Stack Overflow please let me know and I will correct that or move it to a blog.
Depending on how things go I may end up submitting my zap for public use (My zap finds estimates by their ID and returns everything, useful for when you have a web-hook on Quickbooks). Anyway, all the information presented in this post is for the OAuth2 setup.
Here is the documentation I used:
API OAuth 2.0
Playground
Question: How do I connect Quickbooks API to a custom app in Zapier Developer with OAuth2?

To start this answer assumes you have a Quickbooks and Zapier dev account. It also assumes you have begun to setup your first Zap and are now working on authentication.
In Zapier Dev, choose Authentication tab and select OAuth2
Leave "Configure your Fields" blank and press continue
In "Enter your Application Credentials" enter your credintials from your Intuit keys page
Now in "Add OAuth v2 Endpoint Configuration" enter the following as shown for the Authorization URL section:
Next define your scope, I used com.intuit.quickbooks.accounting openid email profile
We also have to get the "Access Token Request", set it up like this:
Finally add the refresh request:
Set "Automatically Refresh Token" to checked.
Now, the next part is custom, but I set up my test request to a random query (you can do the same if you want)
const options = {
url: 'https://sandbox-quickbooks.api.intuit.com/v3/company/ENTERYOURREALMID/query?query=select*from Invoice&minorversion=38',
method: 'GET',
headers: {
'Authorization': `Bearer ${bundle.authData.access_token}`,
'content-type': 'application/x-www-form-urlencoded',
'accept': 'application/json'
},
params: {
},
body: {
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
// You can do any parsing you need for results here before returning them
return results;
});
Just toss in your RealmID in the http link (you can get the REALMID by clicking myaccount in Quickbooks, this is the same as Company ID).
Once you connect and run it should enter the HTTP Headers for you. If not, then for all sections they are same:
content-type: application/x-www-form-urlencoded
accept: application/json
That's it! Connect your account and you should be good to go!
NOTES:
-Quickbooks will require a refresh each 100 days.
-Remember that you must use backticks ` over single quotes ' if you are using a
Zapier variable.

Related

How to manually authenticate user/client in spartacus?

right now I'm trying to create a proof of concept on spartacus. The concept is to manually check out a cart for an anonymous customer.
I came to a point, where I was wondering whether it is possible to authenticate a client or user manually with spartacus.
So my question in general: What is the best practice to manually authenticate the client/user in spartacus? Some code examples would be great :)
Best regards and thanks in advance
Not sure exactly what you mean by "manually" authenticate.
In spartacus if you want to authenticate the client (the app) it's quite simple. The client-token.interceptor is setup to catch request containing a specific header and add the client token to the request. If Spartacus doesn't have the token in memory it will request it.
To do so you should use add the USE_CLIENT_TOKEN to your request header. Here is an example:
const url: string = '/url';
let headers = new HttpHeaders({
'Content-Type': 'application/json',
});
// The line bellow add the token to the header
headers = InterceptorUtil.createHeader(USE_CLIENT_TOKEN, true, headers);
return this.http
.post<User>(url, { data: data }, { headers });
As for the user authentication, the user token will be added to all request as long as the user is authenticated in Spartacus. There is no "automatic" mechanism to fetch it. The token is fetched via login.
Hope this helps!
There are a few things you have to do in case of a guest checkout.
First thing is to enable guest checkout in the config with:
checkout: { guest: true }
Then the first step of the checkout should be /checkout-login page.
There user needs to provide email address that is assigned to a specific cart.
We recognize guest checkout by that assigned email to the cart. Otherwise, checkout components will behave like it is normal checkout. Because of that, there are calls for user addresses or payments.
In case you want everything on one page (setting email address, delivery, payments etc.) you have to override default implementation for checkout components to avoid all these calls for the logged user.
And calls for setting address and payment in case of guest checkout doesn't have to by authorized (you can see that on demo guest checkout these calls have undefined in Authorization header).
And for client authorization, it is nicely described in https://stackoverflow.com/a/60821200/4666829

Access Power BI API with Python

My requirement is to push real time data into Power BI using Python to first read from a database and then send the data inside a Streaming dataset in Power BI.
The first thing I want is to make a simple "get" call to Power BI.
The official documentation explains the processes of connecting to Power BI via the REST API for either a Client App or a Web App.
However, I'm using Python - not sure if that is either a client app or a web app.
Anyway, I am able to get the accessToken using the adal library and the method .acquire_token_with_client_credentials, which asks for authority_uri, tenant, client_id and client_secret (notice this is not asking for username and password).
By the way, I've also tried getting the accessToken with .acquire_token_with_username_password, but that didn't work.
Unfortunately, when I use the below code with the obtained accessToken, I get a response 403.
#accessToken is received using the adal libary
headers = {'Authorization': 'Bearer ' + accessToken, 'Content-Type': 'application/json'}
read_datasets = requests.get('https://api.powerbi.com/v1.0/myorg/datasets', headers=headers)
#shockingly, this will result in a response 403
After reading other stackoverflow posts and looking at console apps, I believe the reason this doesn't work is because there is no user sign-in process.
This thread mentions that using Client Credentials is not enough (it is enough to get the accessToken, but not enough to use the APIs)
Not sure how to proceed, but what I need is perhaps a way to keep using this adal template that gives me the accessToken, and also to provide my username and password (if required), and together with the accessToken, to access the APIs.
I see that you've answered this over on the PowerBI forums:
https://community.powerbi.com/t5/Developer/Access-Power-BI-API-with-Python/m-p/190087#M6029
For future reference of anyone visiting this in the future:
Get your token using the python adal library and the appropriate method. Once you've got your token, you pass that in as part of your request headers like so:
url = f'{self.api_url}/v1.0/myorg/groups/{self.group_id}/datasets'
headers = {
'Authorization': f'Bearer {self.token["accessToken"]}'
}
Where api_url is https://api.powerbi.com, group_id is your group_id and token is the token dict you got from acquire_token_with_username_password.
From there you'll be able to make all the PowerBI API calls you need.

Power BI - Programmatically sign in

I'm trying to write a web app which embeds some Power BI reports. The data is on-premises so I cannot use the new solution available (Power BI Embedded). Now the inconvenience of using the old approach (https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-integrate-a-power-bi-tile-or-report/) is that the consumer of the web page needs to be a Power BI user which needs to sign in in order for the web app to finally get an authentication token (there is a couple of page redirections that need to happen before).
So my question is, is there a way to do the Power BI Sign In in a programmatic way? so in that way I can just use one Power BI account for getting the content.
I am also experimenting there,
this thread helped me with just that (see post #8):
http://community.powerbi.com/t5/Developer/How-to-use-Power-BI-Rest-API-without-GUI-authentication-redirect/m-p/14218#
Basically:
POST request to:
https://login.microsoftonline.com/common/oauth2/token
Body, form-url-encoded:
grant_type: "password"
scope: "openid"
resource: "https://analysis.windows.net/powerbi/api"
client_id: your client id
client_secret: your client secret
username: that username
password: that usernames password
Then you directly get the token.
Also it might be good to consider security concerns like described here: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/ under "When NOT to Use This Feature"
It's just a coincidence that I am doing the same. Actually Power BI provides a Rest API to do this very easily. You need to register an app at Azure portal which will provide you with a client id and client secret. Now you can use the rest API and these details.
POST: https://login.microsoftonline.com/common/oauth2/token
and in the body, you need to send these details and in the header, you need to set
Content type : application/x-www-form-urlencoded
data: {
grant_type: password
scope: openid
resource: https://analysis.windows.net/powerbi/api
client_id: {Client ID}
username: {PBI Account Username}
password: {PBI Account Username}
client_secret: {Enter client secret here}
}

ZenDesk API Call From NetSuite Not Working

I'm trying to send data from NetSuite to ZenDesk via the ZenDesk API. Problem is, I can not get it to authenticate by placing the authentication inside the header. Has anyone seen any articles on doing it this way? I've tried adding it as {email}:{password} and {email}/token:{token} with no luck.
I have tested the password and the token using curl. So I do know that the password is correct. Any thoughts on this one?
I've also tried using Postman to create the authentication and it worked as well. Oddly enough, though, I can not use that authentication in any other application. I can paste is into the header (in Postman) with no issues, but when I try to do that via Advanced Rest Client (Chrome Extension) it won't work, nor will it work in the header from NetSuite.
I'm guessing there must be something that I am missing that Postman is doing by itself.
generally you have to provide credentials as a header e.g. a GET request like:
var url = 'https://...';
var cred = 'username' +':'+ 'password';
var headers = {
'Content-Type' : 'application/json',
'Authorization' : nlapiEncrypt(cred, 'base64');
};
nlapiRequestURL(url, null, headers);
Netsuite has a new method that apparently helps with this: nlapiRequestURLWithCredentials but I've not bothered figuring it out since the above is well tested and has worked with multiple remote systems.

Office 365 API ErrorAccessDenied (Access is denied. Check credentials and try again.)

I'm trying to build me first app with office 365 API and have one big problem.
I'm trying to get main info about user with Office 365 API and Azure Active Directory and for that I'm doing:
1) Get access token. The http post request to https://login.windows.net/common/oauth2/token for token:
HEADERS:
Content-Type: application/x-www-form-urlencoded
POST DATA:
grant_type = authorization_code
client_id = *my_client_id*
client_secret = *my_client_secret*
session_state = e5fb6cd5-28f7-4dfc-b793-9ce8522534ac
code = *code_that_i_got_to_my_callback_url*
resource = https://outlook.office365.com/
I get response with access_token, refresh_token, id_token, resource etc.
2) I'm trying to get main info about user with access token:
Get request to https://outlook.office365.com/api/v1.0/me with
HEADERS:
client-request-id: *some_random_id*
return-client-request-id: true,
authorization: 'Bearer ' + *access_token*
Accept: '*/*'
But I get:
{ error:
{ code: 'ErrorAccessDenied',
message: 'Access is denied. Check credentials and try again.' } }
My app in AAD has max permissions for everything (sorry for russian):
I'm doing everything like here:
http://blogs.msdn.com/b/exchangedev/archive/2014/03/25/using-oauth2-to-access-calendar-contact-and-mail-api-in-exchange-online-in-office-365.aspx
And the most interesting moment is that one week ago everything worked good (except that sometimes response time was about 30 sec) and I could get information about users.
And last thing.
On that page (http://blogs.msdn.com/b/exchangedev/archive/2014/03/25/using-oauth2-to-access-calendar-contact-and-mail-api-in-exchange-online-in-office-365.aspx) you can find request to https://login.windows.net/common/oauth2/token with parameter prompt=admin_consent. It was working also week ago, but now if you try you'll get Bad Request (400).
Thanks for your question and sorry to hear about the trouble you are having with your first app. Can you please check the permissions for Office 365 Exchange Online and make sure the permission "Have full access to a user's mailbox" is NOT selected? See attached image for more details.
This is meant for access to a user's mailbox using an older API called Exchange Web Services, and not intended for Office 365 REST APIs. I think you are getting "Access Denied" for your REST API request because you may have selected this permission.
Let me know if you are still seeing an issue after removing this permission. Let me know if you have any questions or need more info.
Thanks,
Venkat