Skip to content

CHI-3641: Add channel_type attribute to new aselo webchat conversations.#4087

Open
stephenhand wants to merge 18 commits intomasterfrom
CHI-3641-channel_type_convo_attribute
Open

CHI-3641: Add channel_type attribute to new aselo webchat conversations.#4087
stephenhand wants to merge 18 commits intomasterfrom
CHI-3641-channel_type_convo_attribute

Conversation

@stephenhand
Copy link
Copy Markdown
Collaborator

@stephenhand stephenhand commented Mar 23, 2026

Description

Replace call to deprecated API with reusing the conversation creation logic we use for custom channels (createConversation). Adds channel_type: 'web' to conversation attributes by passing channelType: 'web' through the shared createConversation flow, and uses getChannelStudioFlowSid to retrieve the studio flow SID from SSM.

Unit tests for initWebchat.ts have been rewritten to align with the updated flow: mocks for the deprecated webChannels.create and patchConversationAttributes have been replaced with mocks for createConversation and getChannelStudioFlowSid, with coverage for correct parameter passing, friendly name fallbacks, pre-engagement data attributes, error handling, and token generation.

Checklist

  • Corresponding issue has been opened
  • New tests added
  • [n/a] Feature flags added
  • [n/a] Strings are localized
  • Tested for chat contacts
  • [n/a] Tested for call contacts

Other Related Issues

None

Verification steps

Create a new webchat conversation and confirm the conversation attributes include channel_type: 'web'. Verify studio flows that branch on channel_type route correctly for webchat contacts.

AFTER YOU MERGE

  1. Cut a release tag using the Github workflow. Wait for it to complete and notify in the #aselo-deploys Slack channel.
  2. Comment on the ticket with the release tag version AND any additional instructions required to configure an environment to test the changes.
  3. Only then move the ticket into the QA column in JIRA

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


⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

@stephenhand
Copy link
Copy Markdown
Collaborator Author

@copilot - add unit test coverage for the updated initWebchat.ts

client.flexApi.v2.webChannels.create and patchConversationAttributes are calls with side effects, explicitly check they are invoked

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 23, 2026

@stephenhand I've opened a new pull request, #4088, to work on those changes. Once the pull request is ready, I'll request review from you.

@stephenhand
Copy link
Copy Markdown
Collaborator Author

@copilot fix the failing unit tests to align with the updated conversation creation process, remove any redundant ones and add new ones to address gaps in coverage of the new workflow

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 27, 2026

@copilot fix the failing unit tests to align with the updated conversation creation process, remove any redundant ones and add new ones to address gaps in coverage of the new workflow

Done in 25bfa84. The test file has been fully rewritten to align with the new flow:

Removed (no longer relevant):

  • Mocks for webChannels.create and patchConversationAttributes
  • Tests asserting the old webChannels.create arguments, patchConversationAttributes invocation, and the old "Customer" fallback name

