Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Image and file upload via mutation generateStagedUploads problem

Image and file upload via mutation generateStagedUploads problem

MR_DEVELOPERS
Shopify Partner
7 0 5

Hi Community Developers,

I have failed to upload file via Graphql generateStagedUploads. Can someone help?

I followed this tutorial https://shopify.dev/api/examples/product-media. But the response seems not exactly same. In my response I can not find the bucket name, policy and other fields from parameters: []. so I assumed that I can use the "url" in "stagedTargets": [] directly. But I always got an SignatureDoesNotMatch error.

 

<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>

 

The did the following steps:


I made a call:

 

mutation generateStagedUploads($input: [StagedUploadInput!]!) {
                      stagedUploadsCreate(input: $input) {
                        stagedTargets {
                          url
                          resourceUrl
                          parameters {
                            name
                            value
                          }
                        }
                        
                      }
                    }
variables = {
                  "input": [
                    {
                      "filename": "blank-logo.png",
                      "mimeType": "image/png",
                      "resource": "IMAGE",
                      "fileSize": str(size)

                    }
                  ]
                }

 

 I got data responsed:

 

{
    "data": {
        "stagedUploadsCreate": {
            "stagedTargets": [
                {
                    "url": "https:\/\/shopify.s3.amazonaws.com\/tmp\/58504741015\/products\/17f18b13-6453-4cd9-a124-5a7c54834df4\/blank-logo.png?x-amz-acl=private\u0026X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=AKIAJYM555KVYEWGJDKQ%2F20210811%2Fus-east-1%2Fs3%2Faws4_request\u0026X-Amz-Date=20210811T055124Z\u0026X-Amz-Expires=900\u0026X-Amz-SignedHeaders=host\u0026X-Amz-Signature=1e2c67cda90abe7ea6a7c1b2731883f4417badf8139a23807dcb31c129f71e02",
                    "resourceUrl": "https:\/\/shopify.s3.amazonaws.com\/tmp\/58504741015\/products\/17f18b13-6453-4cd9-a124-5a7c54834df4\/blank-logo.png",
                    "parameters": [
                        {
                            "name": "content_type",
                            "value": "image\/png"
                        },
                        {
                            "name": "acl",
                            "value": "private"
                        }
                    ]
                }
            ]
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 11,
            "actualQueryCost": 11,
            "throttleStatus": {
                "maximumAvailable": 1000.0,
                "currentlyAvailable": 989,
                "restoreRate": 50.0
            }
        }
    }
}

 

and then i make this call in python:

 

headers = {
            'x-amz-acl': 'private',
            'Content-Type': 'image/png'
        }
        with open('blank-logo.png', 'rb') as f:
            response = requests.request("POST", url_aws, headers=headers, data=f)

 

I also tried curl in terminal and postman:

 

curl -v \
  -F "x-amz-acl=private" \
  -F "Mime-Type=image/png" \
  -F "key=tmp/58504741015/products/a1a28122-03b0-42f0-bb58-1626583177f0/blank-logo.png" \
  -F "Filename=blank-logo.png" \
  -F "file=@/Volumes/Development/backend_project/project-blank-integration/blank-logo.png" \
   "https://shopify.s3.amazonaws.com/tmp/58504741015/products/a1a28122-03b0-42f0-bb58-1626583177f0/blank-logo.png?x-amz-acl=private&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJYM555KVYEWGJDKQ/20210811/us-east-1/s3/aws4_request&X-Amz-Date=20210811T055512Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=58391e74775af43ec4585ae078e2178fd19c286d830085f53868e456866f696d"

 

Screen Shot 2021-08-11 at 5.59.33 PM.png

 

Could you please help me with the correct way to using the aws url?

Thank you very much!

Barrick

Replies 8 (8)

fact
Shopify Partner
2 0 0

I have the same issue

TudorBNG
Shopify Partner
2 0 0

I have the same issue. Did anyone manage to find a solution?

Matthias7
Excursionist
30 3 3

I just posted a question asking the same thing, does anyone have any enlightenment on the subject?  🙂

twilson90
Shopify Partner
32 0 23

Same issue.

Anyone finally worked this out?

Matthias7
Excursionist
30 3 3

Which part is not working? 
Are you receiving a response from the StagedUploadsCreate? 

 

Cheers, Matthias

 

twilson90
Shopify Partner
32 0 23

No, I would get a nondescript error when i tried to post an image using this method.

Videos however worked.

I got it working in the end by changing my initial input when declaring the image upload.

I'm not at my PC right now so I cant tell you the exact details, but I can a bit later.

Matthias7
Excursionist
30 3 3

ah if its working 🙂 then congrats 

twilson90
Shopify Partner
32 0 23

Here's how I got it working for anyone who might find it useful. Note that I'm using the node api:

 

 

var stat = fs.statSync(filepath);
var input = {
  "filename": convert_to_handle(product_title)+"-"+String(++i).padStart(3,"0")+path.extname(m),
  "mimeType": mimetype,
  "resource": media_type,
}
if (media_type == "IMAGE") input["httpMethod"] = "POST";
else input["fileSize"] = stat.size.toString();
inputs.push(input);
var resp = await shopify.graphql(
  `mutation generateStagedUploads($input: [StagedUploadInput!]!) {
    stagedUploadsCreate(input: $input) {
      stagedTargets {
        url
        resourceUrl
        parameters { name, value }
      }
      userErrors {
        field, message
      }
    }
  }`, {
    input: [input]
  }
);

var t = resp.stagedUploadsCreate.stagedTargets[0];
var media = {
  "alt": product_title,
  "mediaContentType": media_type,
  "originalSource": t.resourceUrl,
}
var form_data = new FormData();
for (var p of t.parameters) {
  form_data.append(p.name, p.value);
}
form_data.append("file", fs.createReadStream(filepath));
await axios.post(t.url, form_data);

await shopify.graphql(
  `mutation createProductMedia($id: ID!, $media: [CreateMediaInput!]!) {
    productCreateMedia(productId: $id, media: $media) {
      media {
        ${fields.media}
        mediaErrors {
          code
          details
          message
        }
        mediaWarnings {
          code
          message
        }
      }
      mediaUserErrors {
        code
        field
        message
      }
    }
  }`, {
    id: product_id,
    media: [media]
  }
);

 

 

The important part I was missing that was causing the issue I'm pretty sure was  declaring the 'httpMethod' specifically for images.