CHI-3946-refactor_conversationMedia_creation - #4582
Conversation
|
@copilot Implement the changes described in the PR description |
There was a problem hiding this comment.
Pull request overview
This PR introduces first-class voicemail channel support across the Flex plugin and account-scoped lambdas, including UI surfacing (task panel + icons + queue status), shared channel typing, and a new webhook handler to create voicemail TaskRouter tasks.
Changes:
- Add voicemail task UI in Flex (task info panel, icons/colors, queue status support) and translation strings.
- Add a new account-scoped webhook (
voicemail/recordingCompleteCallback) to create a TaskRouter task when a voicemail recording completes. - Refactor/centralize channel typing (new
@tech-matters/twilio-typeschannelType module) and add voicemail identifier sanitization + voicemail conversationMedia posting on contact creation.
Reviewed changes
Copilot reviewed 38 out of 39 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin-hrm-form/src/voicemail/VoicemailTaskPanel.tsx | New Flex task info panel content for voicemail tasks (recording + actions). |
| plugin-hrm-form/src/voicemail/setUpVoicemailComponents.tsx | Registers voicemail components into Flex UI (TaskInfoPanel). |
| plugin-hrm-form/src/utils/task.ts | Adds voicemail identifier normalization using phone number standardization. |
| plugin-hrm-form/src/translations/en.json | Adds localized strings for voicemail task panel buttons. |
| plugin-hrm-form/src/transfer/transferTaskState.ts | Adjusts transfer eligibility logic (now based on isVoiceTask). |
| plugin-hrm-form/src/states/DomainConstants.ts | Adds voicemail to core/custom channel type constants. |
| plugin-hrm-form/src/HrmFormPlugin.tsx | Hooks voicemail component setup into plugin initialization. |
| plugin-hrm-form/src/components/queuesStatus/QueueCard.tsx | Adds voicemail rendering in queue status UI. |
| plugin-hrm-form/src/components/queuesStatus/helpers.ts | Adds voicemail field to new queue entry shape. |
| plugin-hrm-form/src/components/profile/IdentifierBanner/iconsFromTask.ts | Adds voicemail icon mapping for identifier banner. |
| plugin-hrm-form/src/components/contact/MediaSection/RecordingSection.tsx | Adds autoLoad and makes overlay loader optional. |
| plugin-hrm-form/src/components/common/icons/VoicemailIcon.tsx | New voicemail SVG icon component. |
| plugin-hrm-form/src/components/case/timeline/TimelineIcon.tsx | Adds voicemail icon support in timeline icon factory. |
| plugin-hrm-form/src/channels/colors.ts | Adds voicemail channel color entry. |
| plugin-hrm-form/src/_tests/transfer/transferTaskState.test.ts | Updates mocks to align with transfer logic changes. |
| plugin-hrm-form/src/_tests/components/queuesStatus/QueuesStatus.test.tsx | Updates expected queue status shape and channel rendering checks. |
| lambdas/packages/twilio-types/src/index.ts | Adds RecordingSid and re-exports new channel typing module. |
| lambdas/packages/twilio-types/src/channelType.ts | New shared channel constants/types + custom channel detection helper. |
| lambdas/packages/hrm-types/src/index.ts | Adds voicemail to HRM ChannelTypes union. |
| lambdas/package-lock.json | Updates uuid semver range in root package entry. |
| lambdas/account-scoped/tests/unit/hrm/getProfileFlagsForIdentifier.test.ts | Tightens channel typing usage via shared ChannelType/channelTypes. |
| lambdas/account-scoped/tests/unit/hrm/createHrmContactTaskRouterListener.test.ts | Mocks/validates new patchTaskAttributes usage. |
| lambdas/account-scoped/tests/unit/conversation/janitorTaskRouterListener.test.ts | Switches custom-channel detection mock to @tech-matters/twilio-types. |
| lambdas/account-scoped/tests/service/hrm/getProfileFlagsForIdentifier.test.ts | Removes unused channelType field from mock event. |
| lambdas/account-scoped/src/voicemail/recordingCompleteCallback.ts | New webhook handler that creates voicemail TaskRouter tasks and sets received time. |
| lambdas/account-scoped/src/router.ts | Registers new voicemail/recordingCompleteCallback route. |
| lambdas/account-scoped/src/hrm/sanitizeIdentifier.ts | Adds voicemail normalization and types channelType as ChannelType. |
| lambdas/account-scoped/src/hrm/createHrmContactTaskRouterListener.ts | Uses optimistic attribute patching + posts S3 recording media for voicemail contacts. |
| lambdas/account-scoped/src/customChannels/telegram/telegramToFlex.ts | Migrates to shared aseloCustomChannelTypes constant. |
| lambdas/account-scoped/src/customChannels/modica/modicaToFlex.ts | Migrates to shared aseloCustomChannelTypes constant. |
| lambdas/account-scoped/src/customChannels/line/lineToFlex.ts | Migrates to shared aseloCustomChannelTypes constant. |
| lambdas/account-scoped/src/customChannels/instagram/instagramToFlex.ts | Migrates to shared aseloCustomChannelTypes constant. |
| lambdas/account-scoped/src/customChannels/customChannelToFlex.ts | Removes re-export of old custom-channel enum helpers. |
| lambdas/account-scoped/src/customChannels/configuration.ts | Tightens studio flow lookup typing to shared channel types. |
| lambdas/account-scoped/src/conversation/janitorTaskRouterListener.ts | Switches custom-channel detection to shared isAseloCustomChannelType. |
| lambdas/account-scoped/src/conversation/getExternalRecordingS3Location.ts | Extracts reusable getExternalRecordingS3Location function and keeps handler wrapper. |
| lambdas/account-scoped/src/conversation/createConversation.ts | Tightens channel typing for conversation creation params. |
| lambdas/account-scoped/src/channelCapture/postSurveyListener.ts | Types channelType as shared ChannelType. |
| lambdas/account-scoped/src/channelCapture/channelCaptureHandlers.ts | Types channelType as shared ChannelType across capture flows. |
Files not reviewed (1)
- lambdas/package-lock.json: Generated file
| export const recordingCompleteCallback: AccountScopedHandler = async ( | ||
| { body }, | ||
| accountSid, | ||
| ): Promise<Result<HttpError, any>> => { | ||
| console.debug('recordingCompleteCallback body', JSON.stringify(body, null, 2)); | ||
| const { from, callSid, recordingSid, maxCallbackAttempts } = | ||
| body as RecordingCompleteCallbackRequestBody; | ||
|
|
…handlers Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
…conversationMedia_creation
| }); | ||
| }; | ||
|
|
||
| registerTaskRouterEventHandler([TASK_WRAPUP], handleEvent); |
There was a problem hiding this comment.
I have updated the PR description, on reflection this code makes more sense to run on task completed events @copilot
There was a problem hiding this comment.
Fixed in 9e0e2b8 — the 8 errors were all prettier/prettier formatting violations in createHrmContactTaskRouterListener.test.ts and recordingCompleteCallback.test.ts. Resolved with eslint --fix; npm run lint in lambdas is now clean (only 2 pre-existing return-await warnings remain) and all 139 unit tests in tests/unit/hrm and tests/unit/voicemail pass.
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Description
@copilot Rework the code that posts conversationMedia to the HRM backend service. Currently requests are initiated from the flex front end plugin, or as part of the contact creation portion of the contact creation
Move all conversation media item creation to task router event handlers in the account scoped lambda. Voice recordings and transcripts media records should be created on task completion, voicemail should continue to be executed from its current location but share common code
Retain the current flex code, have a feature flag to control whether conversationMedia items are created from Flex or the task router handler (this does not apply to voice mails which are always handled in a task router handler)
Checklist
Other Related Issues
None
Verification steps
AFTER YOU MERGE
You are responsible for ensuring the above steps are completed. If you move a ticket into QA without advising what version to test, the QA team will assume the latest tag has the changes. If it does not, the following confusion is on you! :-P