Updated/added (covering the new workflow):

  • Mocks for createConversation and getChannelStudioFlowSid
  • getChannelStudioFlowSid called with accountSid and 'web'
  • createConversation called with all expected params (channelType: 'web', studioFlowSid, conversationFriendlyName, senderScreenName, twilioNumber: web:<accountSid>, uniqueUserName matching /^web:/, additionalConversationAttributes with pre_engagement_data and from)
  • createToken called with the identity passed as uniqueUserName to createConversation
  • Success result shape (token, conversationSid, expiration)
  • Error when createConversation throws (verifies createToken is not called)
  • Friendly name from CustomerFriendlyName body field when absent in form data
  • Fallback to 'Anonymous' (including from field in attributes)
  • Pre-engagement form data correctly set as additionalConversationAttributes.pre_engagement_data

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • mock-ssm
    • Triggering command: /opt/hostedtoolcache/node/20.20.1/x64/bin/node node /home/REDACTED/work/flex-plugins/flex-plugins/lambdas/node_modules/.bin/jest tests/unit/webchatAuthentication/initWebchat.test.ts --no-coverage (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@stephenhand stephenhand marked this pull request as ready for review March 27, 2026 17:40
@stephenhand stephenhand requested review from Copilot and gpaoloni March 30, 2026 12:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the webchat conversation initialization flow to use the shared Conversations creation helper (instead of the deprecated Flex WebChannels API), ensuring new webchat conversations include channel_type: 'web' in their attributes and use a Studio Flow SID retrieved from SSM. It also aligns several unit tests and custom-channel call sites with the updated conversation creation/webhook naming.

Changes:

  • Replace deprecated webchat conversation creation with shared createConversation(...), passing channelType: 'web' and retrieving the Studio Flow SID via getChannelStudioFlowSid(...).
  • Introduce shared conversation utilities (createConversation, patchConversationAttributes) and refactor custom channels to use onMessageAddedWebhookUrl naming.
  • Update/adjust unit tests to reflect new behavior (web conversations supported in HRM sanitization/profile-flag flows, janitor behavior changes, and rewritten webchat init tests).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lambdas/account-scoped/src/webchatAuthentication/initWebchat.ts Webchat now creates conversations via shared helper and uses SSM Studio Flow SID.
lambdas/account-scoped/tests/unit/webchatAuthentication/initWebchat.test.ts New unit tests for the updated init flow and parameter passing.
lambdas/account-scoped/src/conversation/createConversation.ts New shared conversation creation helper that sets attributes and webhooks.
lambdas/account-scoped/src/conversation/patchConversationAttributes.ts New helper to patch conversation attributes.
lambdas/account-scoped/src/customChannels/customChannelToFlex.ts Refactor to import shared createConversation and rename webhook param.
lambdas/account-scoped/src/customChannels/*/*ToFlex.ts Update call sites to pass onMessageAddedWebhookUrl (renames/aliases).
lambdas/account-scoped/src/customChannels/configuration.ts Allow getChannelStudioFlowSid to accept 'web' as a channel name.
lambdas/account-scoped/src/hrm/sanitizeIdentifier.ts Allow web conversation triggers to sanitize without error (behavior change).
lambdas/account-scoped/tests/unit/hrm/sanitizeIdentifier.test.ts Update expectations for web conversation trigger behavior.
lambdas/account-scoped/tests/unit/hrm/getProfileFlagsForIdentifier.test.ts Update expectations for web conversation channel behavior.
lambdas/account-scoped/src/conversation/chatChannelJanitor.ts Stop deleting proxy sessions when deactivating conversations (behavior change).
lambdas/account-scoped/tests/unit/conversation/chatChannelJanitor.test.ts Remove test coverage for proxy-session deletion on conversation deactivation.
Comments suppressed due to low confidence (1)

lambdas/account-scoped/src/conversation/chatChannelJanitor.ts:106

  • chatChannelJanitor's file header says it will delete the associated proxy session, but deactivateConversation no longer checks conversation attributes for proxySession or deletes it (only deactivateChannel does). Either update the documentation to reflect the new behavior or restore proxy-session cleanup for conversation-based flows if conversations can still have proxySession attributes.
const deactivateConversation = async (
  accountSid: AccountSID,
  conversationSid: ConversationSID,
) => {
  const client = await getTwilioClient(accountSid);
  const conversation = await client.conversations.v1.conversations
    .get(conversationSid)
    .fetch();

  if (conversation.state !== 'closed') {
    console.info('Attempting to deactivate active conversation', conversationSid);
    const updated = await conversation.update({
      state: 'closed',
      xTwilioWebhookEnabled: 'true',
    });

channelType: AseloCustomChannel | 'web'; // The chat channel being used
uniqueUserName: string; // Unique identifier for this user
senderScreenName: string; // Friendly info to show in the Flex UI (like Telegram handle)
onMessageAddedWebhookUrl?: string; // The url that must be used as the onMessageSent event webhook.
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onMessageAddedWebhookUrl is documented as "onMessageSent" in the inline comment, which is misleading now that the webhook is subscribed to the onMessageAdded filter. Update the comment to match the actual behavior (and consider renaming any remaining references to onMessageSent if they exist).

Suggested change
onMessageAddedWebhookUrl?: string; // The url that must be used as the onMessageSent event webhook.
onMessageAddedWebhookUrl?: string; // The url that must be used as the onMessageAdded event webhook.

Copilot uses AI. Check for mistakes.
Comment on lines 45 to 68
const client = await getTwilioClient(accountSid);
const orchestratorResponse = await client.flexApi.v2.webChannels.create({
customerFriendlyName,
addressSid,
preEngagementData: JSON.stringify(formData),
uiVersion: process.env.WEBCHAT_VERSION || '1.0.0',
chatFriendlyName: 'Webchat widget',
const conversation = await createConversation(client, {
channelType: 'web',
conversationFriendlyName: customerFriendlyName,
senderScreenName: customerFriendlyName,
studioFlowSid,
testSessionId,
twilioNumber: `web:${accountSid}`,
uniqueUserName: senderId,
additionalConversationAttributes: {
pre_engagement_data: formData,
from: customerFriendlyName,
},
});
console.info('Webchat Orchestrator successfully called', orchestratorResponse);

const { conversationSid, identity } = orchestratorResponse;
const { conversationSid } = conversation;
console.info(
`Created new conversation ${conversationSid} via the API with sender ID: ${senderId}`,
);

return newOk({
conversationSid: conversationSid as ConversationSID,
identity,
identity: senderId,
});
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createConversation returns { conversationSid, error? } rather than throwing on post-create failures (participants/attributes/webhooks). Here the error field is ignored, so contactWebchatOrchestrator can return Ok even when conversation setup failed, and token creation will proceed for a broken conversation. Handle the returned error (and consider removing the partially created conversation, similar to customChannelToFlex) or change createConversation to throw on failure.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
const senderId = `web:${crypto.randomUUID()}`;
console.info(`Creating new conversation via the API with sender ID: ${senderId}`);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crypto.randomUUID() is used without importing crypto. In this codebase other usages import from crypto (e.g. import crypto from 'crypto'), and relying on a global may fail depending on TS libs/runtime. Import crypto explicitly (or use an existing UUID helper) to avoid build/runtime issues.

Copilot uses AI. Check for mistakes.
stephenhand and others added 4 commits March 30, 2026 13:51
…butes.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…butes.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ibute' into CHI-3641-channel_type_convo_attribute
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants