Timill Platform Documentation

Scripting API Reference

Complete JavaScript (Goja ES5.1) scripting API reference for backend scripts, widget scripts, and chart scripts.

Complete JavaScript (Goja ES5.1) scripting API for backend scripts, widget scripts, and chart scripts.

Global Variables#

VariableTypeDescription
userIdstringCurrent user ID
groupIdstringGroup ID (if group-scoped)
instanceIdstringInstance ID
scriptIdstringCurrent script ID
scriptTypestring"backend", "widget", or "chart"
itemIdstringItem ID (if item-scoped)
isGroupScopedbooleanTrue if script runs in a group context
isInstanceScopedbooleanTrue if script runs at instance level
isItemScopedbooleanTrue if script runs on a specific item

user Object#

Available in all script types. Backend scripts get read-write access.

Read Methods (all scripts)#

MethodReturnsDescription
user.ID()stringUnique user identifier
user.Name()stringDisplay name
user.Email()stringEmail address
user.FirstName()stringFirst name (extracted from Name)
user.LastName()stringLast name (extracted from Name)
user.ProfilePicture()stringAvatar URL
user.Locale()stringLanguage preference
user.IsActive()booleanWhether account is active

Write Methods (backend scripts only)#

MethodReturnsDescription
user.Save(){success, error?}Save changes to database
user.UpdateProfile(data){success, error?}Update name/language. data: {name?: string, language?: string}

group Object#

Available when isGroupScoped is true. Backend scripts get read-write access.

Read Methods (all scripts)#

MethodReturnsDescription
group.ID()stringGroup identifier
group.Name()stringGroup name
group.Description()stringGroup description
group.Icon()stringGroup icon
group.Color()stringGroup color
group.QueryItems(queryString)Item[]Execute a query. Example: group.QueryItems("type:task status:open")
group.GetMemberById(userID)User or nullGet a member by user ID
group.GetMembers()User[]All group members
group.GetItemTypes()object[]Item type definitions
group.GetStatuses(itemTypeID)object[]Statuses for an item type
group.GetFields(itemTypeID)object[]All fields (default + custom) for an item type
group.GetCustomFields(itemTypeID)object[]Custom fields only
group.GetDefaultFields(itemTypeID)object[]Default fields only

Write Methods (backend scripts only)#

MethodReturnsDescription
group.Save(){success, error?}Save group changes
group.CreateItem(itemTypeID, data){success, itemId?, error?}Create a new item. data: {title, description, status, assignee, dueDate, customFields}
group.DeleteItem(itemID){success, error?}Delete an item

item Object#

Available when isItemScoped is true. Backend scripts get read-write access.

Read Methods (all scripts)#

MethodReturnsDescription
item.ID()stringItem identifier
item.Title()stringItem title
item.Description()stringItem description
item.Status()string or nullCurrent status ID
item.ItemType()stringItem type ID
item.GroupID()stringParent group ID
item.IDInGroup()numberSequential ID within group
item.CreatedBy()stringCreator user ID
item.AssignedTo()stringAssignee user ID
item.IsCompleted()booleanWhether item is completed
item.CreatedAt()stringISO 8601 creation timestamp
item.UpdatedAt()stringISO 8601 last update timestamp
item.DueDate()string or nullISO 8601 due date
item.CompletedAt()string or nullISO 8601 completion timestamp
item.GetField(fieldID)anyGet any field value (default or custom)
item.RenderField(fieldID)stringGet rendered HTML for a field

Write Methods (backend scripts only)#

MethodReturnsDescription
item.Save(){success, error?}Save all changes
item.Delete(){success, error?}Delete the item
item.SetField(fieldID, value){success, error?}Set any field value
item.SetTitle(title){success, error?}Set title
item.SetDescription(desc){success, error?}Set description
item.SetStatus(statusID){success, error?}Set status
item.SetAssignedTo(userID){success, error?}Set assignee (empty string to unassign)
item.SetDueDate(isoDate){success, error?}Set due date (ISO 8601, empty to clear)
item.AddComment(text){success, error?}Add a comment

api Object#

Data transformation helpers, available in all script types.

MethodReturnsDescription
api.groupBy(items, fieldName)objectGroup items by a field value. Returns {groupValue: items[]}
api.aggregate(items, fieldName, fn)numberAggregate field values. fn: "sum", "avg", "min", "max", "count"
api.filterItems(items, predicate)any[]Filter items using a predicate function

Example#

var tasks = group.QueryItems("type:task");
var byStatus = api.groupBy(tasks, "status");
var totalEstimate = api.aggregate(tasks, "estimate", "sum");
var overdue = api.filterItems(tasks, function(t) {
    return t.DueDate() !== null && new Date(t.DueDate()) < new Date();
});

