Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow users to add auto reply triggers #1664

Open
wants to merge 15 commits into
base: feat-auto-reply-handling
Choose a base branch
from

Conversation

ajohn25
Copy link
Contributor

@ajohn25 ajohn25 commented Aug 12, 2023

Description

This PR allows admins to add auto reply triggers when editing a campaign. It also adds logic for marking contacts ineligible for auto replies, when a message is sent to them from Message Review

Motivation and Context

Closes #1663

How Has This Been Tested?

This has been tested locally:

  • Auto reply triggers are copied when copying a campaign
  • Setting up multiple interaction steps on the same level of the tree with the same auto reply token fails on save with a friendly error
  • Auto reply eligilble conversations do not appear in Texter Todos
  • Sending from Message Review marks the conversation as ineligible and drops retry jobs
  • Pasting multiple words separated by commas automatically creates separate tokens

Screenshots (if appropriate):

image

Documentation Changes

Checklist:

  • My change requires a change to the documentation.
  • I have included updates for the documentation accordingly.

@ajohn25
Copy link
Contributor Author

ajohn25 commented Aug 12, 2023

This is ready for review! See notes about failing test in #1663

@ajohn25 ajohn25 marked this pull request as ready for review August 12, 2023 14:55
Copy link
Member

@bchrobot bchrobot left a comment

Choose a reason for hiding this comment

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

Comments/suggestions inline!

Still needs a schema-dump.sql update

@@ -25,5 +25,20 @@ export const schema = `
createdAt: Date
interactionSteps: [InteractionStepInput]
}

type InteractionStepWithChildren {
Copy link
Member

Choose a reason for hiding this comment

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

Question: is this necessary in the GraphQL schema? It looks like it is only being used for TypeScript typing. And the children are already captured in the interactionSteps array property.


return (
<div>
<br />
Copy link
Member

Choose a reason for hiding this comment

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

Required: remove this -- styling should be done with CSS not <br>'s

return;
}
switch (event.key) {
/* eslint-disable no-case-declarations */
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: prefer an empty no-op default

onChange={handleChange}
onInputChange={handleInputChange}
onKeyDown={handleKeyDown}
onPas
Copy link
Member

Choose a reason for hiding this comment

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

Question: intentional onPas prop?

return (
<div>
<br />
Auto Replies
Copy link
Member

Choose a reason for hiding this comment

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

Question: should the label be part of the field itself? Or added where the field is used? I think separating form inputs from labels is the right way to do it but can't remember what Spoke conventions are (and would rather be consistent with conventions).

});
const autoReplyCount = parseInt(rowCount, 10);

if (handleOptOut || Number.isNaN(autoReplyCount) || autoReplyCount === 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: use variable to improve clarity

Suggested change
if (handleOptOut || Number.isNaN(autoReplyCount) || autoReplyCount === 0) {
const hasNoAutoReplies = Number.isNaN(autoReplyCount) || autoReplyCount === 0;
if (handleOptOut || hasNoAutoReplies) {

});
}

await updateQuery;
Copy link
Member

Choose a reason for hiding this comment

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

Question: execution of this query was moved inside an if block -- intentional?

Comment on lines +62 to +68
await assignContacts(client, assignment.id, campaign.id, 1);
await createMessage(client, {
assignmentId: assignment.id,
campaignContactId: contact.id,
contactNumber: contact.cell,
text: "Hi! Want to attend my cool event?"
});
Copy link
Member

Choose a reason for hiding this comment

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

nit: mirror actual flow and assign contact and send message after campaign creation (interaction steps and auto-reply triggers)


test("does not respond to a contact who says YES! with no auto reply configured for the campaign", async () => {
const testbed = await withClient(pool, async (client) => {
return createTestBed(client, agent);
Copy link
Member

Choose a reason for hiding this comment

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

Question: doesn't createTestBed() configure a yes auto reply token for the campaign?

);

const msgCount = parseInt(msgs.count, 10);
expect(msgCount).toBe(2);
Copy link
Member

Choose a reason for hiding this comment

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

Question: should this also check retry-interaction-step jobs?

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.

2 participants