Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Task Channel Definitions


Flex is a multichannel contact center. We support a number of channels out-of-the-box, and are constantly adding more. As of version 1.0 we support the following native channels:

  • Voice
  • SMS
  • WebChat with Media Attachments
  • Facebook Messenger
  • WhatsApp
  • RCS

With the Task Channel Definition API you can also add custom channels and override the behavior of existing ones.


Steps to add a custom channel

steps-to-add-a-custom-channel page anchor

To add a custom channel, you need to make changes in the following places:

  • Add a custom channel in TaskRouter
  • Trigger the custom channel to be routed to the agent
  • Define how the custom channel is rendered in the UI with Task Channel Definition API

Task Channel Definition API

task-channel-definition-api page anchor

All task channels that Flex UI handles are defined and registered by the Task Channels API. Flex registers its default Task Channel definitions (see below), but users and plugins can register their own. When task-based components are rendered, the first matching channel definition for a given task will be used. If there is more than one channel definition match for a task, then the most recently registered definition will be used. This allows you to register a more specific channel definition to override the behavior of a general one.

See below interface TaskChannelDefinition for what can be set up. All parameters are optional; the paramaters from the Default task channel definition will be used if not specified. The most important property of a task channel definition is the isApplicable callback function. The callback receives a task as an argument and must return boolean true if this definition can be used to handle the given task.

In a task channel definition you can specify:

  • callback to determine which tasks are applicable
  • strings (templates) to use in different Flex components based on task status
  • colors to be used in task list based on task status
  • icons to be shown in task list, tabs, and canvases based on task status
  • custom components to be added to task based components if channel is applicable
  • custom components to be replaced in task based components if channel is applicable

Predefined Task Channels definitions are available via Twilio.Flex.DefaultTaskChannels objects for reference. Channels that are defined by default:

  • Call - Twilio.Flex.DefaultTaskChannels.Call
  • Chat - Twilio.Flex.DefaultTaskChannels.Chat
  • Chat SMS - Twilio.Flex.DefaultTaskChannels.ChatSms
  • Chat Messenger - Twilio.Flex.DefaultTaskChannels.ChatMessenger
  • Chat WhatsApp - Twilio.Flex.DefaultTaskChannels.ChatWhatsApp
  • Default - Twilio.Flex.DefaultTaskChannels.Default
(warning)

Warning

It is not recommended to change Twilio.Flex.DefaultTaskChannels at runtime. You should create your own definition and register it instead.


Override Predefined Task Channels definitions Notifications

override-predefined-task-channels-definitions-notifications page anchor

Predefined Task Channels definitions are available via Twilio.Flex.DefaultTaskChannels and they can be altered with custom logic when required.


Override Default Chat Channel notifications

override-default-chat-channel-notifications page anchor

The example below demostrates how you can define your own custom icon for browser notification of an IncomingTask with channel type Chat


_14
const originalChatNotifications = Flex.DefaultTaskChannels.Chat.notifications.override.IncomingTask;
_14
Flex.DefaultTaskChannels.Chat.notifications.override.IncomingTask = {
_14
...originalChatNotifications,
_14
options: {
_14
...originalChatNotifications.options,
_14
browser: {
_14
...originalChatNotifications.options.browser,
_14
options: {
_14
...originalChatNotifications.options.browser.options,
_14
icon: “CUSTOM_ICON_URL”
_14
}
_14
}
_14
}
_14
};


Override Default Voice Channel notifications

override-default-voice-channel-notifications page anchor

The example below demostrates how you can define your own custom icon for browser notification of an IncomingTask with channel type Voice


_10
const overrides = Flex.DefaultTaskChannels.Call.notifications.override.IncomingTask;
_10
Flex.DefaultTaskChannels.Call.notifications.override.IncomingTask = (notification, cancel) => {
_10
overrides(notification, cancel);
_10
notification.options.browser.options.icon = “CUSTOM_ICON_URL”;
_10
};


Tasks can be rendered depending on which media type they support. We have helper functions to define custom channels that support the following media type:

  • Call - voice call based
  • Chat - messaging based like WebChat, SMS, Facebook Messenger, etc.
  • Generic - no media

Creating custom channel definitions with helper functions

creating-custom-channel-definitions-with-helper-functions page anchor

Flex has the following helper functions to create channel definitions with default values for chat, call, and generic.

Chat channel creation with default chat templates:


