This Quick Start guide will take you through the required steps to begin automating asset and product creation. There are 3 sequential steps:
- Importing your files
- Using those files to create assets
- Using the resulting assets to create your products
Since step one and two always go together, let's combine them into a single function:
Code
Node
ORGID: Can be obtained by opening up the console inside the Threekit Platform and typing:
PRIVATE_TOKEN: While inside the Threekit platform, go to settings and create a private token: Instructions for Creating Tokens.
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
const API_PATH = 'https://preview.threekit.com/api/';
const ASSET_IMPORT = 'asset-jobs/import';
const FILE_IMPORT = 'files';
const importedAssets = [];
const importedFiles = [];
const fileImportErros = [];
const assetImportErrors = [];
const importAssets = (folderPath, orgId, authToken, options) => {
fs.readdir(folderPath, async function (err, files) {
if (err) {
console.error('Could not list the directory.', err);
process.exit(1);
}
var fileCount = 0;
var assetCount = 0;
const numFiles = files.length;
const promises = files.map((file) => {
const data = new FormData();
data.append('orgId', orgId);
const fromPath = path.join(folderPath, file);
return new Promise((resolve) => {
fs.stat(fromPath, function (error, stat) {
if (error) {
console.error('Error stating file.', error);
return;
}
if (stat.isFile() && file.substr(-3) !== 'txt') {
console.log("'%s' is a file.", fromPath);
const fileStream = fs.createReadStream(fromPath);
data.append('file', fileStream);
axios({
method: 'post',
url: `${API_PATH}${FILE_IMPORT}`,
headers: {
'content-type': `multipart/form-data; boundary=${data._boundary}`,
authorization: `Bearer ${authToken}`,
},
maxContentLength: Infinity,
maxBodyLength: Infinity,
data,
})
.then((res) => {
console.log(
'Import file success',
fromPath,
res.data.files[0].id
);
console.log(`Total: ${++fileCount}/${numFiles}`);
importedFiles.push({
fileName: fromPath,
fileId: res.data.files[0].id,
});
importAsset(
fromPath,
res.data.files[0].id,
orgId,
authToken
).then(() => {
console.log('Import asset success', fromPath);
console.log(`Total: ${++assetCount}/${numFiles}`);
resolve();
});
})
.catch((err) => {
fileImportErros.push({
fileName: fromPath,
error: err.message,
});
resolve();
});
} else resolve();
});
});
});
await Promise.all(promises);
fs.writeFileSync(`successAssets.json`, JSON.stringify(importedAssets));
fs.writeFileSync(`successFiles.json`, JSON.stringify(importedFiles));
fs.writeFileSync(`failedAssets.json`, JSON.stringify(assetImportErrors));
fs.writeFileSync(`failedFiles.json`, JSON.stringify(fileImportErros));
console.log(
`Import job finish. Total count: ${numFiles}, Sucessful: ${assetCount}, Errors: ${
numFiles - assetCount
}`
);
const { cb } = options;
cb && typeof cb === 'function' && cb();
});
};
const importAsset = (fileName, fileId, orgId, authToken) => {
const data = new FormData();
data.append('orgId', orgId);
data.append('fileId', fileId);
data.append('sync', 'true');
return new Promise((resolve) => {
axios({
method: 'post',
url: `${API_PATH}${ASSET_IMPORT}`,
headers: {
'content-type': `multipart/form-data; boundary=${data._boundary}`,
authorization: `Bearer ${authToken}`,
},
data: data,
})
.then((res) => {
if (res.data.job.runs[0].resultCode === 'Success') {
const resultId = res.data.job.runs[0].results.files[0].id;
axios({
method: 'get',
url: `${API_PATH}files/${resultId}/content?bearer_token=${authToken}`,
})
.then((res) => {
importedAssets.push({ fileName, fileId, data: res.data });
resolve();
})
.catch((err) => {
assetImportErrors.push({ fileName, fileId, error: err.message });
resolve();
});
}
})
.catch((err) => {
assetImportErrors.push({ fileName, fileId, error: err.message });
resolve();
});
});
};
module.exports = importAssets;
This function takes in a folder path which contains the files you wish to import as assets and write JSON files for successful and failed imports containing assetIds and names. You can use the data in this file to create catalog items linked to these assets.
A file can trigger the creation of multiple assets by separating the model from the materials. If the objective is to automate product creation, it is recommended that you have a single model or material per file, to easily match file name to assetId.
Example JSON of successful assets
With this result, you can combine specific metadata you have for each file (from a spreadsheet, a file, a GraphQL server, a database, etc) with the resulting assetId to create a JSON file such as the one below.
Example JSON required for product creation
JSON
Utilizing the Product Import API with a JSON object such as the above, you can make use of the previously saved assetIds to create your products:
Code
Node