New thumbnail feature - how to use in Java - google-drive-api

I'd like to leverage the new thumbnail feature of Google Drive using the latest Java SDK.
But all I get is a bad request response.
Can someone post a working example of this feature?
I've been simply setting the mimetype and Base64-encoded image data but this does not work - at least for file.insert and file.patch.
Update:
This is my (simplified) code snippet. It works fine without the new thumbnail stuff - and the encoded image data looks ok as well:
...
Drive drive = getDrive(account);
File file = new File();
file.setTitle(name);
...
HTTPResponse response = urlFetch.fetch(new URL(imageUrl));
String encodedImage = new String(Base64.encodeBase64(response.getContent()));
Thumbnail thumbnail = new Thumbnail();
thumbnail.setImage(encodedImage);
thumbnail.setMimeType("image/png");
file.setThumbnail(thumbnail);
file = drive.files().insert(file).execute();
This is the response:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 OK
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "badRequest"
} ],
"message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:143)
at com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:187)
at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:279)
at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:207)

The thumbnail image needs to be encoded as a Base64 UrlSafe String.
Using
String encodedImage = Base64.encodeBase64URLSafeString(response.getContent());
to encode the image fixed the issue.

Related

Data won't post correctly

I'm trying to use Google Apps Scripts to post to Salesforce to create a new account. I'm able to use my credentials fine to query with SOQL. When I try to post, it basically returns data as if I'm describing the Account, and the new account doesn't get created. I tried using the workbench rest API with this payload and can create an account no problem, so I know it's not an issue with fields/values.
function pushToSalesforce(){
var userProperties = PropertiesService.getUserProperties();
var instance_url = "https://na9.salesforce.com";
var access_token = userProperties.getProperty('access_token');
var payload = {
"Name" : "testaccount",
"Website" : "testaccountstuff.com",
"Platform__c" : "API",
"Industry" : "Apparel"
};
var queryUrl = instance_url + '/services/data/v26.0/sobjects/account/';
var headers =
{
"method" : "POST",
"contentType" : "application/json",
"payload": JSON.stringify(payload),
"headers": {
"Authorization" : "Bearer "+access_token,
"Accept": "application/json"
}
};
var response = UrlFetchApp.fetch(queryUrl, headers);
}
I'm going nuts trying to figure out what the issue is. Anybody have an idea?
Sounds like your app is making a GET instead of POST. Is this language / HTTP library case-sensitive? Documentation seems to use lowercase
You are supposed to send a POST to /services/data/v49.0/sobjects/Account (you're using very old API version but that shouldn't matter). What exactly do you see in response? It may look "describe'ish" but it's unlikely to be a real describe result unless you explicitly call /services/data/v49.0/sobjects/Account/describe.
A GET call to /services/data/v49.0/sobjects/Account is a discovery, a way for the API to self-document. Returns very basic info about the object, something like
{
"objectDescribe" : {
"activateable" : false,
"createable" : true,
"custom" : false,
(... snip...)
"updateable" : true,
"urls" : {
"compactLayouts" : "/services/data/v48.0/sobjects/Account/describe/compactLayouts",
"rowTemplate" : "/services/data/v48.0/sobjects/Account/{ID}",
"approvalLayouts" : "/services/data/v48.0/sobjects/Account/describe/approvalLayouts",
"defaultValues" : "/services/data/v48.0/sobjects/Account/defaultValues?recordTypeId&fields",
"listviews" : "/services/data/v48.0/sobjects/Account/listviews",
"describe" : "/services/data/v48.0/sobjects/Account/describe",
"quickActions" : "/services/data/v48.0/sobjects/Account/quickActions",
"layouts" : "/services/data/v48.0/sobjects/Account/describe/layouts",
"sobject" : "/services/data/v48.0/sobjects/Account"
}
},
"recentItems" : [ ]
}
A proper describe call would instead return info about all columns you can see in the table, all relations (foreign keys) to this object...
In my actual script was the "my domain" custom instance_url for my company (but didn't want to broadcast it), e.g. "https://companyname.lightning.force.com". I tried using my server instance "na85" instead and it worked fine! Super weird because I have another function using the other instance_url with a GET and it worked no problem. Thanks for your help!

With Vimeo API, unable to create new album even with access token and create scope

I'm using Vimeo's official NodeJS API module to build an app, and I can successfully upload a video without issue. I can also set the video's privacy property successfully. Now, I would like to move that uploaded video to an album, and if the album does not exist, I want to create one automatically. I have an access token stored in a file that my application reads from, and the scopes granted to the token are the following
"scope": "interact create edit upload delete video_files private public"
So, I've got the create scope which is needed to create a new album for a user. However, when I make the request to the Vimeo API, I am getting an error of which I cannot resolve or fix.
{
"invalid_parameters":[{
"field":"name",
"error_code":2204,
"error":"You have provided an invalid parameter. Please contact developer of this application.",
"developer_message":"The parameters passed to this API endpoint did not pass Vimeo's validation. Please check the invalid_parameters list for more information."
}]
}
Here is my code that is making the request:
if (!album_uri) {
console.log("Attempting to create a new album named `" + config.params.video.group + "`");
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : config.params.video.group
, "description" : config.params.video.group
};
api.request(req_make_album, function(error, body, status_code, headers) {
if (error)
throw new Error(error);
step();
})
}
To be sure, the config.params.video.group variable is a string and to be certain that it was in fact a string, I replaced the request options with literal ones as such:
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : "My First New Album"
, "description" : "My First New Album"
};
Still, I received the above error about the "name" field being invalid. What am I missing here? When I go to the Vimeo API "playground" for this particular endpoint, it does work (even when I authenticate via my app) but I don't understand why it won't work when I make the request via the NodeJS module. Why am I getting this error?
My mistake. The issue is that the Vimeo API requires that the items "name" and "description" to be passed as an object.
So, instead of
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "name" : "My First New Album"
, "description" : "My First New Album"
};
It should actually be:
var req_make_album = {
"method" : "POST"
, "path" : "/me/albums"
, "query" : {"name" : "My First New Album", "description" : "My First Album's Description"
};
The more you know :)