echarts Object#

Chart configuration helpers for widget/chart scripts.

MethodReturnsDescription
echarts.createPieChart(data, options?)objectCreate a pie chart configuration
echarts.createBarChart(data, options?)objectCreate a bar chart configuration
echarts.createLineChart(data, options?)objectCreate a line chart configuration
echarts.createScatterChart(data, options?)objectCreate a scatter chart configuration

fetch(url, options?) (Backend Scripts Only)#

Make HTTP requests to external URLs. Each call counts against the API call limit.

Parameters#

ParameterTypeDescription
urlstringURL to fetch (http/https only)
options.methodstringHTTP method: "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD". Default: "GET"
options.headersobjectRequest headers as key-value pairs
options.bodystring or objectRequest body. Objects are auto-serialized to JSON

Response#

PropertyTypeDescription
statusnumberHTTP status code
statusTextstringHTTP status text
headersobjectResponse headers (lowercase keys)
bodystringResponse body as string
okbooleanTrue if status is 2xx
json()anyParse body as JSON

Security#

  • Requests to private/loopback IPs are blocked (SSRF protection)
  • Only http:// and https:// schemes allowed
  • Max response body: 1MB
  • Max 5 redirects
  • Respects script timeout

Example#

var apiKey = secrets.get("EXTERNAL_API_KEY");
var resp = fetch("https://api.example.com/data", {
    method: "POST",
    headers: {
        "Authorization": "Bearer " + apiKey,
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ query: "test" })
});

if (resp.ok) {
    var data = resp.json();
    log("Got " + data.results.length + " results");
} else {
    log("Request failed: " + resp.status);
}

secrets.get(key) (Backend Scripts Only)#

Retrieve encrypted secrets by key. Secrets are resolved with group-then-instance fallback.

ParameterTypeDescription
keystringSecret key (e.g., "API_KEY", "WEBHOOK_TOKEN")

Returns: string (decrypted value) or null if not found.

Security#

  • You must specify the exact key - no list() or getAll() is available
  • Secret values are never logged by the system
  • If you pass a secret to log() or fetch(), that is your responsibility
  • Each call counts against the API call limit

Example#

var token = secrets.get("SLACK_WEBHOOK_TOKEN");
if (token) {
    fetch("https://hooks.slack.com/services/...", {
        method: "POST",
        body: JSON.stringify({ text: "Item created: " + item.Title() })
    });
}

log(...args) / console.log(...args)#

Log messages during script execution. Messages appear in the execution log.

log("Processing", items.length, "items");
console.log("User:", user.Name());

Resource Limits#

LimitBackend ScriptsWidget/Chart Scripts
Timeout30 seconds10 seconds
Max API calls10050
Max memory50 MB25 MB
Max fetch response1 MBN/A (no fetch)

API calls include: QueryItems, GetMemberById, GetMembers, fetch, secrets.get, and other data-fetching methods.


Trigger Types#

Backend scripts can be triggered in four ways:

TypeDescription
ManualExecute on demand from the admin UI
ScheduleRun on a cron schedule (e.g., 0 9 * * * for daily at 9am)
EventFire when specific events occur (item created, status changed, etc.) with optional field conditions
Save HookRun after every item save, with optional field conditions

Available Events#

CREATE, UPDATE, DELETE, STATUS_CHANGE, FIELD_UPDATE, ASSIGN, COMMENT_CREATE


Query Syntax#

The Timill query syntax supports filtering items by any field:

// Simple query
group.QueryItems("type:task")

// Multiple conditions
group.QueryItems("type:task status:open")

// Date range
group.QueryItems("type:task dueDate:>=2024-01-01")

// Complex query with parentheses
group.QueryItems("type:task (status:open OR status:in-progress)")

Supported Operators#

OperatorDescriptionExample
:Equals (shorthand)type:task
=Equalsstatus = 'open'
!=Not equalsstatus != 'closed'
>=Greater than or equaldueDate >= 2024-01-01
<=Less than or equaldueDate <= 2024-12-31
>Greater thancreatedDate > 2024-01-01
<Less thancreatedDate < 2024-12-31
INIn liststatus IN ('open', 'in-progress')

Supported Fields#

FieldTypeExample
typestringtype:task
statusstringstatus:open
assigneestring (user ID)assignee:userId123
authorstring (user ID)author:userId123
dueDatedatedueDate:>=2024-01-01
createdDatedatecreatedDate:>2024-01-01
prioritystringpriority:high
Custom fieldsvariesUse field ID

See also: