Channel Developers

thumbnail

Function Registration

A Function is a typed RPC that Channel or another app sends to an app server. The request method is the full Function name and params is its input. Register app-owned Functions as standalone names such as orders.get; standard Extension Functions combine an Extension name with a relative name.

Incoming calls use this JSON-RPC-like envelope:

JSON
  • method: the exact full Function name exposed by discovery

  • params: untrusted input validated by a schema

  • context: surface-dependent caller, Channel, language, auth, and config data

  • systemVersion: identifies the system contract between AppStore and the app server

Public JSON fields use camelCase in both TypeScript and Go. Trust context only after the raw-body x-signature verification succeeds.

Return result for success and a structured error for an expected failure.

JSON
JSON

Common codes are 1 for unprocessable input, 2 for bad request, 3 for not found, 4 for unauthorized, -32601 for method not found, and -32603 for internal error. Keep type stable for programmatic handling and never put credentials or customer data in errors. The shared protocol defines the complete envelope.

When a call cannot complete without another user choice, return NeedsUserInputResultSchema as a successful result. Include every currently required question in one result. The next call goes to the same Function with the original continuationToken and only the answers the user supplied.

TypeScript

The continuationToken is opaque and must not be shown to the user. Give it an expiry and sign it with bindings for the app, Function, Channel, and caller. A resumed call must repeat the normal input validation, authorization, and execution-policy checks. Never store credentials or raw customer data in the token.

Register the Function root in the developer portal. AppStore calls the route with a system version.

The SDK handles routing, dispatch, schema validation, error envelopes, and extension.core.function.getFunctions discovery. Do not build a second raw JSON-RPC router or a manual discovery response. Verify the exact request bytes with SignatureGuard and rawBody: true in TypeScript, or server.WithSignature in Go.

The route suffix v1 and request systemVersion carry the same AppStore system contract. The current TypeScript and Go SDKs do not maintain separate handler sets for the URL :version or the request systemVersion; after signature verification, dispatch is based on the exact method. /functions/v1 is therefore not a developer-owned API version namespace.

When an app-owned standalone Function needs a breaking change while preserving existing callers, keep orders.get and register the new contract under a distinct name such as orders.getV2. Update metadata and callers to reference the new name explicitly when they are ready. Do not use systemVersion: "v2" or /functions/v2 for this purpose. Standard Extension Functions must keep their official Function names and follow the new system contract published by AppStore and the SDK.

Use the decorator API with Zod schemas.

TypeScript

On a provider with @Extension({ name: "command" }), @Func("metadata.getCommands") becomes extension.command.metadata.getCommands. Do not create a fake Extension for a standalone Function. Add every decorated class to the NestJS module's providers so discovery can find it.

Go uses builders and generic handlers.

Go

appsdk.Register and appsdk.MustRegister derive schemas from Go structs and call Validate() error when the input implements it. Use appsdk.InputSchema, appsdk.OutputSchema, or proto helpers for an explicit contract.

A Native Function reverses the direction: the app asks Channel to perform an operation. Obtain an app or channel token from TokenManager and prefer a typed proxy or client. The current TypeScript NativeFunctionTypeMap and exported Go native.Client methods are the source of truth, not a static list copied into documentation.

Use the SDK app-function client when calling another app's registered Function or your own Function through AppStore.

TypeScript
Go

A valid access token does not replace business authorization. Recheck the relationship among the target app, installed Channel, caller, and requested resource in the handler. Read the TypeScript Native Function reference and Go Native Function reference for exact APIs.

Prefer a standard Extension helper that owns the SDK schemas and Function names. Go builder packages include extension/config, extension/oauth, extension/calendar, extension/command, extension/widget, extension/customtab, extension/hook, extension/polling, extension/store, extension/messaging, extension/alftask, and extension/wms. Isolate generic registration to standalone Functions without an SDK helper.

Continue with the Command guide, WAM guide, Extension guide, and production readiness guide.

This document is maintained with the Channel App SDK. Check the SDK README first for current packages and the complete reading order. The source of truth for this Document is the GitHub source.