Skip to content

Commit

Permalink
feat(contentful): WIP new Handoff content
Browse files Browse the repository at this point in the history
  • Loading branch information
dpinol committed Jun 10, 2021
1 parent f95705d commit d133d1f
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 2 deletions.
9 changes: 9 additions & 0 deletions packages/botonic-plugin-contentful/src/cms/cms-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
DateRangeContent,
Document,
Element,
Handoff,
Image,
Queue,
ScheduleContent,
Expand Down Expand Up @@ -81,6 +82,14 @@ export class ErrorReportingCMS implements CMS {
this.cms.document(id, context)
)
}
handoff(id: string, context?: Context): Promise<Handoff> {
return this.catchAndValidate(
id,
context,
ContentType.HANDOFF,
this.cms.handoff(id, context)
)
}
text(id: string, context?: Context): Promise<Text> {
return this.catchAndValidate(
id,
Expand Down
5 changes: 4 additions & 1 deletion packages/botonic-plugin-contentful/src/cms/cms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DateRangeContent,
Document,
Element,
Handoff,
Image,
Queue,
ScheduleContent,
Expand All @@ -35,9 +36,10 @@ export const MESSAGE_CONTENT_TYPES = Object.values(MessageContentType).filter(

export enum NonMessageTopContentType {
DATE_RANGE = 'dateRange',
HANDOFF = 'handoff',
QUEUE = 'queue',
URL = 'url',
SCHEDULE = 'schedule',
URL = 'url',
}

export type TopContentType = MessageContentType | NonMessageTopContentType
Expand Down Expand Up @@ -114,6 +116,7 @@ export interface CMS {
chitchat(id: string, context?: Context): Promise<Chitchat>
element(id: string, context?: Context): Promise<Element>

handoff(id: string, context?: Context): Promise<Handoff>
/** Even if ContentfulOptions.resumeErrors is set, if the asset is not available
* the method will fail. */
image(id: string, context?: Context): Promise<Image>
Expand Down
52 changes: 52 additions & 0 deletions packages/botonic-plugin-contentful/src/cms/contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,58 @@ export class ScheduleContent extends TopContent {
}
}

export class OnFinishPayload {
readonly type = 'PAYLOAD'
constructor(readonly payload: string) {}
}

export class OnFinishPath {
readonly type = 'PATH'
constructor(readonly path: string) {}
}

export type OnFinish = OnFinishPath | OnFinishPayload

export class HandoffAgentEmail {
readonly type = 'AGENT_EMAIL'
constructor(readonly agentEmail?: string) {}
}

export class HandoffAgentId {
readonly type = 'AGENT_ID'
constructor(readonly agentId?: string) {}
}

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

export type HandoffDestination =
| HandoffAgentEmail
| HandoffAgentId
| HandoffQueue

/**
* Most CommonFields make no sense for Handoff.
* However, we decided to make it a TopContent since it does not depend on other content.
* Also CommonFields might be potentially useful.
*/
export class Handoff extends TopContent {
constructor(
readonly common: CommonFields,
readonly text: string,
readonly onFinish: OnFinish,
readonly destination?: HandoffDestination,
readonly shadowing?: boolean
) {
super(common, ContentType.HANDOFF)
}
}

/**
* A {@link Content} which is automatically displayed after another one
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export abstract class ResourceDelivery {
})
}

private getContentIdForLogs(entry: contentful.Entry<any>): ContentId {
protected getContentIdForLogs(entry: contentful.Entry<any>): ContentId {
if (ContentfulEntryUtils.isFullEntry(entry)) {
return ContentfulEntryUtils.getContentId(entry)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as contentful from 'contentful'

import * as cms from '../../cms'
import { CmsException, ContentType, OnFinish, OnFinishPayload } from '../../cms'
import { DeliveryApi } from '../delivery-api'
import {
addCustomFields,
CommonEntryFields,
ContentfulEntryUtils,
} from '../delivery-utils'
import { DeliveryWithFollowUp } from './follow-up'

export class HandoffDelivery extends DeliveryWithFollowUp {
constructor(delivery: DeliveryApi, resumeErrors: boolean) {
super(ContentType.HANDOFF, delivery, resumeErrors)
}

async handoff(id: string, context: cms.Context): Promise<cms.Handoff> {
const entry: contentful.Entry<HandoffFields> = await this.getEntry(
id,
context
)
return this.fromEntry(entry, context)
}

onFinish(entry: contentful.Entry<HandoffFields>): OnFinish {
if (entry.fields.onFinishPayload && entry.fields.onFinishPath) {
throw new CmsException(
`${this.getContentIdForLogs(entry)} has both path and payload`
)
} else if (entry.fields.onFinishPayload) {
return new OnFinishPayload(entry.fields.onFinishPayload)
} else if (entry.fields.onFinishPath) {
return new OnFinishPayload(entry.fields.onFinishPath)
}
throw new CmsException(
`${this.getContentIdForLogs(entry)} has neither path nor payload`
)
}

async fromEntry(
entry: contentful.Entry<HandoffFields>,
context: cms.Context
): Promise<cms.Handoff> {
const fields = entry.fields
const common = ContentfulEntryUtils.commonFieldsFromEntry(entry)
return addCustomFields(
new cms.Handoff(
common,
fields.text,
this.onFinish(entry),
this.destination(entry),
fields.shadowing
),
fields,
['onFinishPath', 'onFinishPayload', 'queue', 'agentEmail', 'agendId']
)
}
}

export interface HandoffFields extends CommonEntryFields {
handoff: contentful.Asset
}

export interface HandoffFields extends CommonEntryFields {
text: string
queue?: string
agentEmail?: string
agentId?: string
onFinishPath?: string
onFinishPayload?: string
shadowing?: boolean
}

0 comments on commit d133d1f

Please sign in to comment.