Resources
The resource fields on the FunctionContext — user, company, agent, asset — and what's available on each.
The FunctionContext exposes several resource properties tailored to the request. IXON Cloud has already verified the user's credentials and ensured that the correct resources are set on the context — your function does not need to verify them.
A Cloud Function can be called from a UI Component placed on Main Pages, Device Pages, Cards, and Reports. Which resources are populated depends on the page.
Available resources
| Property | Description | Available fields | Available from |
|---|---|---|---|
user | The user logged in to IXON Cloud that is calling the Cloud Function. | public_idnamecustom_properties | Main page · Device Page · Report page · Card |
company | The company the user has open in the Portal. | public_idnamecustom_propertiespermissions | Main page · Device Page · Report page · Card |
agent | Optional. Set when the Cloud Function is called from a device page with an agent, or a device page with an asset that has a linked agent. | public_idnamecustom_propertiespermissions | Device Page · Report page · Card |
asset | Optional. Set when the Cloud Function is called from an asset page with an asset. | public_idnamecustom_propertiespermissions | Device Page · Card |
agent_or_asset | Optional. Whichever of agent / asset applies. When both are set, the asset is preferred. | public_idnamecustom_propertiespermissions | Device Page · Card |
Reading common fields
Below you can see an example of how to retrieve name or public_id of a user or company:
@FunctionContext.expose
def caller(context: FunctionContext) -> dict:
return {
'user_id': context.user.public_id if context.user else None,
'user_name': context.user.name if context.user else None,
'company_id': context.company.public_id if context.company else None,
}Reading custom properties
custom_properties is a dict-like field your administrators can populate on agents, assets, users, and companies — for example, to attach a customer ID or a region code.
@FunctionContext.expose
def get_region(context: FunctionContext) -> dict:
if not context.agent:
return {'region': None}
return {'region': context.agent.custom_properties.get('region')}
Custom properties are configured in the IXON PortalCustom properties are managed through the IXON Portal's Admin UI. Whether they're set on a given agent, asset, or user depends on your company's configuration.
Permissions
company, agent, asset, and agent_or_asset expose a permissions field that calculates which permissions a user has on those resources. You can use these to gate behaviours in your function.
In this function, the user can modify the name of the agent in a Device Page, provided that they have the MANAGE_AGENT permission:
@FunctionContext.expose
def edit_agent_name(context: FunctionContext, new_name: str) -> dict:
# Must be called in an agent context
if not context.agent:
return {'success': False, 'error': 'No agent in context'}
# Caller must have the MANAGE_AGENT permission on this agent
if 'MANAGE_AGENT' not in context.agent.permissions:
return {'success': False, 'error': 'Missing MANAGE_AGENT permission'}
# Update the agent's name via the API client
context.api_client.patch('Agent', {
'publicId': context.agent.public_id,
'name': new_name,
})
return {'success': True, 'name': new_name}
Tip: How can I find a full list of permissions?When writing code, you will need to retrieve the
publicId(the name, such asMANAGE_AGENT) of a permission to be able to use it. You can call PermissionList to get a full list of permissions.
Choosing between agent, asset, and agent_or_asset
agent, asset, and agent_or_assetWhen your function works with whatever device-like resource the user is currently viewing — and you don't care whether it's modeled as an agent or as an asset — use context.agent_or_asset. When the distinction matters (for example, you only want to act on raw agents), branch on context.agent and context.asset directly.
@FunctionContext.expose
def device_name(context: FunctionContext) -> dict:
target = context.agent_or_asset
return {'name': target.name if target else None}