-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
15761d6
commit 3d8d516
Showing
3 changed files
with
93 additions
and
84 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
functions/interaction/interactionChannelParticipants.private.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { Context } from '@twilio-labs/serverless-runtime-types/types'; | ||
import { | ||
InteractionChannelParticipantInstance, | ||
InteractionChannelParticipantListInstance, | ||
InteractionChannelParticipantStatus, | ||
} from 'twilio/lib/rest/flexApi/v1/interaction/interactionChannel/interactionChannelParticipant'; | ||
|
||
const transitionAgentParticipants = async ( | ||
client: ReturnType<Context<any>['getTwilioClient']>, | ||
twilioWorkspaceSid: string, | ||
taskSid: string, | ||
targetStatus: InteractionChannelParticipantStatus, | ||
interactionChannelParticipantSid?: string, | ||
): Promise<string[] | { errorType: 'Validation' | 'Exception'; errorMessage: string }> => { | ||
console.log('==== transitionAgentParticipants ===='); | ||
|
||
const task = await client.taskrouter.workspaces | ||
.get(twilioWorkspaceSid) | ||
.tasks.get(taskSid) | ||
.fetch(); | ||
const { flexInteractionSid, flexInteractionChannelSid } = JSON.parse(task.attributes); | ||
|
||
if (!flexInteractionSid || !flexInteractionChannelSid) { | ||
console.warn( | ||
"transitionAgentParticipants called with a task without a flexInteractionSid or flexInteractionChannelSid set in it's attributes - is it being called with a Programmable Chat task?", | ||
task.attributes, | ||
); | ||
return { | ||
errorType: 'Validation', | ||
errorMessage: | ||
"ValidationError: Task specified must have a flexInteractionSid and flexInteractionChannelSid set in it's attributes", | ||
}; | ||
} | ||
const interactionParticipantListInstance: InteractionChannelParticipantListInstance = | ||
client.flexApi.v1.interaction | ||
.get(flexInteractionSid) | ||
.channels.get(flexInteractionChannelSid).participants; | ||
const interactionAgentParticipants = (await interactionParticipantListInstance.list()).filter( | ||
(p) => | ||
p.type === 'agent' && | ||
(p.sid === interactionChannelParticipantSid || !interactionChannelParticipantSid), | ||
); | ||
|
||
if (interactionAgentParticipants.length === 0) { | ||
return []; | ||
} | ||
|
||
const results = await Promise.allSettled( | ||
interactionAgentParticipants.map((p) => { | ||
console.log(`Transitioning agent participant ${p.sid} to ${targetStatus}`); | ||
Object.entries(p).forEach(([k, v]) => { | ||
try { | ||
console.log(`${k}: ${typeof v === 'object' ? JSON.stringify(v) : v}`); | ||
} catch (e) { | ||
console.log(`${k}: ${v}`); | ||
} | ||
}); | ||
console.log('routing_properties', JSON.stringify((p as any).routing_properties)); | ||
console.log('routingProperties', JSON.stringify((p as any).routingProperties)); | ||
|
||
return p.update({ status: targetStatus }); | ||
}), | ||
); | ||
const failures: PromiseRejectedResult[] = results.filter( | ||
(r) => r.status === 'rejected', | ||
) as PromiseRejectedResult[]; | ||
failures.forEach((f) => console.warn(f.reason)); | ||
// This is a bit of a hack. Conversations which have been transferred between agents should have all the previous agents removed as participants of the interaction | ||
// However if they haven't for any reason, they are in a state where their status cannot be transitioned, presumably because they are no longer active in the conversation. | ||
// I can't see a good way to detect these in the API, so we assume if any of the agents are successfully transitioned, the 'current' agent has been transitioned and the operation can be considered successful. | ||
// There are probably edge cases where this assumption isn't valid, but this is itself working around an edge case so we would be into edge cases of edge cases there. | ||
if (failures.length < interactionAgentParticipants.length) { | ||
return results | ||
.filter((r) => r.status === 'fulfilled') | ||
.map((r) => (r as PromiseFulfilledResult<InteractionChannelParticipantInstance>).value.sid); | ||
} | ||
return { errorType: 'Exception', errorMessage: failures[0].reason }; | ||
}; | ||
|
||
export type InteractionChannelParticipants = { | ||
transitionAgentParticipants: typeof transitionAgentParticipants; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters