When I am using the AIO library and I try to create a rendition using the createRendition call I am getting the following error:
{
code: 403,
details: [
{
name: 'https://s3.amazonaws.com/...',
reason: 'Unable to upload the outputs'
}
],
title: 'Access Is Forbidden',
type: 'AuthForbidden'
}
Here is the code I'm using:
const util = require('util');
const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);
const sdk = require('@adobe/aio-lib-photoshop-api');
function createRenditionOfPSD() {
// GENERATE A NEW TOKEN
const authDetails: string = await this.generateIMSToken(clientIdAndApiKey, clientSecret);
let authInfo = JSON.parse(authDetails);
authToken = authInfo.access_token;
// CREATE PS API OBJECT
const client = await sdk.init(ims, clientIdAndApiKey, authToken);
// GET SIGNED URL
var signedPSDGetURL = await getSignedUrl(key, bucket);
// CREATE SIGNED URL FOR SAVING THE OUTPUT
var psdImageKey = id + ".png";
//var signedOutputURL = await getSignedPutUrl(psdImageKey, bucket);
var signedOutputURL = await getSignedPostUrl(psdImageKey, bucket);
// CREATE DOCUMENT RENDITION
var psdInputOptions = {
href: signedPSDGetURL,
storage: sdk.Storage.EXTERNAL
}
var psdOutputOptions = {
href: signedOutputURL,
type: sdk.MimeType.PNG,
storage: sdk.Storage.EXTERNAL,
overwrite: true
}
const renditionResults = await client.createRendition(psdInputOptions, psdOutputOptions);
console.log(renditionResults);
var outputs = psdRenditionResults.outputs;
for (var output in outputs) {
var outputItem = outputs[output];
var status = outputItem.status;
if (status=="failed") {
var errors = outputItem.errors;
console.log(errors);
}
log(output)
}
}
The results:
Job {
getJobStatus: [Function: bound __getJobStatus] AsyncFunction,
url: 'https://image.adobe.io/pie/psdService/status/....',
jobId: '...',
outputs: [
{
input: 'https://s3.amazonaws.com/...',
status: 'failed',
created: '...',
modified: '...',
errors: [Object]
}
],
_links: {
self: {
href: 'https://image.adobe.io/pie/psdService/status/...'
}
}
}
The get signed PUT url and get signed Post URL functions are below:
export async function getSignedPutUrl(
key: string,
bucket: string,
expireAfterMinutes: number = 0,
options = null,
): Promise<string> {
const s3 = new AWS.S3();
var params = {
Bucket: bucket,
Key: key,
};
if (options) {
params = Object.assign(params, options);
}
const url = await s3.getSignedUrlPromise("putObject", params);
return url;
}
export async function getSignedPostUrl(
key: string,
bucket: string,
expireAfterMinutes: number = 0,
options = null,
): Promise<string> {
const s3 = new AWS.S3();
var params = {
Bucket: bucket,
Fields: {
Key: key,
ContentType: "application/octet-stream",
},
};
if (options) {
params = Object.assign(params, options);
}
const presignedPost = await s3.createPresignedPost(params);
const url = presignedPost.url;
return url;
}
I've tried creating a PUT URL and a POST URL, removed the ContentType and so far nothing has worked. Is there something I'm missing?
Creating a presigned post URL.
UPDATE:
Found more info on the storage types. The page says for saving the output it's a PUT URL but this example code for createRendition says POST URL but the other example page says PUT url. Will update and see. There's example S3 code. I've got it to save. The save status is not "failed". But having issues with getting the url returned. I probably have to sign it.



To save the output requires an exact match of the signed URL to the service and the service sending the exact form to that URL.
There is no way to get that exact match from trial and error. There was a slightly misleading code example but the same page linked to the documentation that has example code for s3 here.
Here is the basic get put url function using async (but check their documentation):