Development discussions around Shopify APIs
Don't have this problem with uploading video or images, but for some reason it's not allowing me to upload 3d models with a .glb extension.
I successfully uploaded the file in the staging process, then when it comes to using 'mutation fileCreate' in the 2023-07 API, I get the following error:
in stagedUploadsCreate how did you define the mutation in GraphQL especially the filename of the model?
var file_inputs = [];
var upload_inputs = [];
var contents = [];
for (var data of datas) {
var filename = path.basename(data.filename);
var stat = null;
var resource = data.resource || ShopifyWrapper.UPLOAD_TARGET_RESOURCE_TYPES.FILE;
try { stat = fs.statSync(data.filename); } catch {}
var mimetype = data.mimetype || mime.lookup(data.filename) || "";
var content_type = mimetype.split("/")[0].toUpperCase();
if (!["FILE","IMAGE","VIDEO"].includes(content_type)) content_type = "FILE";
var file_input = {
"filename": filename,
"alt": data.alt,
"contentType": content_type,
}
var content = data.content || (await fs.readFile(data.filename));
if (content instanceof Readable) content = await streamToBuffer(content);
var size = data.size;
if (!size && content) content.length
var upload_input = {
"filename": filename,
"mimeType": mimetype,
"resource": resource,
"fileSize": size,
"httpMethod": "POST",
}
contents.push(content);
file_inputs.push(file_input);
upload_inputs.push(upload_input);
}
if (upload_inputs.length) {
var response = await this.graphql(
`mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
stagedUploadsCreate(input: $input) {
stagedTargets {
url
resourceUrl
parameters { name, value }
}
userErrors {
field, message
}
}
}`, {
input: upload_inputs
}
);
if (response.stagedUploadsCreate.userErrors.length) console.error(response.stagedUploadsCreate.userErrors);
for (var i = 0; i < file_inputs.length; i++) {
var file_input = file_inputs[i];
var content = contents[i];
var t = response.stagedUploadsCreate.stagedTargets[i];
file_input.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", content, {filename:file_input.filename});
var res = await axios.post(t.url, form_data);
}
}
return file_inputs;
^ This is the code I used. The bit you probably need to know about is how to define each StagedUploadInput:
var upload_input = {
"filename": filename,
"mimeType": mimetype,
"resource": resource,
"fileSize": size,
"httpMethod": "POST",
}
You use that to define each file you're about to upload and it has to be correct. For 3d models (or any file type) the 'resource' field has to equal "FILE" if you are just uploading to the 'Files' section essentially. It's a very strange and intolerant system!
The response contains a special url that you can then upload to. Then you make a request to that url for each file using the httpMethod that you stated earlier, attaching each file as form data.
I was able the generate the resourceUrl and upon logging it, but its giving me an error saying no such key exists, I am thinking that there might be an issue with only the filename I am calling,
const stagedUploadsResponse = await admin!.graphql(
`#graphql
mutation StagedUploadsCreate($input: [StagedUploadInput!]!) {
stagedUploadsCreate(input: $input) {
stagedTargets {
url
resourceUrl
parameters {
name
value
}
}
}
}`,
{
variables: {
input: [
{
filename: "watch.glb",
mimeType: "model/gltf-binary",
resource: "FILE",
fileSize: "3846680",
httpMethod: "POST",
},
],
},
},
);