Issue deleting instances with google API Explorer

I have tried deleting instances using https://cloud.google.com/compute/docs/reference/beta/instanceGroupManagers/deleteInstances but it's not working.
In the request body, I am entering
{
"instances": [
"scaler-group-instance-1"
]
}
For project, I used project-name-1
For zone, I used us-west1-a
For instanceGroupManager I am using scaling-group-manager
In response, I am receiving
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid value for field 'instances[0]': 'scaler-group-instance-1'. The URL is malformed.",
"reason" : "invalid"
} ],
"message" : "Invalid value for field 'instances[0]': 'scaler-group-instance-1'. The URL is malformed."
}
I have also tried this in Java as well using this code snippet and have also received a 400 Bad Request
String projectId = "project-name-1";
String zoneName = "us-west1-a";
String instanceGroupName = "scaling-group-manager";
List<String> instancesToDelete = new ArrayList<>();
instancesToDelete.add("scaler-group-instance-1");
InstanceGroupManagersDeleteInstancesRequest deleteInstancesRequest = new InstanceGroupManagersDeleteInstancesRequest().setInstances(instancesToDelete);
Compute.InstanceGroupManagers.DeleteInstances deleteInstances = compute.instanceGroupManagers().deleteInstances(projectId, zoneName, instanceGroupName, deleteInstancesRequest).execute();
Is there something wrong with my request that I'm not seeing?
I found the issue. This request expects the instance string to be a URL and not an instance name.
The instance can be found in the selfLink value in the listInstances requests.
Entering the selfLink URL into the request caused the server to reply correctly.

Best way to do authorisation through REST API using Lumen?

I am making a simple REST API using latest stable version of Lumen. That API is going to be used in mobile applications, and there is one thing I'm not sure about.
What is the best ( secure enough ) way to an authorization? At the moment I am doing a simple POST request to the server url like http://api.example.com/v1/auth with username and password parameters and return a JSON response like
{ "code" : 200, "message" : "OK", "access_token" : string }
or
{ "code" : 401, "message" : "Unauthorized" }
Is JSON response a good solution?
Is it better to return response code within header?
Have you checked this? https://softwareengineering.stackexchange.com/questions/183665/the-best-way-to-implement-authorization-for-a-rest-api
200 and 401 seem the "standard" response to me.

Bad Request error while using google drive api to copy file into a folder

I am trying to use the google drive api to copy a file into a folder
As the documentation says i am generating a POST request to https://www.googleapis.com/drive/v2/files/{fileId}/copy?access_token={MY_ACCESS_TOKEN}
i am using python to generate the request and in order to specify the target folder i am setting the request body to -
{
"parents":
[
{
"id":"{parent_id}"
}
]
}
so the final code is like-
url = https://www.googleapis.com/drive/v2/files/Ansjd021-23123414kjn2k3jn2/copy?access_token=Ya.asdsakjn2312k3n21kj3n-12312j3knb123l
body = {
"parents":
[
{
"id":"ZXC12312323123-Blahasd12323X"
}
]
}
request2 = urllib2.Request(url, urllib.urlencode(body))
request2_open = urllib2.urlopen(request2)
response = request2_open.read()
request2_open.close()
print response
The problem being that I am getting a Http Error : 404 Bad Request
I cant seem to figure out the problem with this. I am doing the same thing using the google playground and its running there.
I did this using https://developers.google.com/drive/v2/reference/files/copy#try-it and got ...
POST https://www.googleapis.com/drive/v2/files/1234/copy?key={YOUR_API_KEY}
Content-Type: application/json
Authorization: Bearer ya29.AHES6ZSZB-t4b4HsR5
X-JavaScript-User-Agent: Google APIs Explorer
{
"parents": [
{
"id": "1234"
}
]
}
This looks pretty much the same as your sample, except the authtoken is in an http header rather than the URL. Also, what happens if you don't urlencode the body? Is there a longer error message in the response body?