Skip to content

Instantly share code, notes, and snippets.

@kylenstone
Last active October 28, 2020 21:18
Show Gist options
  • Save kylenstone/3f054520426121121c71a8706ef296e3 to your computer and use it in GitHub Desktop.
Save kylenstone/3f054520426121121c71a8706ef296e3 to your computer and use it in GitHub Desktop.
Frame.io Folder Templater for Zapier Code Steps (Node 10.x+)
/**
/ This sample code demonstrates applying a Folder template to a Frame.io Project.
/ A Zapier Code Step must be configured to catch webhook events emitted by Frame.io.
/ Learn about Frame.io webhooks: https://docs.frame.io/docs/webhooks
/ Learn about using JavaScript in Zapier: https://zapier.com/help/create/code-webhooks/use-javascript-code-in-zaps
*/
// Destructure Zapier-defined variables
const { teamId, userId, resourceId, AUTH_TOKEN_KEY } = inputData;
// Frame.io variables. To run on Zapier you must provide your API Token
const AuthHeader = {
Authorization: `Bearer ${AUTH_TOKEN_KEY}`,
'Content-Type': 'application/json'
};
const API_URL = "https://api.frame.io/v2";
// This template defines a folder tree three levels deep
const template = [
{
"name": "top level folder",
"type": "folder",
"folders": [
{
"name": "Online",
"type": "folder"
},
{
"name": "Audio",
"type": "folder"
},
{
"name": "Deliverables",
"type": "folder"
},
{
"name": "Test sub-folder",
"type": "folder",
"folders": [
{
"name": "Test sub-sub-folder 1",
"type": "folder"
},
{
"name": "Test sub-sub-folder 2",
"type": "folder"
}
]
}
]
},
{
"name": "top level folder 2",
"type": "folder"
}
];
/* Every Project in Frame.io has a root_asset_id acting as a 'parent'
/ node to 'children' beneath it. This function returns the
/ root_asset_id for a Project. */
async function getRootAssetId(resourceId) {
let url = `${API_URL}/projects/${resourceId}`;
let options = {
method: 'GET',
headers: AuthHeader,
};
let response = await fetch(url, options).catch(err => {
console.error(`Error fetching root id for ${resourceId}: ${err}`);
throw err;
});
if (!response.ok) {
throw new Error(`Network error fetching root id for ${resourceId}: ${response.status}, ${response.statusText}`);
} else {
let jsonResponse = await response.json();
return jsonResponse.root_asset_id;
}
}
async function createFolder(name, parentId) {
let url = `${API_URL}/assets/${parentId}/children`;
let body = {
type: "folder",
name: name,
};
let options = {
method: 'POST',
headers: AuthHeader,
body: JSON.stringify(body)
};
console.log(`Attempting to create folder: ${name}`);
let response = await fetch(url, options).catch(err => {
console.error(`Error creating folder: ${name}: ${err}`);
throw err;
});
if (!response.ok) {
throw new Error(`[Network error creating folder ${name}: ${response.status}, ${response.statusText}`);
} else {
let result = await response.json();
return result.id;
}
}
/* Recursive function creates each folder in the template using preorder traversal */
const runTemplater = async (template, parentId) => {
while (template.length) {
let item = template.shift();
if (item.type === 'folder') {
let newParentId = await createFolder(item.name, parentId).catch(err => {
console.error(`folder creation error: ${item.name}: ${err}`);
throw err;
});
console.log(`runTemplater successfully created folder: ${item.name}`);
if (item.folders) {
await runTemplater(item.folders, newParentId);
}
}
}
return;
};
let root = await getRootAssetId(resourceId);
await runTemplater(template, root);
return {};
@kylenstone
Copy link
Author

kylenstone commented Oct 26, 2020

Here's exactly what the two Steps in my Zap look like in Zapier:

folderTemplaterStepOne

folderTemplaterStepTwo

@Claystation4
Copy link

Kick ass and thanks for sharing Kyle!

@machiq
Copy link

machiq commented Oct 28, 2020

Kyle, you are our secret weapon! Thanks for posting! Putting this to use right now ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment