Skip to content

Instantly share code, notes, and snippets.

@chase2981
Last active February 19, 2021 17:42
Show Gist options
  • Save chase2981/9d38a41b215dbdb8262fc1c198d4a815 to your computer and use it in GitHub Desktop.
Save chase2981/9d38a41b215dbdb8262fc1c198d4a815 to your computer and use it in GitHub Desktop.
// task
// snake case
var taskJson = {
// this shows up in flex on the task as the primary text
"name": "(435) 999-5175",
// this is needed cuz there's no good way to access it on a task basis within the workflow expressions
"channelType": "chat",
// differentiates between different task queues based on acceptable response times
"type": "short-lived",
// this means it's an important task
"vip": true,
"ignore_agents": [],
// language spoken on call/chat/email
"spoken_language": "spanish",
"rd": {
// contactCenter -- we might not need this tbh -- especially if we do different flex projects or even different workspaces or workflows per contact center
"contact_center_id":1,
// spoken language
"worker_spoken_language_required": "spanish",
// alt method
"skills_needed": ["spanish_speaking"],
// startDate
"start_date": "2021-02-04T02:35:14.466Z",
// clientId
"client_id": 1,
// communityGroupId if we have it
// optional
"community_group_id": 2,
// adSourceId here, then we'll put the adSourceName in the "conversations" sub-object
// optional
"ad_source_id": 124,
// this should factor in a bunch of different things including call-cap overages and new beta clients
// 10 is highest priority
// 0 is lowest priority
// "community_group_priority": 10, // update, all task ordering must be done using task.priority
// this should factor in whether or not the worker is in training and low experience levels should not take high priority calls
// 10 is highest experience
// 0 is lowest experience
"worker_experience_required": 7,
// parent task when transferring a task or when creating one outbound task from an inbound follow-up task
// optional
"parent_task_sid": "XXSF...",
// this lets us know to show the follow up component on the frontend on the child task
// optional -- same as above
"parent_task_channel_unique_name": "follow-up",
// this will be used to trigger search on the frontend if email
// optional
"email_message_id": 2132424,
// this will be used to trigger search on the frontend if call
// optional
"call_detail_id": 2132424,
// this will be used to trigger search on the frontend if sms
// optional
"sms_conversation_id": 2132424,
// timing - what about holidays?
// required mainly for inbound emails, inbound texts, and outbound calls but would likely make task-routing logic easier if all tasks had this
"acceptable_contact_time_min_utc": "0800",
"acceptable_contact_time_max_utc": "1630", // update, all task ordering must be done using task.priority
// the following will be used on the frontend to automatically go straight to a lead or resident, also it will be used when transferring a task to a supervisor to automatically pull up the lead or resident
// it's also used just in normal chats and whatnot to skip the search
// optional
"lead_id": 3245621,
"resident_id": 435563,
// used in transfers
// optional
"transferred_from_user_id": 291,
// completion -- this may be better served in the "conversations" sub-object
// optional
"completed_by_user_id": 291,
// this is needed only for calls
"call_route_step?": 0,
...{ /* ... any other use-case specific attributes can be added here */ }
},
// these are used only for direct task assignment use-cases
"targetWorker":"client:chasewgibbons", // outbpund call direct assignment added automatically by flex
"flexOutboundDialerTargetWorker": "client:chasewgibbons", // outbpund call direct assignment added automatically by flex
// direction
"direction": "inbound",
// todo: make this more robust
// should set as much of the following whenever we can for flex insights reporting purposes
"conversations" : {
// s3 call recording link
"segment_link" : "https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Recordings/REXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
// parent taskSid to link followUps together in flex insights
"conversation_id" : "WTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
// whether or not conversation was productive
"productive": "true",
// example custom metric which doesn't count towards 2 billion unique values limit
"conversation_attribute_1" : "Google",
// links to above conversation_attribute_1
"conversation_label_1" : "AdSourceName",
// integer of some measure, it might link to the conversation_attribute_1 and conversation_label_1 above, idk, need to look this one up..
"conversation_measure_1" : 101,
// language used by participants in the conversation
"language": "spanish",
// outcome of conversation
"outcome": "no appointment set"
},
// todo: make this more robust
// should set as much of the following whenever we can for flex insights reporting purposes
"customers":{
"phone":"3059867013",
"market_segment":"4th Street Commons",
"organization":"Asset Campus Housing",
"name":"JESSICA AUJLA",
"custom_attr_1":true,
"category":"4th Street Commons",
"customer_manager":"Asset Campus Housing",
// example custom metric which doesn't count towards 2 billion unique values limit
"customer_attribute_1" : "544532",
// links to above customer_attribute_1
"customer_label_1" : "LeadId",
// value of this customer to the business, greater equals more valuable
// 10 means most valuable
// 0 means not at all valuable
"business_value" : 2
},
// dictates how flex behaves on frontend, this is added automatically on frontend direct assignments in certain instances as camelcase
"autoAnswer":false,
// i'm not sure what this does tbh, but it is added on frontend automatically in certain instances
"internal":false
}
interface AnyObject {
[key: string]: any;
}
interface TaskAttributes extends AnyObject {
name: string;
channelType: "chat" | "sms" | "voice" | "email" | "follow-up";
type: "short-lived" | "long-lived";
vip: boolean;
spoken_language: "english" | "spanish",
rd: Rd;
targetWorker?: string;
flexOutboundDialerTargetWorker?: string;
direction: "inbound" | "outbound";
conversations: Conversations;
customers: Customers;
autoAnswer?: "true" | "false";
internal?: "true" | "false";
}
interface Customers {
phone?: string;
market_segment: string;
organization: string;
name: string;
custom_attr_1?: boolean;
category: string;
customer_manager?: string;
customer_attribute_1?: string;
customer_label_1?: string;
business_value?: number;
}
interface Conversations {
segment_link?: string;
conversation_id?: string;
productive: "true" | "false";
conversation_attribute_1: string;
conversation_label_1: string;
conversation_measure_1: number;
language: "english" | "spanish";
outcome?: string;
}
interface Rd extends AnyObject {
contact_center_id: number;
start_date: string;
client_id: number;
community_group_id?: number;
ad_source_id?: number;
// community_group_priority: number; // update, all task ordering must be done using task.priority
worker_experience_required: number;
parent_task_sid?: string;
parent_task_channel_unique_name?: string;
email_message_id?: number;
call_detail_id?: number;
sms_conversation_id?: number;
acceptable_contact_time_min_utc: string;
acceptable_contact_time_max_utc: string;
// acceptable_contact_time_utc_offset: number; // update, all task ordering must be done using task.priority
lead_id?: number;
resident_id?: number;
transferred_from_user_id?: number;
completed_by_user_id?: number;
call_route_step?: number;
}
// worker
var workerJson = {
"public_identity":"Chase",
// this is what flex uses to do direct assignment in task-router
"contact_uri":"client:cgibbons",
"roles":["admin","wfo.full_access"],
"team_leader_sid": "",
"first_name":"Chase",
"last_name":"Gibbons",
"full_name":"Chase Gibbons",
"rd_username":"cgibbons",
"user_id":"291",
"phone":"+14359994722",
"email":"chase@rentdynamics.com",
"rd_auth_token":"7975c687ab46687f9800ce8b38d55bac295d720ce2c3",
// this is ytica stuff
"manager":"Zach Passey",
"team_id":"1",
"team_name":"Hello",
"team_name_in_hierarchy":"Hello,Logan,UT",
"department":"Contact Center",
"department_id": "2",
// this is how the flex-ui sets up the skills on the worker when modifying them through the frontend by default
// we might change this up a bit to allow arrays
"routing":{
"skills": [
// this will be set from the frontend and it will mean the worker is capable of speaking spanish
"spanish_speaking",
// signifies how big a priority it is for the worker is in the queue
"overflow_status",
// this should signify the overall experience this worker has as a contact-center agent at taking all kinds of tasks
"experience_level"
],
"levels":{
// 10 means they should recieve calls/chats/emails last
// 0 means they should recieve calls/chats/emails first
"overflow_status":10,
// 10 means they are the most experienced ever
// 0 means they are a new hire
"experience_level": 9
}
},
"disabled_skills":{"skills":[],"levels":{}}
}
interface AnyObject {
[key: string]: any;
}
interface WorkerAttributes extends AnyObject {
public_identity: string;
contact_uri: string;
roles: string[];
team_leader_sid: string;
first_name: string;
last_name: string;
full_name: string;
rd_username: string;
user_id: string;
phone: string;
email: string;
rd_auth_token: string;
manager: string;
team_id: string;
team_name: string;
team_name_in_hierarchy: string;
department: string;
department_id: string;
routing: Routing;
disabled_skills: Disabledskills;
}
interface Disabledskills {
skills: any[];
levels: Levels2;
}
interface Levels2 extends AnyObject {
}
interface Routing {
skills: string[];
levels: Levels;
}
interface Levels extends AnyObject {
overflow_status: number;
experience_level: number;
}
@chase2981
Copy link
Author

chase2981 commented Feb 11, 2021


	// update task attributes to ignore the agent who transferred the task
	// it's possible that the agent who transferred the task is in the queue
	// the task is being transferred to - but we don't want them to
	// receive a task they just transferred. It's also possible the agent
	// is simply transferring to the same queue the task is already in
	// once again, we don't want the transferring agent to receive the task
	newAttributes.ignoreAgents = [...oldAttributes.ignoreAgents, ...[workerName]];

	// update task attributes to include the required targetSid on the task
	// this could either be a workerSid or a queueSid
	newAttributes.targetSid = targetSid;

	// add an attribute that will tell our Workflow if we're transferring to a worker or a queue
	if (targetSid.startsWith('WK')) {
		newAttributes.transferTargetType = 'worker';
	} else {
		newAttributes.transferTargetType = 'queue';
	}
ignore_agents: [] // for when rejecting a task

The following attributes will make it so the worker doesn't even have to click accept on a task, it automatically assigns it to them and it automatically selects it within the flex-ui.

"targetWorker": "client:cgibbons",
"autoAnswer": "true",
 "_selectTask": true,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment