Skip to main content

JavaScript Environment

Functions execute JavaScript in serverless containers. This page covers the execution environment, available objects, and best practices.

Available Objects

Core Objects

ObjectDescriptionAvailable In
itemThe current record being created, updated, or deletedTrigger functions
meCurrent authenticated userAll functions (when authenticated)
apiInformation about the APIAll functions
secretsConfigured secrets (key/value pairs)All functions
reqIncoming HTTP request detailsTrigger & Invocable functions
resResponse object for custom responsesInvocable functions

The item Object

For trigger functions, item contains the record being processed:

// Access item properties
console.log('Processing:', item.name);
console.log('Item ID:', item.id);

// Modify the item (for validation/transformation)
item.slug = item.title.toLowerCase().replace(/\s+/g, '-');
item.updatedAt = new Date().toISOString();

The me Object

Information about the current user:

PropertyDescription
idUser ID (GUID)
emailUser email
nameUser display name
rolesArray of role IDs/names
console.log('Request by:', me.name);
console.log('User email:', me.email);

The api Object

Information about the API:

PropertyDescription
idAPI ID (GUID)
nameAPI name
tenantIdTenant ID
apiSettingsArray of settings [{key, value}]

The req Object

Request details (trigger and invocable functions):

PropertyDescription
methodHTTP method (GET, POST, PUT, PATCH, DELETE)
headersRequest headers (filtered for security)
queryQuery parameters
bodyRaw body string
bodyJsonParsed JSON body
// Access request data
const method = req.method;
const contentType = req.headers['content-type'];
const page = req.query.page || 1;
const payload = req.bodyJson;

The res Object (Invocable Only)

Set custom responses in invocable functions:

PropertyDescription
statusHTTP status code (default: 200)
headersResponse headers
bodyJsonJSON response body
bodyPlain text response body
// Return custom response
res = {
status: 201,
headers: { 'X-Custom-Header': 'value' },
bodyJson: { success: true, id: newItem.id }
};

Real-Time Channels

Functions can manage gated channels (channels with : in the name) using the built-in HTTP methods:

// Add client to a gated channel with send permission
await post('_rt/join', {
connectionId: req.connectionId,
channel: 'game:room-123',
readOnly: false // Client can send messages
});

// Add client as read-only listener
await post('_rt/join', {
connectionId: req.connectionId,
channel: 'announcements:system',
readOnly: true // Client can only receive
});

// Send message to any channel
await post('_rt/send', {
channel: 'announcements:system',
body: { type: 'notification', text: 'New update available' }
});

Gated channels (with :) can only be joined/messaged by functions. The readOnly parameter controls whether the client can send messages after joining.

See Real Time for channel types and client-side usage.

Built-in HTTP Methods

Functions have built-in async methods for API calls:

MethodDescription
get(url)GET request to API endpoint
post(url, data)POST request
put(url, data)PUT request
patch(url, data)PATCH request
del(url)DELETE request
// Get all active products
const products = await get('products?filter=status eq "active"');

// Create a new order
const order = await post('orders', {
customerId: item.customerId,
total: item.total
});

// Update a record
await patch(`customers/${item.customerId}`, {
lastOrderDate: new Date().toISOString()
});

// Delete a record
await del(`temp-items/${item.id}`);

These methods automatically include authentication and use relative URLs within your API.

External HTTP Requests (fetch)

Use fetch for external API calls:

const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Authorization': `Bearer ${secrets.EXTERNAL_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'value' })
});

const data = await response.json();
Paid Feature

The fetch function for external HTTP requests is only available on paid tiers. Free tier APIs cannot make external HTTP calls.

File Operations

MethodDescription
getFileBase64(url)Get file as Base64 string
postFileBase64(url, fileName, content, mimeType)Upload Base64 file
// Download a file
const fileContent = await getFileBase64(`products/${item.id}/image`);

// Upload a file
await postFileBase64(
`products/${item.id}/thumbnail`,
'thumbnail.jpg',
resizedImageBase64,
'image/jpeg'
);

Secrets

Secrets are securely stored credentials injected into your function.

Configuring Secrets

  1. Create secrets in SettingsSecrets
  2. Select which secrets to inject when configuring your function
  3. Access them via the secrets object

Using Secrets

// Access secrets
const apiKey = secrets.STRIPE_API_KEY;
const webhookSecret = secrets.WEBHOOK_SECRET;

// Use in external calls
const response = await fetch('https://api.stripe.com/v1/charges', {
headers: {
'Authorization': `Bearer ${secrets.STRIPE_SECRET_KEY}`
}
});
warning

Never log secrets or include them in error messages.

Logging

FunctionSeverity
console.log(message) or log(message)Info
logWarn(message)Warning
logError(message)Error
log('Processing started');
console.log('Item:', item.name);
logWarn('Customer has pending balance');
logError('Failed to sync with external service');

Logs include timestamps and milliseconds from execution start.

Context by Function Type

Trigger Functions

// Available: item, me, api, secrets, req
console.log('Processing item:', item.id);
console.log('Triggered by:', me.name);
console.log('Method:', req.method);

// Modify item before save
item.updatedBy = me.id;

Timer Functions

// Available: api, me (service account), secrets
// No item or request context
console.log('Running scheduled task for API:', api.name);

const items = await get('orders?filter=status eq "pending"');
// Process items...

Invocable Functions

// Available: req, res, me, api, secrets
const input = req.bodyJson;
const result = processData(input);

res = {
status: 200,
bodyJson: { success: true, result }
};

Error Handling

Throwing Errors

Throw errors to halt execution:

if (!item.email) {
throw new Error('Email is required');
}

Try-Catch

Handle errors gracefully:

try {
const external = await fetch(externalUrl);
if (!external.ok) {
throw new Error(`External API error: ${external.status}`);
}
} catch (error) {
logError('External call failed: ' + error.message);
// Handle gracefully or re-throw
}

Filtered Headers

For security, these headers are removed from req.headers:

  • authorization, cookie, host
  • x-forwarded-*, x-azure-*, x-arr-*
  • Other infrastructure headers

Best Practices

  • Use item not body — For trigger functions, the record is in item
  • Use built-in methodsget(), post(), etc. handle auth automatically
  • Validate inputs early — Check required fields at the start
  • Handle errors gracefully — Use try-catch for external calls
  • Log important operations — Aids debugging and auditing
  • Keep secrets secure — Never expose in logs or responses
  • Set appropriate timeouts — Prevent long-running functions