Quickbook No apptoken detected; (PHP)errorCode=003102; statusCode=401 - quickbooks-online

I am new in quickbooks API implementation, I am always getting one error No apptoken detected; errorCode=003102; statusCode=401 when I am doing API call for customer add etc.
I am giving my steps, please look over that.
My sandbox info like that
Consumer Key: qyprdffbBBInX4a82jG73Mreyy96tC
Consumer Secret: IgpJzJrYvb9FmmdB7A0ECDGHG62Cp7dqVWjfMTvU
Access Token: qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ
Access Token Secret: TdPGpcUI8AiAdWFiCyb8jAAygH16bzU7VRGaspx4
I am Using PHP.
First I have generated oauth_signature.
$URL =
rawurlencode('https://sandbox-quickbooks.api.intuit.com/v3/company/408554291/customer');
$method = 'POST'; $parameter =
rawurlencode('oauth_consumer_key=qyprdffbBBInX4a82jG73Mreyy96tC&oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1449659733&oauth_token=qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ&oauth_version=1.0');
$ukey =
rawurlencode('IgpJzJrYvb9FmmdB7A0ECDGHG62Cp7dqVWjfMTvU').'&'.rawurlencode('TdPGpcUI8AiAdWFiCyb8jAAygH16bzU7VRGaspx4');
$hasmac = hash_hmac("sha1", $BaseURL,$ukey,1);
and My oauth_signature is jZ8JhECy/e0kpPbUdZp/o/EUC7U=
When i call API with this oauth_signature, i am getting Error 'No apptoken detected; errorCode=003102; statusCode=401'
My CURL call like this
curl -X POST -H 'Content-Type: application/json, Authorization: OAuth
oauth_token=qyprdlo3WrK0KhGZMTeA857AuKiVy2eaAmpXsRvG3jycYaMQ,oauth_consumer_key=qyprdffbBBInX4a82jG73Mreyy96tC,oauth_signature_method=HMAC-SHA1,oauth_timestamp=1449659733,oauth_version=1.0,oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733,oauth_signature=jZ8JhECy/e0kpPbUdZp/o/EUC7U='
-d '{"data": [{"BillAddr":{"Line1":"86 A Topsia","City":"Kolkata","Country":"India","CountrySubDivisionCode":"WB","PostalCode":"700102"},"Title":"Mr.","GivenName":"ApurbaK","MiddleName":"Kumar","FamilyName":"ApurbaK","PrimaryPhone":{"FreeFormNumber":"564545465"},"PrimaryEmailAddr":{"Address":"apurbahazra12#navsoft.in"}}]}'
'https://sandbox-quickbooks.api.intuit.com/v3/company/408554291/customer'
Please look over that.
Thanks,
Apurba

Firstly, you don't want to be doing this yourself -- use a library. OAuth is complex, and implementing it yourself is going to be a hairy process, rife with errors.
Go grab a library:
https://github.com/consolibyte/quickbooks-php
Follow the quick-start guide linked there, and benefit from the examples:
https://github.com/consolibyte/quickbooks-php/tree/master/docs/partner_platform/example_app_ipp_v3
With that said, if you do decide to write it yourself, make sure you follow the OAuth spec:
https://www.rfc-editor.org/rfc/rfc5849
So far, the issues I immediately see with your implementation are:
You can't hard-code the timestamp like this: &oauth_timestamp=1449659733 The timestamp should be ever-changing, and set to the currenty timestamp.
You can't hard-code a nonce like this: &oauth_nonce=BlyqIBbv3R4T0P4qglAv1RjoYisMZk1449659733 The nonce has to change with every single request so this is going to fail after your first request.
You haven't normalized your request parameters / sorted them, per the spec.
This is the incorrect way to specify multiple headers with cURL: -H 'Content-Type: application/json, Authorization: OAuth .... Please see the cURL docs: http://curl.haxx.se/docs/manpage.html#-H
In the code you posted, you haven't actually set $BaseURL anywhere, so right now you're signing an empty string (unless you forgot to paste some code somewhere?)
What is $ukey set to? It doesn't appear to be defined in your code anywhere (did you forget to paste some code in?)

Related

libcurl - CURLOPT_MIMEPOST vs CURLOPT_POSTFIELDS

