Skip to content

Commit

Permalink
feat(contentful): add handoff fail message, split destination
Browse files Browse the repository at this point in the history
  • Loading branch information
AinaVendrell committed Jun 23, 2021
1 parent b8313d6 commit 772790b
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 78 deletions.
6 changes: 3 additions & 3 deletions packages/botonic-plugin-contentful/src/cms/cms-dummy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Document,
Element,
Handoff,
HandoffQueue,
Image,
Queue,
ScheduleContent,
Expand Down Expand Up @@ -70,9 +69,10 @@ export class DummyCMS implements CMS {
return Promise.resolve(
new Handoff(
new CommonFields(id, id),
'Dummy text for ' + id,
this.buttonCallbacks[0],
new HandoffQueue(queue)
'Dummy message for ' + id,
'Dummy handofFailfMessage for ' + id,
queue
)
)
}
Expand Down
35 changes: 16 additions & 19 deletions packages/botonic-plugin-contentful/src/cms/contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ export class Queue extends TopContent {
readonly common: CommonFields,
readonly queue: string,
readonly schedule?: time.Schedule,
readonly handoffMessage?: string
readonly message?: string
) {
super(common, ContentType.QUEUE)
}
Expand Down Expand Up @@ -440,18 +440,7 @@ export class HandoffAgentId {
constructor(readonly agentId: string) {}
}

export class HandoffQueue {
readonly type = 'QUEUE'
/**
* @param queue the queue id or name
*/
constructor(readonly queue: Queue) {}
}

export type HandoffDestination =
| HandoffAgentEmail
| HandoffAgentId
| HandoffQueue
export type HandoffAgent = HandoffAgentEmail | HandoffAgentId

/**
* Most CommonFields make no sense for Handoff.
Expand All @@ -461,18 +450,26 @@ export type HandoffDestination =
export class Handoff extends TopContent {
constructor(
readonly common: CommonFields,
readonly text: string,
readonly onFinish?: OnFinish,
//destination is optional because often it is set dynamically by the bot
readonly destination?: HandoffDestination,
readonly onFinish: OnFinish,
readonly message?: string,
readonly failMessage?: string,
//agent and queue are optional because often they are set dynamically by the bot
readonly queue?: Queue,
readonly agent?: HandoffAgent,
readonly shadowing?: boolean
) {
super(common, ContentType.HANDOFF)
}

cloneWithDestination(newDestination: HandoffDestination): this {
cloneWithQueue(newQueue: Queue): this {
const clone = shallowClone(this)
;(clone as any).queue = newQueue
return clone
}

cloneWithAgent(newAgent: HandoffAgent): this {
const clone = shallowClone(this)
;(clone as any).destination = newDestination
;(clone as any).agent = newAgent
return clone
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
Element,
FollowUp,
Handoff,
HandoffDestination,
HandoffAgent,
Image,
OnFinish,
Queue,
StartUp,
Text,
} from '../contents'
Expand Down Expand Up @@ -224,20 +225,32 @@ export class DocumentBuilder extends MessageContentBuilder {
}

export class HandoffBuilder extends MessageContentBuilder {
onFinish?: OnFinish
destination?: HandoffDestination
message?: string
failMessage?: string
queue?: Queue
agent?: HandoffAgent
shadowing?: boolean
constructor(id: string, name: string, public text: string) {
constructor(id: string, name: string, public onFinish: OnFinish) {
super(id, name)
}

withOnFinish(onFinish?: OnFinish): this {
this.onFinish = onFinish
withHandoffMessage(message?: string): this {
this.message = message
return this
}

withHandoffFailMessage(failMessage?: string): this {
this.failMessage = failMessage
return this
}

withDestination(destination?: HandoffDestination): this {
this.destination = destination
withQueue(queue?: Queue): this {
this.queue = queue
return this
}

withAgent(agent?: HandoffAgent): this {
this.agent = agent
return this
}

Expand All @@ -249,9 +262,11 @@ export class HandoffBuilder extends MessageContentBuilder {
build(): Handoff {
return new Handoff(
this.buildCommonFields(),
this.text,
this.onFinish,
this.destination,
this.message,
this.failMessage,
this.queue,
this.agent,
this.shadowing
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ContentType } from '../cms'
import { HandoffAgentEmail } from '../contents'
import { HandoffAgentEmail, OnFinish } from '../contents'
import {
CarouselBuilder,
DocumentBuilder,
Expand Down Expand Up @@ -240,13 +240,17 @@ export class RndDocumentBuilder extends DocumentBuilder {
export class RndHandoffBuilder extends HandoffBuilder {
readonly topComponentBuilder = new RndTopContentBuilder()

constructor(name: string = rndStr(), text: string = rndStr()) {
super(rndStr(), name, text)
constructor(
name: string = rndStr(),
onFinish: OnFinish = new ContentCallbackBuilder().build()
) {
super(rndStr(), name, onFinish)
}

withRandomFields(): this {
this.onFinish = new ContentCallbackBuilder().build()
this.destination = new HandoffAgentEmail(rndStr())
this.message = rndStr()
this.failMessage = rndStr()
this.agent = new HandoffAgentEmail(rndStr())
this.shadowing = rndBool()
this.topComponentBuilder.withRandomFields(this)
return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import * as contentful from 'contentful'

import * as cms from '../../cms'
import {
CmsException,
ContentType,
HandoffAgent,
HandoffAgentEmail,
HandoffAgentId,
HandoffDestination,
HandoffQueue,
OnFinish,
Queue,
} from '../../cms'
import { DeliveryApi } from '../delivery-api'
import {
Expand All @@ -23,7 +24,7 @@ export class HandoffDelivery extends DeliveryWithFollowUp {
static REFERENCES_INCLUDE = QueueDelivery.REFERENCES_INCLUDE + 1
constructor(
delivery: DeliveryApi,
private readonly queue: QueueDelivery,
private readonly queueDelivery: QueueDelivery,
resumeErrors: boolean
) {
super(ContentType.HANDOFF, delivery, resumeErrors)
Expand All @@ -41,38 +42,37 @@ export class HandoffDelivery extends DeliveryWithFollowUp {
private onFinish(
entry: contentful.Entry<HandoffFields>,
context: cms.Context
): OnFinish | undefined {
if (entry.fields.onFinish) {
return getTargetCallback(entry.fields.onFinish, context)
): OnFinish {
if (!entry.fields.onFinish) {
throw new CmsException(`Handoff ${this.entryId(entry)} has no onFinish`)
}
return undefined
return getTargetCallback(entry.fields.onFinish, context)
}

private queue(entry: contentful.Entry<HandoffFields>): Queue | undefined {
if (!entry.fields.queue) return undefined
return this.queueDelivery.fromEntry(
entry.fields.queue as contentful.Entry<QueueFields>
)
}

private destination(
private agent(
entry: contentful.Entry<HandoffFields>
): HandoffDestination | undefined {
if (!entry.fields.destination) return undefined
): HandoffAgent | undefined {
if (!entry.fields.agent) return undefined
const AGENT_EMAIL_TYPE = 'agentEmail'
const AGENT_ID_TYPE = 'agentId'
const model = ContentfulEntryUtils.getContentModel(
entry.fields.destination
entry.fields.agent
) as string
switch (model) {
case ContentType.QUEUE:
return new HandoffQueue(
this.queue.fromEntry(
entry.fields.destination as contentful.Entry<QueueFields>
)
)
case AGENT_EMAIL_TYPE: {
const destination = entry.fields
.destination as contentful.Entry<AgentEmailFields>
return new HandoffAgentEmail(destination.fields.agentEmail)
const agent = entry.fields.agent as contentful.Entry<AgentEmailFields>
return new HandoffAgentEmail(agent.fields.agentEmail)
}
case AGENT_ID_TYPE: {
const destination = entry.fields
.destination as contentful.Entry<AgentIdFields>
return new HandoffAgentId(destination.fields.agentId)
const agent = entry.fields.agent as contentful.Entry<AgentIdFields>
return new HandoffAgentId(agent.fields.agentId)
}
}
return undefined
Expand All @@ -87,13 +87,15 @@ export class HandoffDelivery extends DeliveryWithFollowUp {
return addCustomFields(
new cms.Handoff(
common,
fields.text,
this.onFinish(entry, context),
this.destination(entry),
fields.message,
fields.failMessage,
this.queue(entry),
this.agent(entry),
fields.shadowing
),
fields,
['onFinish', 'destination']
['onFinish', 'agent', 'queue']
)
}
}
Expand All @@ -106,13 +108,13 @@ export interface AgentIdFields {
agentId: string
}

type DestinationTarget = contentful.Entry<
QueueFields | AgentEmailFields | AgentIdFields
>
type AgentTarget = contentful.Entry<AgentEmailFields | AgentIdFields>

export interface HandoffFields extends CommonEntryFields {
text: string
destination?: DestinationTarget
onFinish?: CallbackTarget
message?: string
failMessage?: string
onFinish: CallbackTarget
queue?: contentful.Entry<QueueFields>
agent?: AgentTarget
shadowing?: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class QueueDelivery extends TopContentDelivery {
ContentfulEntryUtils.commonFieldsFromEntry(entry),
fields.queue,
schedule && schedule.schedule,
fields.handoffMessage
fields.message
),
fields
)
Expand All @@ -50,5 +50,5 @@ export class QueueDelivery extends TopContentDelivery {
export interface QueueFields extends CommonEntryFields {
queue: string
schedule?: contentful.Entry<ScheduleFields>
handoffMessage?: string
message?: string
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
ContentCallback,
ContentType,
HandoffAgentEmail,
HandoffAgentId,
HandoffQueue,
SPANISH,
} from '../../../src'
import { testContentful, testContext } from '../contentful.helper'
Expand All @@ -12,7 +12,7 @@ const TEST_HANDOFF_QUEUE_MAIN_ID = '6A7D4ssRYuLufjvl1pnOzV'
const TEST_QUEUE_ID = '62ILnVxLHOEp7aVvPMpCO8'

describe('Contentful Handoff', () => {
test('TEST: contentful handoff with queue as destination', async () => {
test('TEST: contentful handoff with queue and AgentId', async () => {
const sut = testContentful()

// act
Expand All @@ -23,10 +23,11 @@ describe('Contentful Handoff', () => {

// assert
const queue = await testContentful().queue(TEST_QUEUE_ID, testContext())
expect(handoff.text).toEqual('En breve un agente le atenderá')
expect(handoff.message).toEqual('En breve un agente le atenderá')
expect(handoff.common.name).toEqual('HANDOFF QUEUE')
expect(handoff.common.shortText).toEqual('Agent Handoff')
expect(handoff.destination).toEqual(new HandoffQueue(queue))
expect(handoff.queue).toEqual(queue)
expect(handoff.agent).toEqual(new HandoffAgentEmail('agent email'))
expect(handoff.onFinish).toEqual(
new ContentCallback(ContentType.TEXT, 'C39lEROUgJl9hHSXKOEXS')
)
Expand All @@ -36,7 +37,7 @@ describe('Contentful Handoff', () => {
})
})

test('TEST: contentful handoff with AgentId as destination', async () => {
test('TEST: contentful handoff with AgentId', async () => {
const sut = testContentful()

// act
Expand All @@ -46,10 +47,11 @@ describe('Contentful Handoff', () => {
)

// assert
expect(handoff.text).toEqual('En breve un agente le atenderá')
expect(handoff.message).toEqual('En breve un agente le atenderá')
expect(handoff.failMessage).toEqual('Agente no disponible')
expect(handoff.common.name).toEqual('HANDOFF AGENT_ID')
expect(handoff.common.shortText).toEqual('Agent Handoff')
expect(handoff.destination).toEqual(new HandoffAgentId('agent id'))
expect(handoff.agent).toEqual(new HandoffAgentId('agent id'))
expect(handoff.onFinish).toEqual(
new ContentCallback(ContentType.TEXT, 'C39lEROUgJl9hHSXKOEXS')
)
Expand Down

0 comments on commit 772790b

Please sign in to comment.