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:
With the Task Channel Definition API you can also add custom channels and override the behavior of existing ones.
To add a custom channel, you need to make changes in the following places:
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:
Predefined Task Channels definitions are available via Twilio.Flex.DefaultTaskChannels
objects for reference. Channels that are defined by default:
Twilio.Flex.DefaultTaskChannels.Call
Twilio.Flex.DefaultTaskChannels.Chat
Twilio.Flex.DefaultTaskChannels.ChatSms
Twilio.Flex.DefaultTaskChannels.ChatMessenger
Twilio.Flex.DefaultTaskChannels.ChatWhatsApp
Twilio.Flex.DefaultTaskChannels.Default
It is not recommended to change Twilio.Flex.DefaultTaskChannels
at runtime. You should create your own definition and register it instead.
Predefined Task Channels definitions are available via Twilio.Flex.DefaultTaskChannels and they can be altered with custom logic when required.
The example below demostrates how you can define your own custom icon for browser notification of an IncomingTask
with channel type Chat
_14const originalChatNotifications = Flex.DefaultTaskChannels.Chat.notifications.override.IncomingTask;_14Flex.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};
The example below demostrates how you can define your own custom icon for browser notification of an IncomingTask
with channel type Voice
_10const overrides = Flex.DefaultTaskChannels.Call.notifications.override.IncomingTask;_10Flex.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:
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:
_10Flex.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)
_10Flex.DefaultTaskChannels.createCallTaskChannel(name: string, isApplicable: TaskChannelApplicableCb): TaskChannelDefinition
Generic channel creation with default templates:
_10Flex.DefaultTaskChannels.createDefaultTaskChannel(name: string, isApplicable: TaskChannelApplicableCb,_10 icon: string | React.ReactNode = "GenericTask", iconActive: string | React.ReactNode = "GenericTaskBold", color: string = defaultChannelColors.custom): TaskChannelDefinition
To register a task channel definition use:
_10Flex.TaskChannels.register(definition: TaskChannelDefinition, mergeWithDefaultChannel = true);
You must register your channel definitions before Flex finishes initializing.
For example:
_10const myOwnChatChannel = Flex.DefaultTaskChannels.createChatTaskChannel("myChat",_10 (task) => task.taskChannelUniqueName === "chat" && task.attributes.somethingSpecial === "myCustom");_10// can modify myOwnChatChannel here_10_10Flex.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
_160export 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_160export type TaskCallbackType<T> = (_160 task: ITask,_160 componentType: React.ComponentType,_160 ...args: Array<any>_160) => T;_160export type TaskStatusBasedTypeBase<T> = {_160 Reserved?: T;_160 Assigned?: T;_160 Wrapping?: T;_160 Completed?: T;_160 Canceled?: T;_160 Pending?: T;_160};_160export type TaskStatusBasedType<T = string> =_160 | T_160 | TaskCallbackType<T>_160 | TaskStatusBasedTypeBase<T>;_160export type TaskChannelApplicableCb = (task: ITask) => boolean;_160_160export type TaskChannelComponentRegistration = {_160 target: keyof FlexComponents;_160 component: React.ReactChild;_160 options?: ContentFragmentProps;_160};_160_160export 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 */_160export 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
_10MyCallChannel.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)
_10const MyComponent = <div key="X">My Call Task Info Panel</div>;_10MyCallChannel.replacedComponents = [_10 { component: MyComponent, target: "TaskInfoPanel" }_10];
Replacing a component conditionally
_10MyCallChannel.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):
_10myOwnChatChannel.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")
_10Flex.DefaultTaskChannels.Call.removedComponents = [{_10 target: "TaskCanvasHeader",_10 key: "actions",_10 options: {_10 if: (props) => props.task.status === "wrapping"_10 }_10}];