Tell me please, what is the main difference between options CURLOPT_MIMEPOST and CURLOPT_POSTFIELDS ?
What can be done with a CURLOPT_MIMEPOST - that cannot be done with CURLOPT_POSTFIELDS ?
CURLOPT_POSTFIELDS
Sends exactly the bytes you specify in the body of the HTTP request. With a default Content-type of application/x-www-form-urlencoded. libcurl will not add or encode the data in any way for you.
With the curl command line tool, you do this with -d.
CURLOPT_MIMEPOST
Makes libcurl send a "multipart formpost". That is a data stream using a format that allows the sender to send multiple "parts" of data to the server, each part being properly separated and identified. Each part has a name, content and its own set of headers. When an HTTP client "uploads a file", this is almost always done using multipart formposts.
Multipart formpost is structured data in the request body and this option helps you produce and send that format. An application can also produce that format by themselves should they prefer that and provide it with CURLOPT_POSTFIELDS or even using the callback CURLOPT_READFUNCTION.
With the curl command line tool, you do this with -F.
See Also
https://everything.curl.dev/libcurl-http/upload

Use token obtained using R package AzureAuth to Query data

I am using the following code to get an access token using AzureAuth package in R
library (AzureAuth)
AuthToken <- get_azure_token("120d688d-1518-4cf7-bd38-182f158850b6",tenant="72f988bf-86f1-41af-91ab-2d7cd011db47", app="1950a258-227b-4e31-a9cf-717495945fc2");
However, I don't see any examples on how to use the obtained AuthToken in query data from an API?
Appreciate any help!
Pls point out my mistake if I misunderstand your question.
=======================Update=======================
Yes, I found some documents and I followed the sample. And I found that, if I wanna to call graph api, I just need to 'install.packages("AzureGraph")', and with this package I can reach my goal. And if I need to use AzureR to do some other operations on azure, the ducoment above has offered an example to illustrate how to create a resource group and storage account in AzureRMR, and a registered app in AzureGraph.
===================================================
Getting started with httr
I use this code to get httr get request, and http post request is similar, look up the document above for more details:
a <- GET("https://graph.microsoft.com/v1.0/me", add_headers(Authorization = "Bearer <accesstoken>"))
I just figured out the syntax. I found it difficult on two counts
Syntax for POST command. There are lot of examples for GET command but not many on POST
Getting to access_token. However once I started using R Studio, I was able to inspect the object and find the right field. Here is the syntax that worked for me
res <- POST(EnvironmentFqdnUrl,add_headers(Authorization = paste("Bearer", AuthToken$credentials$access_token)), body = upload_file("body.json"), verbose())
print(res)

Codename One Curl Request oAuth

I am trying to make a call to the Petfinder API from codename one. It requires oAuth authorization. Right now I am able to get access to the API from terminal, but I do not know how to call it from codename one which uses Java. Right now I'm able to pull data from APIs that don't need oAuth but need a key.
From terminal it looks like this:
curl -d "grant_type=client_credentials&client_id={CLIENT-ID}&client_secret={CLIENT-SECRET}" https://api.petfinder.com/v2/oauth2/token
{"token_type": "Bearer","expires_in": 3600,"access_token": "{my access token}"
}
curl -H "Authorization: Bearer {my access token}" GET https://api.petfinder.com/v2/animals?type=dog&page=2
You can use something like this. I haven't tested it though so debugging will be required:
Rest.post("https://api.petfinder.com/v2/oauth2/token").
queryParam("grant_type", "client_credentials").
queryParam("client_id", clientId).
queryParam("client_secret", clientSecret).
fetchAsJsonMap(response -> {
// data is already parsed to Map here
if(response.getResponseData() != null) {
accessToken = (String)response.getResponseData().get("access_token");
// set the auth header for all future requests in this session
addDefaultHeader("Authorization", "Bearer " + accessToken);
}
});
Notice that the code assumes a static import of the CN class exists. You could also store the token into Prefrences and load it dynamically/set it globally as I did here which is the more complete example.

Why is Gmail returning a UID outside the range specified by UID FETCH command?

