How to utilize API call to overwrite/update Google Sheet? - api

My current API request will post a new Google Sheet every time it runs, but I just want it to either overwrite the existing sheet or just update it with new data.
I've tried using different request methods, but it's not doing what I am looking to do.
Request URL: https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart
Request Method: POST
Content Type: multipart/related; boundary="foo_bar_baz"
Request Body:
--foo_bar_baz
Content-Type: application/json; charset=UTF-8
{
"name": "<var_my_google_sheet_name>",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
--foo_bar_baz
Content-Type: text/csv; charset=UTF-8
<var_query_results>
--foo_bar_baz--
Hoping to have it either overwrite the existing table over and over with updated data, or to just append new data to the existing table.

Related

SAP Business One Service Layer - Upload Attachment - Internal Error (-43)

I'm having an issue uploading an attachment into SAP B1 via the Service Layer. I am able to upload an attachment using the SAP client without issue. I'm using Postman to test sending the request before I embed this into a real application. I've gone over the documentation available in the SAP B1 Service Layer Guide (located here https://help.sap.com/doc/0d2533ad95ba4ad7a702e83570a21c32/9.3/en-US/Working_with_SAP_Business_One_Service_Layer.pdf) on page 106.
Here's what my HTTP request looks like... and it matches what the documentation expects.
POST /b1s/v1/Attachments2 HTTP/1.1
Host: 129.159.XXX.XXX:50000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cookie: B1SESSION=62bbdc3e-d634-11ec-8000-02001703771b; ROUTEID=.node3
Content-Length: 197
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="JSON-Tshirt-Master Product.txt"
Content-Type: text/plain
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Here's the error that I'm getting which doesn't make sense to me. I can't find anything on this error and I was wondering if anyone had seen something like this before?
{
"error": {
"code": -43,
"message": {
"lang": "en-us",
"value": "Internal error (-43) occurred"
}
}
}

Get shopify analytics token programmatically

How do you get the token needed to make a request to the Shopify analytics API?
For example:
POST https://analytics.shopify.com/queries?beta=true
REQUEST BODY:
token: HOW_DO_I_GET_THIS?
q[]: SHOW+total_visitors+AS+%22total_visitors...
source: shopify-reports
I've tried using OAuth, but it seems to be a different token entirely.
You have to request Shopify Core GraphQL to get analyticsToken.
POST /admin/internal/web/graphql/core HTTP/1.1
Host: [[STORE_NAME]].myshopify.com
Accept: application/json
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
content-type: application/json
X-CSRF-Token: [[CSRF_TOKEN]]
Origin: https://[[STORE_NAME]].myshopify.com
Connection: close
Cookie: [[COOKIE]]
{ "query": "{ shop { analyticsToken } }" }
Since the request requires CSRF Token & Cookie, it's not programmatic at all.
For additional information please check the Examples for Testing in the Shopify Admin page.

Why is my OData 4 Batch not picking up the request body of the last request

I am working on an ASP.NET Core 2.2 API using the Microsoft.AspNetCore.OData NuGet v7.1.0 and I am trying to test OData batch using Postman v7.0.5.
The problem I am having is that it always fails to see the data in the last POST request in my batch. In the response, I get "201 Created" for every post except the last on, which returns "400 Bad Request" because it is not picking up the data in the last request body.
Here is the relevant section of my Startup.cs where I enable OData Batch handling;
app.UseODataBatching();
app.UseMvc(routeBuilder =>
{
routeBuilder
.MapODataServiceRoute("ODataRoutes", "api/v1",
modelBuilder.GetEdmModel(app.ApplicationServices),
new DefaultODataBatchHandler());
});
In Postman, I have a POST request to
{{url}}/api/v1/$batch
and in the Request -->Headers section, I have a Content-Type header set to
multipart/mixed; boundary=batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
The Body of the request is set to "Raw" and "Text"
Below is the request body;
--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal
{
"Code": "Z1",
"Description": "Test Batch Z1",
"Active": true
}
--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal
{
"Code": "Z2",
"Description": "Test Batch Z2",
"Active": true
}
--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal
{
"Code": "Z3",
"Description": "Test Batch Z3",
"Active": true
}
--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /api/v1/AddressComplianceCode HTTP/1.1
OData-Version: 4.0
Content-Type: application/json
Accept: application/json;odata.metadata=minimal
{
"Code": "Z4",
"Description": "Test Batch Z4",
"Active": true
}
--batch_abbe2e6f-e45b-4458-9555-5fc70e3aebe0--
And here is the response;
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z1')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0
{"#odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z1","Description":"Test Batch Z1","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:20.9434728-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:20.9434728-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z2')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0
{"#odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z2","Description":"Test Batch Z2","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:21.2241031-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:21.2241031-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 201 Created
Location: https://localhost:44331/api/v1/AddressComplianceCode('Z3')
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0
{"#odata.context":"https://localhost:44331/api/v1/$metadata#AddressComplianceCode/$entity","Code":"Z3","Description":"Test Batch Z3","MarkedForRetirement":false,"RetirementDate":null,"LastModifiedDate":"2019-03-12T10:19:21.5068813-04:00","LastModifiedBy":null,"CreatedDate":"2019-03-12T10:19:21.5068813-04:00","CreatedBy":null,"Delete":false,"Active":true}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 400 Bad Request
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
OData-Version: 4.0
{"error":{"code":"","message":"The input was not valid.","details":[{"code":"","message":"The input was not valid."}]}}
--batchresponse_f2c84aaf-dc39-4f20-8da0-881f402436fa--
No matter how many POST sections I add to the request ( I have tested 2, 3 and 4), the last request always fails to pass the request body values.
I have reviewed the Batch advanced tutorial at www.odata.org site, as well as all of the relevant SO posts I could find. I also tried the Github issues pages using the filter;
is:issue is:open batch
All with no luck so far.
What am I missing here?
Based upon my own experiences, I'd guess it's because you're sending LFs with Postman, rather than CRLFs.
Postman will send whatever newline you've entered (perhaps pasted in from something that prefers LF) , but multipart/mixed data requires CRLF. Sending just the LF confuses the ODataMultipartMixedBatchReader about whether a boundary line is an end-boundary or not, and causes the end-boundary marker to be added to the request. This in turn confuses the model binder on the ASP.NET Core side of things, which can't deserialize the request body.

Storage multipart upload with custom metadata not adding metadata

I'm constructing a multipart/related upload request, as described here, with some custom object metadata in the request body. The upload is successful but the custom metadata fields are not being set.
The request body looks like:
--===============5679188666781658153==
Content-Type: application/json; -charset="utf-8"
MIME-Version: 1.0
{"x-goog-meta-local-path": "./images/02-05-2017/2017-02-05T14:33:30.364112.jpg", "x-goog-meta-capture-ds": "2017-02-05T14:33:30.364112", "name": "0/02-05-2017/2017-02-05T14:33:30.364112.jpg"}
--===============5679188666781658153==
Content-Type: image/jpeg
MIME-Version: 1.0
Content-Transfer-Encoding: base64
<Image Data>
--===============5679188666781658153==--
From my understanding I should be able to arbitrarily set metadata key:value pairs as long as the keys are prefixed with x-goog-meta-*.
Am I missing something? How can I persist the custom metadata to the object using a multipart upload?
I found the answer in this related question: Google Storage API custom header on node.js
As jterrace points out:
Take a look at the JSON request builder here: https://developers.google.com/storage/docs/json_api/v1/objects/insert
You'll notice that metadata is a separate key in the body. So you'll want something like:
var metadata = {
name: "name"
contentLanguage: "en",
metadata: {
"something": "completely different",
},
acl: [...]
};

How to get Header Location value from a Fetch request in browser

From a ReactJS - Redux front app, I try to get the Location Header value of an REST API response.
When I Curl this :
curl -i -X POST -H "Authorization: Bearer MYTOKEN" https://url.company.com/api/v1.0/tasks/
I Have this answer :
HTTP/1.1 202 ACCEPTED
Server: nginx
Date: Fri, 12 Aug 2016 15:55:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Location: https://url.company.com/api/v1.0/tasks/status/idstatus
When I make a Fetch in ReactJS
var url = 'https://url.company.com/api/v1.0/tasks/'
fetch(url, {
method: 'post',
credentials: 'omit',
headers: {
'Authorization': `Bearer ${token}`
}
}
)
I don't have any Headers in the response object :
No header in Fetch request
I tried all the response.headers functions I've found in https://developer.mozilla.org/en-US/docs/Web/API/Headers :
response.headers.get('Location');
But well, as headers is empty, I have empty results.
Do you know why I can't get a proper Header object filled with the headers values ?
Thanks to John, I've found the answer.
I just had to put
Access-Control-Expose-Headers: Location
To my response headers and it worked, so now I can access Location value with :
response.headers.get('Location');
Thx John !
Besides to expose the Location Header in the server.
I just could access the location in the react application with:
response.headers.location;