A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
I use Graphql API: stagedUploadsCreate, then I send request to Url: https://shopify.s3.amazonaws.com.
But response Location url: Access Denied
I then send a request to the Graphql API: fileCreate and the image is not uploaded successfully.
When I submit a public image url from google I don't get the returned image url in: files -> preview -> image -> originalSrc.
Here is my PHP code:
use PHPShopify\ShopifySDK;
$file = $_FILES['upload'];
$filename = $file['name'];
$mimeType = $file['type'];
$filesize = (string) $file['size'];
$query = '
mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
stagedUploadsCreate(input: $input) {
stagedTargets {
url
resourceUrl
parameters {
name
value
}
}
userErrors {
field
message
}
}
}
';
$variables = [
'input' => [
'fileSize' => $filesize,
'filename' => $filename,
'httpMethod' => 'POST',
'mimeType' => $mimeType,
'resource' => 'FILE'
]
];
$config = [
'ShopUrl' => 'onepiece-test.myshopify.com',
'AccessToken' => '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',
];
$shopify = ShopifySDK::config($config);
$response = $shopify->GraphQL->post($query, null, null, $variables);
$client = new \GuzzleHttp\Client();
$url = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['url'];
$resourceUrl = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['resourceUrl'];
$parameters = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['parameters'];
$formData = [];
foreach ($parameters as $parameter) {
$formData[] = [
'name' => $parameter['name'],
'contents' => $parameter['value']
];
}
$formData[] = [
'name' => 'file',
'contents' => $file['tmp_name']
];
try {
$response = $client->request('POST', $url, [
'headers' => [
'Accept' => 'application/json',
],
'multipart' => $formData
]);
$xml = simplexml_load_string($response->getBody()->getContents());
$convertJson = json_encode($xml);
$convertArray = json_decode($convertJson, true);
$imageUrl = urldecode($convertArray['Location']);
// $imageUrl = $url . '/' . $imageKey['value'];
// $imageUrl = 'https://www.industrialempathy.com/img/remote/ZiClJf-1920w.jpg';
// dd($imageUrl);
$query = '
mutation fileCreate($files: [FileCreateInput!]!) {
fileCreate(files: $files) {
files {
alt
createdAt
fileErrors {
code
details
message
}
fileStatus
preview {
image {
altText
height
id
originalSrc
transformedSrc
width
}
status
}
}
userErrors {
code
field
message
}
}
}
';
$variables = [
'files' => [
[
'originalSource' => $resourceUrl,
]
]
];
$response = $shopify->GraphQL->post($query, null, null, $variables);
dd($response);
} catch (RequestException $e) {
throw $e;
}
Can you help me. Thanks
Hey @lekhang25122,
I took a closer look here at your questions, code and worked through a bit of testing.
While I am not a PHP developer, this does seem to be the correct approach. Have you tried logging out the GuzzleHttp request data to confirm that this multipart/form data is formatted properly, and that all the 'parameters' returned from the stagedUploadCreate mutation are being passed? For file uploads, I did a quick example cURL request that was worked as expected. From there I used this to staged upload process with a .json file and utilized the corresponding "resourceURL" when completing the fileCreate mutation. Here is that request:
curl -v -X "POST" \
-F "key= {VALUE}" \
-F "content-type=text/json" \
-F "success_action_status=201" \
-F "acl=private" \
-F "policy={VALUE}" \
-F "x-amz-credential={VALUE}" \
-F "x-amz-algorithm={VALUE}" \
-F "x-amz-date={VALUE}" \
-F "x-amz-signature={VALUE}" \
-F "file=~{FILE}" \
"https://shopify.s3.amazonaws.com/"
Does your logging match this request structure?
- Cheers
awwdam | API Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
S3 expects the content type in the header. Try adding the following:
"Content-Type" => $mimeType
"POST" should also be replaced with HTTP method "PUT"
You can find some examples for other languages here on the AWS docs:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html