When I run a fetch command UID FETCH 170930:170930 BODY[] I get the response 88924 FETCH (UID 170920 FLAGS (\Seen)). I wasn't expecting to retrieve a message with a UID out of the range specified. Is this normal IMAP behaviour? The 170930 UID came from watching the folder with an IdleManager only moments earlier, so I have no reason to believe that a message with that UID doesn't exist on the server.
The fetch request I've posted here is a guess based on the Java code I'm using to execute it. At the very least it should still be requesting only messages within that range:
Argument args = new Argument();
args.writeString(Long.toString(start) + ":" + Long.toString(end));
args.writeString("BODY[]");
Response[] r = protocol.command("UID FETCH", args);
Response response = r[r.length - 1];
An IMAP server is required to send you FETCH responses in certain cases. Sometimes the server is required to wait with responses, but it's never required not to send you any.
If you send a command that requires two response, and someone else does something that requires one response to you, then you get three responses. That something might be to change the flag on a message (requires FETCH ... FLAGS ... to you, although there's no promptness requirement) or send you some mail (requires EXISTS to you).

How do I delete all cards that belong to my app?

I'm trying to simply delete a few cards that were created by my app. However, it appears as though the list() method cycles through every single card in the entire user's timeline.
My code below is slightly modified from the example in the documentation under the timeline list. When I attempted to use this, it accidentally looped through every card in my timeline using up my entire 1,000 / day quota in just a few seconds before the operation timed out.
def delete_previous_cards(self):
"""
This cleans up any cards that may have been leftover.
"""
result = []
request = self.mirror_service.timeline().list()
while request:
try:
timeline_items = request.execute()
result.extend(timeline_items.get('items', []))
request = self.mirror_service.timeline().list_next(request, timeline_items)
except errors.HttpError, error:
print 'An error occurred: %s' % error
break
for item in result:
item_id = item['id']
self.mirror_service.timeline().delete(id=item_id).execute()
What's the best way to efficiently delete the cards created by my app?
There's a JavaScript based tool that an Explorer wrote for just this purpose: Glass Cleaner.
It looks to me like the Python example is missing any concept of a pageToken, most of the other language examples have a nextPageToken and loop until the response does not have a nextPageToken. If you keep requesting the first page over and over even if you only have three cards you will quickly exhaust your API quota.
The rest of this answer is general information about list and delete and some curl commands you can safely experiment with that won't loop and exhaust your quota quite as quickly. Make special note of the nextPageToken property in the returned JSON from list commands ...
LIST and DELETE are weird and don't follow the documentation exactly in my experience.
Here is a sample CURL command for List.
curl -x http://localhost:5671 -H "Authorization: Bearer YOUR_TOKEN_HERE"
https://www.googleapis.com/mirror/v1/timeline
It returns 10 items for the user and app that are associated with the token.
It includes deleted items (isDeleted set to true) but does not show the isDeleted property in the output JSON. This is weird.
If you modify it slightly:
curl -x http://localhost:5671 -H "Authorization: Bearer YOUR_TOKEN_HERE"
https://www.googleapis.com/mirror/v1/timeline?isDeleted=true
(note the trailing parameter) now you get the same list but the output JSON includes the isDeleted property. The lesson for me here is you should probably be requesting isDeleted=false for looping delete requests.
To delete an item you can do this:
curl -x http://localhost:5671 -H "Authorization: Bearer YOUR_TOKEN_HERE"
-H "Content-Type: application/json" -v -X DELETE
https://www.googleapis.com/mirror/v1/timeline/ID_OF_A_TIMELINE_CARD
Note you have to use an actual id from a card you got from a list command at the end. Grab one from a list command above.
When you do a successful DELETE the response is a 204, which in a RESTful world can indicate delete success.
Then if you do a subsequent list as in the first example above the item will come right back and not be marked as deleted because the isDeleted property is missing.
Pages seem to be 10 in size, but I guess that could change, since I didn't find that documented anywhere.
nextPageToken values seem to frequently have identical beginnings and ends, and they are very long strings, so it can be confusing to look at them and you might inadvertently think they are identical when they are not, lesson here is to compare very carefully in the middle.
Maybe those curl commands help you experiment when your API quota comes back, and I would experiment with testing for a null or empty string nextPageToken to tell you when to exit your loop. The equivalent java code is:
} while (request.getPageToken() != null && request.getPageToken().length() > 0);
Good luck, and great question.

Resources