Skip to content

CHI-3946-quick_dial_with_config - #4622

Open
stephenhand wants to merge 70 commits into
CHI-3946-quick_dialfrom
CHI-3946-quick_dial_with_config
Open

CHI-3946-quick_dial_with_config#4622
stephenhand wants to merge 70 commits into
CHI-3946-quick_dialfrom
CHI-3946-quick_dial_with_config

Conversation

@stephenhand

@stephenhand stephenhand commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR moves the quick dial UI over from dummy hardcoded values to using the private config endpoint set up in copilot/add_private_configuration_endpoint (those changes are included inthis PR)

  • It adds a client to retrieve this, including support for GET requests to account-scoped lambda
  • Adds loading private config into redux
  • Adds looking up the quick dial options from state for thge UI

Checklist

  • Corresponding issue has been opened
  • New tests added
  • Feature flags added
  • Strings are localized
  • Tested for chat contacts
  • Tested for call contacts

Other Related Issues

None

Verification steps

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

stephenhand and others added 30 commits July 15, 2026 14:37
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
…nt/AsyncIterable pattern

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
- Add SMS channel to twilio-iac/helplines/e2e/development.hcl using the
  messaging-lex-v3-blocking-lambda.tftpl template (same as aselo_webchat)
  and an empty contact_identity (conversations address managed separately)
- Create twilio-iac/helplines/e2e/files/additional.configure.tf that uses
  a Twilio data source to look up the only phone number attached to the
  account at apply time and creates the SMS conversations address linked to
  the SMS studio flow
- Guard twilio_conversations_configuration_addresses_v1 in channels/v1/main.tf
  so channels with an empty contact_identity skip automatic address creation
  (allowing helpline-specific additional.tf to manage it instead)

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
- Replace dynamic phone number lookup with hardcoded +12607821891 in both development.hcl and additional.configure.tf
- Remove data source that previously scraped the phone number from the Twilio account
- Set contact_identity to the hardcoded phone number in the SMS channel configuration

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
The twilio-iac/terraform-modules/channels/v1/main.tf module now
automatically creates the SMS conversations address since
contact_identity is no longer empty. The separate additional.configure.tf
file is no longer needed.

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
- Add voice channel using voice-no-chatbot-operating-hours-blocking-lambda template
- Use the same phone number (+12607821891) as the SMS channel
- Include voice_ivr_greeting_message, voice_ivr_blocked_message, and voice_ivr_language
- Follows established patterns used in other helplines for voice configurations

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
…nt/AsyncIterable pattern

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
- Add SMS channel to twilio-iac/helplines/e2e/development.hcl using the
  messaging-lex-v3-blocking-lambda.tftpl template (same as aselo_webchat)
  and an empty contact_identity (conversations address managed separately)
- Create twilio-iac/helplines/e2e/files/additional.configure.tf that uses
  a Twilio data source to look up the only phone number attached to the
  account at apply time and creates the SMS conversations address linked to
  the SMS studio flow
- Guard twilio_conversations_configuration_addresses_v1 in channels/v1/main.tf
  so channels with an empty contact_identity skip automatic address creation
  (allowing helpline-specific additional.tf to manage it instead)

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>
Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 migrates the Quick Dial UI from hardcoded/dummy options to options sourced from an account-scoped “private configuration” endpoint, then loads that configuration into the Flex plugin Redux state for UI consumption.

Changes:

  • Added an account-scoped lambda route/handler (and unit tests) to return Twilio “private” configuration from S3.
  • Added client-side service + Redux async action/reducer logic to load private Twilio configuration into state.
  • Added a selector to read quickDialOptions from Redux for the UI.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
plugin-hrm-form/src/states/configuration/selectQuickDialOptions.ts Adds selector to read quickDialOptions from Redux state.
plugin-hrm-form/src/states/configuration/reducer.ts Extends configuration state to include twilioPrivateConfiguration and wires in the loader reducer.
plugin-hrm-form/src/states/configuration/loadPrivateTwilioConfig.ts Adds async action + reducer to fetch/store private Twilio configuration.
plugin-hrm-form/src/services/fetchProtectedApi.ts Adds account-scoped GET helper and improves error wrapping for protected API calls.
plugin-hrm-form/src/services/configurationService.ts Adds service wrapper to fetch the private Twilio configuration from account-scoped lambda.
plugin-hrm-form/src/HrmFormPlugin.tsx Dispatches private configuration load during plugin initialization.
lambdas/account-scoped/tests/unit/configuration/getTwilioPrivateConfiguration.test.ts Adds unit tests for the new private configuration handler.
lambdas/account-scoped/src/router.ts Registers the new account-scoped configuration/twilioPrivate route.
lambdas/account-scoped/src/configuration/getTwilioPrivateConfiguration.ts Implements handler that reads/parses twilio-private.json from S3.
lambdas/account-scoped/package.json Adds @tech-matters/s3 dependency for S3 reads in the lambda.
Suppressed comments (1)

plugin-hrm-form/src/services/configurationService.ts:23

  • getPrivateTwilioConfiguration uses getFromAccountScopedLambda (GET), but the account-scoped router protects this endpoint with validateFlexTokenRequest which currently only accepts Token from the request body. As written, this call will be rejected as missing Token.
export const getPrivateTwilioConfiguration = async (): Promise<ConfigurationState['twilioPrivateConfiguration']> =>
  getFromAccountScopedLambda(`configuration/twilioPrivate`);

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread lambdas/account-scoped/src/router.ts Outdated
Comment thread plugin-hrm-form/src/services/fetchProtectedApi.ts Outdated
Comment thread plugin-hrm-form/src/services/configurationService.ts
Comment thread plugin-hrm-form/src/HrmFormPlugin.tsx
@stephenhand
stephenhand marked this pull request as draft August 18, 2026 07:48
@stephenhand

Copy link
Copy Markdown
Collaborator Author

@copilot - fix the failing unit tests and add unit tests for all new / changed code in this PR except for react components

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

@copilot - fix the failing unit tests and add unit tests for all new / changed code in this PR except for react components

Addressed in commit 280419c. I fixed the failing configuration reducer unit expectations and added unit tests for the new/changed non-React quick-dial configuration code paths (configuration service, account-scoped lambda fetch helper, quick-dial selector, async configuration reducer behavior, and flex token header/body validation).

@stephenhand

Copy link
Copy Markdown
Collaborator Author

@copilot One unit test is still failing

Co-authored-by: stephenhand <1694716+stephenhand@users.noreply.github.com>

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

@copilot One unit test is still failing

Fixed in commit 61eed07. I updated the remaining failing unit test expectation in fetchProtectedApi.test.ts to account for the Authorization header now sent by fetchProtectedApi.

@stephenhand
stephenhand marked this pull request as ready for review August 18, 2026 14:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

plugin-hrm-form/src/services/fetchProtectedApi.ts:69

  • fetchOptions is spread after the headers object, so if a caller passes fetchOptions.headers, it will overwrite the entire headers object and silently drop the Authorization / Content-Type headers. This can break auth (and is easy to miss because tests don’t cover the overriding case).
      'Content-Type': contentType,
      ...fetchOptions?.headers,
    },
    ...fetchOptions,
  };

plugin-hrm-form/src/states/configuration/loadAseloTwilioConfiguration.ts:42

  • The fulfilled reducer stores the remote JSON payload directly into Redux without whitelisting/validation. Since this data comes from S3 (arbitrary JSON), unexpected keys will be persisted client-side and a malformed quickDialOptions value (e.g. non-array) can later crash the UI when it’s mapped. Prefer projecting the payload into the expected shape before storing it.
      (state, { payload }): ConfigurationState => {
        return {
          ...state,
          aseloTwilioConfiguration: payload,
        };

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