_10
Flex.DefaultTaskChannels.createChatTaskChannel(name: string, isApplicable: TaskChannelApplicableCb,
_10
icon: string | React.ReactNode = "Message", iconActive: string | React.ReactNode = "MessageBold", color: string = defaultChannelColors.chat): TaskChannelDefinition

Call channel creation with default templates:

Call channel definition uses callbacks to determine the icon and colors (based on call state and destination to render)


_10
Flex.DefaultTaskChannels.createCallTaskChannel(name: string, isApplicable: TaskChannelApplicableCb): TaskChannelDefinition

Generic channel creation with default templates:


_10
Flex.DefaultTaskChannels.createDefaultTaskChannel(name: string, isApplicable: TaskChannelApplicableCb,
_10
icon: string | React.ReactNode = "GenericTask", iconActive: string | React.ReactNode = "GenericTaskBold", color: string = defaultChannelColors.custom): TaskChannelDefinition


Registering custom channels

registering-custom-channels page anchor

To register a task channel definition use:


_10
Flex.TaskChannels.register(definition: TaskChannelDefinition, mergeWithDefaultChannel = true);

You must register your channel definitions before Flex finishes initializing.

For example:


_10
const myOwnChatChannel = Flex.DefaultTaskChannels.createChatTaskChannel("myChat",
_10
(task) => task.taskChannelUniqueName === "chat" && task.attributes.somethingSpecial === "myCustom");
_10
// can modify myOwnChatChannel here
_10
_10
Flex.TaskChannels.register(myOwnChatChannel);


  • Flex.TaskChannels.unregister(myOwnChatChannel); - to unregister previously registered channel
  • Flex.TaskChannels.getRegistered(); - to get all registered task channels
  • Flex.TaskChannels.getForTask(task: ITask); - to get a matching task channel definition for a task

Complete TaskChannelDefinition Interface

complete-taskchanneldefinition-interface page anchor

