Guide
There can be times when you want an automation to do something a bit more complicated, something which might not be possible using the existing actions. In these cases, scripting can help.
The scripts are executed with Node.js 22, so feel free to use async/await and other recent JS features.
Script
Select Script in Actions to create a script. All scripting is written using the JavaScript language. You don't need to be a complete master, but having a basic understanding will help.
AI Assistant
You can generate Scripts in automations using AI prompts. For example, let’s generate a script to close all tasks related to a product:
You can use AI to learn Scripts and write them faster. In most cases it is way faster to start with an incorrect script and fix some errors than type everything from scratch.
AI-generated scripts are not always correct, they can have mistakes, so please review them carefully.
Some prompts examples to spark the creativity:
Add tasks with following names to feature: “Design”, “Implementation”, “Testing”.
Move all tasks to the final state
Move all non-completed features to new sprint with name of “Sprint X Split”
Post product entity as JSON to https://SOME_URL
Add tasks descriptions to description of a feature
Services
A script has access to the following services: fibery, http and utils.
Use the fibery service to perform some operations on your Fibery workspace.
const fibery = a.getService('fibery');
Use http to make arbitrary requests on the web.
The utils service has some commonly-used utilities.
Once a service has been defined, the functions available for that service can be used, e.g.
fibery.deleteEntity("Tasks/Task","6a5ca230-da86-11ea-a1b3-ff538984283f")
Await
The available Fibery functions are asynchronous, so you will need to use the await keyword when calling them, and since some of the functions return a result, you will typically want to save the result in a variable, e.g.
const newTask = await fibery.createEntity("Tasks/Task",{"Name":"New Task"});
Arguments
When an action button is run or a rule is triggered, there are pieces of data that are available to be accessed within the script.
This includes the entity (or entities) that was (were) selected/active when the button was pressed/trigger occurred, the identity of the user that pressed the button/triggered the rule, and the results of previous steps.
Trigger
The triggering entity (or entities) is available as args.currentEntities which is an array of objects.
It will look something like this:
[
{
"Public Id": "1",
"Id": "a129d810-f8a0-11e8-88d2-3d1a5c86c61f",
"Creation Date": "2018-12-05T15:15:41.738Z",
"Modification Date": "2019-09-27T08:48:08.873Z",
"Rank": 500000,
"Name": "Swim farthest",
"State": {
"Name": "Done",
"Id": "70df7a70-f8a0-11e8-a406-9abbdf4720ab"
},
"type": "Tasks/Task"
},
{
...
}
]
User
The User causing the automation to run is available as args.currentUser which is an object that will typically look something like this:
{
"Public Id": "1",
"Id": "fe1db100-3779-11e9-9162-04d77e8d50cb",
"Email": "vincent@gattaca.dna",
"Creation Date": "2019-02-23T14:47:49.262Z",
"Modification Date": "2019-09-27T08:17:46.608Z",
"Name": "Vincent Freeman",
"Role": {
"Id": "57d5dd70-b9df-11e9-828d-51c8014f51c9",
"Name": "Navigator"
},
"type": "fibery/user"
}
If a rule has been triggered by something other than a user action, e.g. when the value of a formula field containing the Today() function changes, then args.currentUser will return null.
Steps
The results of previous steps are available as args.steps which is an array of objects. Each element is an object corresponding to a previous step. An automation that added a Task to a Project (in step 2) might generate something like this for args.steps :
[
{ result: null },
{
result: {
entities: [
{
id: 'f18fcef0-d225-11ed-b709-adb989f0f62c',
type: 'SpaceName/Project'
}
]
}
},
{
result: {
message: 'Add Tasks Item: 1 Task added',
entities: [
{
id: '14642800-31d4-11ee-a348-0999a062bf2d',
type: 'SpaceName/Task'
}
]
}
}
]
The first element (args.steps[0]) has no valid result since there is no step zero.
Success and error messages (Buttons)
A scripted Button can display custom messages to the person who clicked it:
To add a custom success message, return this message as a string at the end of your script:
<...>
return `${tasks.length} Tasks have been added from the template`;
You can also stop Button execution at any time by throwing an error:
if (!project.template) {
throw new Error("Please specify the template");
}
The user who clicked the Button will see this error message and will have a chance to make things right:
Activity log
The Activity log for each automation is the place to look to see when an automation has been executed and what happened.
Debugging
When running a script from a button press, if everything goes OK, there will be a pop-up message to let you know: "Script button is completed".
Sometimes, things might not always go as planned. It can be useful to add steps to the script that report relevant information to the browser console, e.g. console.log(args.currentEntities[0]);
It varies from browser to browser; in the case of Chrome, the browser console can be opened with Cmd + Shift + J.
Fibery service workspace functions
The following functions are available in scripting for the fibery service:
Function (arguments) | Returned data type |
getEntityById(type: string, id: string, fields: string[])
| object |
getEntitiesByIds(type: string, ids: string[], fields: string[])
| object array |
createEntity(type: string, values: object)
| object |
createEntityBatch(type: string, entities: object[])
| object[] |
updateEntity(type: string, id: string, values: object)
| object |
updateEntityBatch(type: string, entities: object[])
| object[] |
addCollectionItem(type: string, id: string, field: string, itemId: string)
| - |
addCollectionItemBatch(type: string, field: string, args: {id: string, itemId: string}[])
| - |
removeCollectionItem(type: string, id: string, field: string, itemId: string)
| - |
removeCollectionItemBatch(type: string, field: string, args: {id: string, itemId: string}[])
| - |
deleteEntity(type: string, id: string)
| - |
deleteEntityBatch(type: string, ids: string[])
| - |
setState(type: string, id: string, state: string)
| - |
setStateToFinal(type: string, id: string)
| - |
assignUser(type: string, id: string, userId: string)
| - |
unassignUser(type: string, id: string, userId: string)
| - |
getDocumentContent(secret: string, format: string)
| string |
setDocumentContent(secret: string, content: string, format: string)
| - |
appendDocumentContent(secret: string, content: string, format: string)
| - |
addComment(type: string, id: string, comment: string, authorId: string, format: string)
| object |
addFileFromUrl(url: string, fileName: string, type: string, field: string, id: string, headers: object)
| object |
executeAction(action: string, type: string, args: [object])
| object |
executeSingleCommand(command: FiberyCommand)
| any* |
graphql(spacename: string, command: string)
| any** |
getSchema()
| any*** |
* the executeSingleCommand function allows a script to run any Fibery API command. This gives tremendous flexibility, but requires a bit of experience with the low-level Fibery API that is beyond the scope of this article.
** the graphql function allows a script to execute a GraphQL command within the script. The usage of GraphQL is explained in more detail here: How to use Graphql API and IDE .
*** the getSchema function will return a complete, structured description of all space/database information.
Function arguments
The type argument is the name of the database, e.g. "Task".
If there is more than one database with the same name, you should prefix with the workspace name, e.g. "Project management/Task"
The id / itemId is the UUID of the entity, e.g. "fe1db100-3779-11e9-9162-04d77e8d50cb"
field and fields are the name(s) of the entity's fields, as a string or an array of strings, e.g. "Creation date" or ["Name","Assignees"]
values is a object containing one or more field name/value pairs, e.g.
{
"Name" : "My entity",
"Effort" : 10
}
state is the name of a workflow state, as a string, e.g. "In Progress"
secret is a UUID string that represents a collaborative document, e.g. "20f9b920-9752-11e9-81b9-4363f716f666". It is the value returned when reading a rich-text field and the value used to access/manipulate that rich-text field's contents.
userId and authorId are UUIDs for Fibery users in the workspace.
Note: the button presser's Id is accessible as args.currentUser['Id']
Http service functions
The following functions are available in scripting for the http service:
Function (arguments) | Returned data type |
getAsync(url: string, options?: { headers?: { [key: string]: string } })
| any |
patchAsync(url: string, options?: { body?: any, headers?: { [key: string]: string } })
| any |
postAsync(url: string, options?: { body?: any, headers?: { [key: string]: string } })
| any |
putAsync(url: string, options?: { body?: any, headers?: { [key: string]: string } })
| any |
deleteAsync(url: string, options?: { body?: any, headers?: { [key: string]: string } })
| any |
These functions represent standard http request methods.
Utils service functions
The following functions are available in scripting for the utils service.
Function (arguments) | Returned data type |
getEntityUrl(type: string, publicId: string)
| string |
getFileUrl(fileSecret: string)
| string |
uuid()
| string |
toBase64(str: string)
| string |
As the name suggests, getEntityURL allows you to generate a URL (entity view) for the selected entity.
getFileUrl allows you to determine the correct download URL for a given file, based on it's secret. The secret is available in the entity's object data (via the 'files' field).
uuid generates a string which can be used when creating a new entity, if for example, you need to refer to that entity before the async createEntity function has completed.
toBase64 generates a base-64 encoded string from the input string. This can be useful when executing http methods which require basic authentication.
Example
Here is an example of what you can use scripting to achieve:
Suppose you want to assign yourself to a number of tasks (which may or may not already have other users assigned). You might also want to remove yourself from a bunch of tasks.
Of course, you could manually open each task and add/remove your name to/from the list of users, but with a button that calls a script action, you can automate this process:
Here is the script:
const fibery = context.getService('fibery');
// do this for all tasks
for (const entity of args.currentEntities) {
// make sure you have the information from the Assignees field
const entityWithAssignees = await fibery.getEntityById(entity.type, entity.id, ['Assignees']);
// extract the IDs of all users currently assigned
const assigneeIds = entityWithAssignees['Assignees'].map(({ id }) => id);
// get the ID of the user who pressed the button
const userId = args.currentUser['id'];
// if the user is already assigned...
if (assigneeIds.includes(userId)) {
// ... then remove them
await fibery.removeCollectionItem(entity.type, entity.id, 'Assignees',userId);
}
else {
// otherwise, add them
await fibery.addCollectionItem(entity.type, entity.id, 'Assignees', userId);
}
}
FAQ
Is it possible to use an external script library in scripting automation?
Unfortunately, no.
Is there a utility I can use to decompress a zip file directly from a script automation?
I'm afraid the answer is "no" and we won't allow this. Compressing/decompressing are cpu-heavy operations, and our scripts are not designed for that.