I working on creating Google slides via java using service account. I'm able to:
- authenticate
- create drive and slide service
- create presentation and add empty slide
I'm struggling with adding image from binary. I can add image that is stored in some online image storage. I have problem with adding image that is byte[]. I dig and I found that image must be uploaded to drive location and I'm able to do that. The problem I have is with adding that image to the slide in presentation. I'm receiving:
`Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
POST https://slides.googleapis.com/v1/presentations/1yUi4nMxjdOfI97jvJP9uG42LyT_5Kd4NN_M9S-B65CM:batchUpdate
{
"code": 400,
"errors": [
{
"domain": "global",
"message": "Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.",
"reason": "badRequest"
}
],
"message": "Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.",
"status": "INVALID_ARGUMENT"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:118)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:37)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:439)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1111)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:525)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:466)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:576)
at com.microstrategy.sdk.AddImageFromBinary.insertImageRequestIntoSlide(AddImageFromBinary.java:165)
at com.microstrategy.sdk.AddImageFromBinary.main(AddImageFromBinary.java:119)Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
POST https://slides.googleapis.com/v1/presentations/1yUi4nMxjdOfI97jvJP9uG42LyT_5Kd4NN_M9S-B65CM:batchUpdate
{
"code": 400,
"errors": [
{
"domain": "global",
"message": "Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.",
"reason": "badRequest"
}
],
"message": "Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.",
"status": "INVALID_ARGUMENT"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:118)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:37)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:439)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1111)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:525)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:466)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:576)
at com.microstrategy.sdk.AddImageFromBinary.insertImageRequestIntoSlide(AddImageFromBinary.java:165)
at com.microstrategy.sdk.AddImageFromBinary.main(AddImageFromBinary.java:119)`
Service account has necessary access and it's owner of the png file that is created in drive location. Scope for credentials is set:
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_FILE, SlidesScopes.PRESENTATIONS, SlidesScopes.DRIVE_FILE);
Here is code:
private static final String CREDENTIALS_FILE_PATH = "/booking.json";
private static final String GOOGLE_FOLDER_MEDIA_TYPE = "application/vnd.google-apps.folder";
private static final String GOOGLE_SLIDES_MEDIA_TYPE = "application/vnd.google-apps.presentation";
public static void main(String[] args) throws Exception {
InputStream in = AddImageFromBinary.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleCredentials credentials = GoogleCredentials.fromStream(in).createScoped(SCOPES);
System.out.println(credentials);
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
// Build a new authorized API client service.
Drive service = new Drive.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(), requestInitializer)
.setApplicationName(APPLICATION_NAME).build();
Slides slidesService = new Slides.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(),
requestInitializer).setApplicationName(APPLICATION_NAME).build();
// createFolder(service, "aaa");
String presentationName = "Test-presentation-10";
Presentation presentation = createGooglePresentation(slidesService, presentationName);
String presentationId = presentation.getPresentationId();
System.out.println("presentationId: " + presentationId);
//IMPORTANT to get presentation obj. again
presentation = getPresentation(slidesService, presentationId);
presentationId = presentation.getPresentationId();
System.out.println("new presentationId: " + presentationId);
if (presentation.getSlides() != null && !presentation.getSlides().isEmpty()) {
System.out.println("removing first slide");
String firstSlideId = presentation.getSlides().get(0).getObjectId();
deleteFirstSlide(slidesService, presentationId, firstSlideId);
//presentation = getPresentation(slidesService, presentationId);
}
String slideId = createSlide(slidesService, presentationId);
System.out.println("Slide ID: " + slideId);
byte[] pictureData = getImageFromPDF(fullExportData);
// Upload the image to Google Drive and get the file ID
String imageFileId = uploadImageToDrive(service, pictureData);
getPermissions(service, imageFileId);
String imageUrl = getImageUrl(service, imageFileId);
//String imageUrl = "https://drive.google.com/uc?id=1SGtAp_KMmPHuts1HHap0TiY8CsKWJGeT";
//CreateImageRequest imageRequest = createImageRequest(imageUrl);
// Insert the image request into the slide
insertImageRequestIntoSlide(slidesService, presentationId, slideId, imageUrl);
if (!presentationId.isEmpty()) {
uploadGoogleSlides(service, presentationId, presentationName);
System.out.println("Upload success...");
}
}
private static Presentation createGooglePresentation(Slides slidesService, String title) throws Exception {
Presentation presentation = null;
try {
// Creates a blank presentation with a specified title.
presentation = new Presentation().setTitle(title);
presentation = slidesService
.presentations()
.create(presentation)
.setFields("presentationId")
.execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return presentation;
}
public static Presentation getPresentation(Slides slidesService, String presentationId) throws IOException {
return slidesService.presentations().get(presentationId).execute();
}
public static String createSlide(Slides service, String presentationId) throws IOException {
// Add a slide at index 1 using the predefined "TITLE_AND_TWO_COLUMNS" layout
List<Request> requests = new ArrayList<>();
String slideId = null;
BatchUpdatePresentationResponse response = null;
try {
requests.add(new Request().setCreateSlide(new CreateSlideRequest()
));
BatchUpdatePresentationRequest body = new BatchUpdatePresentationRequest().setRequests(requests);
response = service.presentations().batchUpdate(presentationId, body).execute();
CreateSlideResponse createSlideResponse = response.getReplies().get(0).getCreateSlide();
// Prints the slide id.
slideId = createSlideResponse.getObjectId();
System.out.println("Created slide with ID: " + slideId);
} catch (GoogleJsonResponseException e) {
// TODO(developer) - handle error appropriately
GoogleJsonError error = e.getDetails();
if (error.getCode() == 400) {
System.out.printf(" Id '%s' should be unique among all pages and page elements.\n", presentationId);
} else if (error.getCode() == 404) {
System.out.printf("Presentation not found with id '%s'.\n", presentationId);
} else {
throw e;
}
}
return slideId;
}
private static String uploadImageToDrive(Drive service, byte[] imageBytes) throws IOException {
File fileMetadata = new File()
.setName("image.png")
.setMimeType("image/png")
.setParents(Collections.singletonList(ROOT_FOLDER));
ByteArrayContent mediaContent = new ByteArrayContent("image/png", imageBytes);
File file = service.files().create(fileMetadata, mediaContent)
//.setFields("id")
.setFields("id , parents")
.execute();
return file.getId();
}
`private static String getImageUrl(Drive service, String imageId) {
try {
// Use the Drive service to retrieve information about the file
File file = service.files().get(imageId).setFields("webContentLink").execute();
// The webContentLink provides the URL to download the file (image)
String imageUrl = file.getWebContentLink();
System.out.println("Image URL: " + imageUrl);
return imageUrl;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}`
`private static void insertImageRequestIntoSlide(Slides slidesService, String presentationId, String slideId, String imageUrl) throws IOException {
CreateImageRequest createImageRequest = new CreateImageRequest()
.setObjectId("myImage")
.setUrl(imageUrl)
.setElementProperties(new PageElementProperties()
.setPageObjectId(slideId)
.setSize(new Size()
.setHeight(new Dimension()
.setMagnitude(300.0)
.setUnit("PT"))
.setWidth(new Dimension()
.setMagnitude(400.0)
.setUnit("PT")))
.setTransform(new AffineTransform()
.setScaleX(1.0)
.setScaleY(1.0)
.setTranslateX(50.0)
.setTranslateY(50.0)));
Request imageRequest = new Request().setCreateImage(createImageRequest);
BatchUpdatePresentationRequest batchUpdateRequest = new BatchUpdatePresentationRequest()
.setRequests(Collections.singletonList(imageRequest));
slidesService.presentations().batchUpdate(presentationId, batchUpdateRequest).execute();
}`
`
private static String uploadGoogleSlides(Drive service, String presentationId, String title) throws IOException {
String presentationCopyId = null;
try {
// Copies an existing presentation using specified presentation title.
File copyMetadata = new File()
.setName(title)
.setParents(Collections.singletonList(ROOT_FOLDER));
File presentationCopyFile = service.files().copy(presentationId, copyMetadata).setFields("id , parents")
.execute();
presentationCopyId = presentationCopyFile.getId();
// Prints the new copied presentation id.
System.out.println("New copied presentation id " + presentationCopyId);
} catch (GoogleJsonResponseException e) {
// TODO(developer) - handle error appropriately
GoogleJsonError error = e.getDetails();
if (error.getCode() == 404) {
System.out.printf("Presentation not found with id '%s'.\n", presentationId);
} else {
throw e;
}
}
return presentationCopyId;
}
`