_160
export enum TaskChannelCapability {
_160
Info = "Info", // whether channel has info panel
_160
Call = "Call", // whether channel has call canvas capabilities
_160
Chat = "Chat", // whether channel has chat canvas capabilities
_160
Video = "Video", // whether channel has video calling capabilities
_160
Wrapup = "Wrapup" // whether channel needs to go to Wrapup state before can be completed
_160
}
_160
_160
export type TaskCallbackType<T> = (
_160
task: ITask,
_160
componentType: React.ComponentType,
_160
...args: Array<any>
_160
) => T;
_160
export type TaskStatusBasedTypeBase<T> = {
_160
Reserved?: T;
_160
Assigned?: T;
_160
Wrapping?: T;
_160
Completed?: T;
_160
Canceled?: T;
_160
Pending?: T;
_160
};
_160
export type TaskStatusBasedType<T = string> =
_160
| T
_160
| TaskCallbackType<T>
_160
| TaskStatusBasedTypeBase<T>;
_160
export type TaskChannelApplicableCb = (task: ITask) => boolean;
_160
_160
export type TaskChannelComponentRegistration = {
_160
target: keyof FlexComponents;
_160
component: React.ReactChild;
_160
options?: ContentFragmentProps;
_160
};
_160
_160
export type TaskChannelComponentRemoveRequest = {
_160
target: keyof FlexComponents;
_160
key: React.Key;
_160
options?: RemoveComponentCallOptions;
_160
};
_160
_160
/**
_160
* Defines a task channel
_160
*
_160
* @export
_160
* @interface TaskChannelDefinition
_160
*/
_160
export interface TaskChannelDefinition {
_160
// for internal usage, will be set to an array of callbacks to invoke to unregister custom components
_160
_registrationCallbacks?: Array<Function>;
_160
_160
name: string;
_160
_160
/**
_160
* Used in TaskList, TaskCard, Canvases
_160
*/
_160
colors?: {
_160
main?: TaskStatusBasedType<string>;
_160
};
_160
_160
/**
_160
* Returns whether this task channel is applicable for a given task.
_160
* @param task task instance to evaluate the channel for
_160
*/
_160
isApplicable: TaskChannelApplicableCb;
_160
_160
/**
_160
* Icons to render to the task channel
_160
*/
_160
icons?: {
_160
/**
_160
* List icon to be used in TaskList and TaskCardList
_160
*/
_160
list?: TaskStatusBasedType<string | React.ReactNode>;
_160
/**
_160
* Icon to be used in Tab headers if tab is not selected
_160
*/
_160
main?: TaskStatusBasedType<string | React.ReactNode>;
_160
/**
_160
* Icon to be used in Tab headers if tab is selected and in Task Canvases as the main icon
_160
*/
_160
active?: TaskStatusBasedType<string | React.ReactNode>;
_160
};
_160
_160
/**
_160
* Templates for components
_160
*/
_160
templates?: {
_160
IncomingTaskCanvas?: {
_160
firstLine?: TaskStatusBasedType<string>;
_160
secondLine?: TaskStatusBasedType<string>;
_160
};
_160
CallCanvas?: {
_160
firstLine?: TaskStatusBasedType<string>;
_160
secondLine?: TaskStatusBasedType<string>;
_160
};
_160
TaskListItem?: {
_160
firstLine?: TaskStatusBasedType<string>;
_160
secondLine?: TaskStatusBasedType<string>;
_160
extraInfo?: TaskStatusBasedType<string>;
_160
};
_160
TaskCanvasHeader?: {
_160
title?: TaskStatusBasedType<string>;
_160
endButton?: TaskStatusBasedType<string>;
_160
};
_160
TaskCard?: {
_160
firstLine?: TaskStatusBasedType<string>;
_160
secondLine?: TaskStatusBasedType<string>;
_160
};
_160
TaskInfoPanel?: {
_160
content: TaskStatusBasedType<string>;
_160
};
_160
Supervisor?: {
_160
TaskCanvasHeader?: {
_160
title?: TaskStatusBasedType<string>;
_160
endButton?: TaskStatusBasedType<string>;
_160
};
_160
TaskInfoPanel?: {
_160
content: TaskStatusBasedType<string>;
_160
};
_160
TaskOverviewCanvas: {
_160
firstLine?: TaskStatusBasedType<string>;
_160
secondLine?: TaskStatusBasedType<string>;
_160
};
_160
};
_160
};
_160
_160
/**
_160
* Set of capabilities, used to render Tabs
_160
*/
_160
capabilities: Set<TaskChannelCapability>;
_160
_160
/**
_160
* Character limit of a message.
_160
*/
_160
charLimit: number;
_160
_160
/**
_160
* Custom components to be added for this task channel. E.g. custom Tabs.
_160
* Supports only components that have a static "Content" property
_160
*/
_160
addedComponents?: Array<TaskChannelComponentRegistration>;
_160
_160
/**
_160
* Custom components to be replaced for this task channel.
_160
* Supports only components that have a static "Content" property
_160
*/
_160
replacedComponents?: Array<TaskChannelComponentRegistration>;
_160
_160
/**
_160
* Custom components to be removed for this task channel
_160
*/
_160
removedComponents?: Array<TaskChannelComponentRemoveRequest>;
_160
_160
/**
_160
* Custom component props to be passed in if we have a matching task channel.
_160
* Works only for task based components.
_160
*/
_160
// componentProps?: {
_160
// [K in keyof FlexComponents]?: any;
_160
// };
_160
}


Adding a Tab to custom channel


_10
MyCallChannel.addedComponents = [
_10
{
_10
target: "TaskCanvasTabs",
_10
component: <MyTab
_10
key="myTab"
_10
icon={<img src="https://someimage.png" />}
_10
iconActive={<img src="someimage.png" />}
_10
/>
_10
}
_10
];

Replacing a component (e.g. TaskInfoPanel or MessagingCanvas)


_10
const MyComponent = <div key="X">My Call Task Info Panel</div>;
_10
MyCallChannel.replacedComponents = [
_10
{ component: MyComponent, target: "TaskInfoPanel" }
_10
];

Replacing a component conditionally


_10
MyCallChannel.replacedComponents = [
_10
{ component: MyComponent, target: "MessagingCanvas", options:
_10
{ if: (props) => props.task.status === "wrapping" }
_10
}
_10
];

Change strings based on task types (e.g., for end task button in the header):


_10
myOwnChatChannel.templates.TaskCanvasHeader.endButton = {
_10
Assigned: "End Task",
_10
Reserved: undefined,
_10
Wrapping: "Wrap up",
_10
Completed: "Template1",
_10
Canceled: "Template2",
_10
Pending: "Template3"
_10
};

Removing a component conditionally (e.g., remove action button from TaskListItem if task is in state "wrapping")


_10
Flex.DefaultTaskChannels.Call.removedComponents = [{
_10
target: "TaskCanvasHeader",
_10
key: "actions",
_10
options: {
_10
if: (props) => props.task.status === "wrapping"
_10
}
_10
}];


Rate this page: