Try   HackMD

TRD Email Statuses

This document contains Technical Requirements Documentation (TRD) for Conquer Development: Email Statuses. The TRD contains information related to specification on now we are building the feature and any technical consideration. It is intended for INTERNAL USE ONLY. The contents in the document may be used as reference for Marketing, Support, Sales, and Customer Success.

tags: TRD template

Description

Currently we have no way for failed emails to report back out to Cadence. We need to get out reporting for when

Planning

Overview

Sprints
Initiative
Epics
Project Lead @williamcook
Developers @doua Yang, @anthonykelly, @shannontighe, @3DduwQvjSqufZtizspE5tg

Sprint Planning

Developer Sprints

Services

Affected Services

Email Service

Overview
Service Name Email Service
Description Email service needs updated to send error statuses to Cadence
Justification Allows for reporting errors back to Cadence
Ports N/A
External Access Method N/A
Required Environment Vairables

None

Skyring Proxy Service

Overview
Service Name Skyring Proxy
Description New endpoint to retry a timer (makes RPC to Go Data API)
Justification Allows for reporting and retrying (automated only)
Ports 443
External Access Method REST
Required Environment Vairables

None

Go Data API timers Service

Overview
Service Name Go Data Api
Description New RPC to retry a timer (called from skyring proxy)
Justification Allows for reporting and retrying (automated only)
Ports 50052
External Access Method gRPC
Required Environment Vairables

None

Concepts

Types of Email Error Messages logged into SFDC

The goal here is just to obfuscate the more technical error messages that may come out of the email service and feed them back to the agent as a more useful type of error. We may want to build an error translator of some sort to convert known error messages into these categorical error types.

  • Transient Error: Indicates an error we expect will be resolved by re-queueing this message in a few minutes
  • Fatal Error: Indicates an error that cannot be resolved by re-queueing this message
  • Fatal Authentication Error: Auth is sideways, and the user needs to re-authenticate before attempting to send this message again
  • Fatal Permissions Error: User may need to obtain assistance from their internal IT department in order to get auth working again (We’ve seen things like getting a new computer or the user account becoming disabled cause this type of problem)
  • Conquer Support Required: Indicates this user needs to contact the Conquer Support team
    Perhaps we standardize a set of error codes that can be passed along to the Support team. This could be for scenarios that are unmatched with known errors, and the Dev/Support teams should work together to figure out the cause.

Status

The status on the email represents the current state of the email touchpoint. Status is initially written by the package and then updated by events from the email_service to the package.

  • Scheduled
    A status of Scheduled indicates an automated email is due to be sent at some date in the future. Scheduled is written on creation of the touchpoint by the package for automated emails only.

  • Pending Manual Send
    A status of Pending Manual Send indicates a manual email is pending completion from a user. Pending Manual Send is written by the package on touchpoint creation for manual emails only

  • Rate Limited
    A status of Rate Limited indicates an email has been attempted to be sent but the salesforce users email account is currently unable to send emails due to a rate limit. The status of Rate Limited is written by the package when the email service sends an event to the package indicating the email user has been rate limited

  • Sent
    A status of Sent means the email has been successfully sent. The Status of sent is written by the package when it receives an event from the email service indicating the email has been sent.

  • Error
    A status of Error indicates the email has failed to send with an error other than a rate limit. The status of Error is written by the package when the package receives an event from the email service indicating the email has failed with error.

  • Manual Retry
    A status of Manual Retry indicates the email had previously failed with Error and the user attempted to resend the email. Manual Retry is written by the package when a user attempts to resend an email.

Schemas

Postgres

Timers.timers - new columns

Column Type Primary Key Default Constraints Foreign Key Description
previous_deleted_at timestamp NULL Represents last time email timer was soft deleted
previous_executed_at timestamp NULL Represents last time email timer was executed
previous_error timestamp NULL Previous error on email attempt
previous_served_at timestamp NULL Represents last time email timer was served
retry_count INTEGER 0 Represents how many times the email timer was retried

Salesforce

New Object

Touchpoint - Parent Object

Key Type Description
Action Status Unrestricted Picklist Represents the status of the email. Initial picklist values are Scheduled, Pending Manual Send, Rate Limited, Sent, Error
Error Message TEXT AREA (5000 Max) If there was an error sending the email, it represents the error on the email sending process.
Error Message (Truncated) TEXT (255) Truncated error message
Error Code TEXT (255) Helps with determining the cause of the error, not always present from email service when error occurs
Manual Retry Count INTEGER Represents how many times the email was retried
Status Last Updated Datetime Represents the datetime of email status last updated

Conquer Error - Child Object

Column Type Description
ID Object ID Conquer Error ID
Error Message TEXT AREA (5000 Max) Captures any error related to parent Touchpoint (related to email send, sms, etc)
Error Message (Truncated) TEXT (255) Truncated error message
Error Code TEXT (255) Helps with determining the cause of the error, not always present from email service when error occurs
Status Unrestricted Picklist Represents the status of the email. Initial picklist values are Scheduled, Pending Manual Send, Rate Limited, Sent, Error
Touchpoint ID Lookup (Conquer Error >> Touchpoint) Relationship field connecting Conquer Error to Touchpoint. Conquer Error == child Touchpoint == parent
Cadence Member Lookup (Conquer Error >> Cadence Member) Relationship field connecting Conquer Error to Cadence Member. Conquer Error == child Cadence Member == parent
Email Message Lookup (Conquer Error >>Email Message) Relationship field connecting Conquer Error to Email Message. Conquer Error == child Email Message == parent. Doua doesn't see the need for this

Error Code Guide

  • 31: InternalError
  • 32: TooManyAttemptsError
  • 33: DraftNetworkError
  • 34: SendError
  • 40: UpdateDraftNetworkError
  • 50: TransientError
  • 51: FatalAuthenticationError
  • 52: FatalPermissionError
  • 53: FatalErrorNoProvider

Service Diagram

Happy Path

BackendSalesforceBackendSalesforceHTTP POST https://in.dialsource.com/timers/salesforce/create/sendEmail200 OKDialSourceCadenceServices email sent200 OK

Rate Limited (3x) With Eventual Send

Email ServiceSalesforceEmail ServiceSalesforceHTTP POST https://in.dialsource.com/timers/salesforce/create/sendEmail200 OKDialSourceCadenceServices Rate Limited - No error message200 OKRetryRetryRetryDialSourceCadenceServices email sent200 OK

Rate Limited then Error then Retry then Rate Limited then Sent

Timers Data APIEmail ServiceSkyring ProxySalesforceTimers Data APIEmail ServiceSkyring ProxySalesforceHTTP POST https://in.dialsource.com/timers/salesforce/create/sendEmail (automated process)200 OKDialSourceCadenceServices Rate Limited - No error message200 OKRetryDialsourceCadenceServices email error with error message200 OKHTTP POST https://in.dialsource.com/timers/salesforce/retry/sendEmailRetrytimer RPCOKOKDialsourceCadenceService rate limited - no error messageOKRetryDialSourceCadenceServices email sent200 OK

Service Implementation Details

The initial status of email touchpoints will be written on creation by the package. Automated emails will be created with a status of Scheduled while manual email sends will be created with a status of Pending Manual Send.

As the email progresses, the status will be updated when the email_service sends REST requests to the package with events indicating the Status on the Touchpoint needs to be updated. This includes Status of Rate Limited, Sent, and Error. This is new functionality in the email service.

If the user attempts to retry a failed automated email, the package will log a Status of Manual Retry on the Action Status of the Touchpoint.

Manual emails are unable to be reattempted.

Current way we are writing to Error Message needs to be refactored to use a new Child Error object.

The child error object will only be created for Status of Rate Limited, Error, or Manual Retry while the Touchpoint object will directly hold Scheduled, Pending Manual Send, and Sent.

Rate Limited emails will continue to be reattempted by the email service if the system is working properly. Error will not be retried by the system and should now give the user to trigger a Manual Retry IF the email was an automated Email, otherwise only an error message should be displayed and the rep can manually re-complete the Touchpoint.

The Touchpoint should always wipe Error Message, Status Last Updated, and Action Status between each new child object and status change. When the state transitions to Manual Retry the Manual Retry Count on the Touchpoint should be incremented by one.

A final status of Sent therefore should have an Action Status of Sent, a blank Error Message / Truncated Error Message, up to X retry count, and the status last updated should represent when the object changed to “Sent”.

To log a new error message the new endpoints should be used to log corresponding statuses

To perform a Manual Retry of an automated email from SF->Timers the user should have to use the “Retry button” in Cadence utilities and Cadence actions and post to the endpoint “Retry Timer”. When a Manual Retry returns a successful HTTP post the Package should log a new Manual Retry child object and corresponding Touchpoint fields. If a 400 error code is returned a toast message should be displayed to the end user using the “error_message” returned as the text of the toast.

When a timer is being retried deleted_at, executed_at, error, and served_at should be NULL and their old values should be written to the same row with columns “previous_deleted_at”, “previous_executed_at”, “previous_error”, “previous_served_at”. “retry_count” Should be incremented 1. These are new columns on the timers db (noted in schema above).

To perform a Retry of a manual email in SFDC the rep needs to manually re-attempt the email as they normally would, even if an error message is there. They will need to redo the entire email.

Environment Handling

This is handled by existing systems - nothing new needed.

Endpoints

REST Endpoints

Skyring Proxy

  • https://in.dialsource.com/timers/salesforce/retry/sendEmail
    This endpoint will be hit by the package when a user attempts to retry a failed automated email. It is responsible for making a RPC call to the RetryTimer RPC on Go Data API Timers to reattempt the timer. On error, return a status code of 400 with “error_message” on the body.
    ​​​​// POST Request
    ​​​​{
    ​​​​      "aid": "18 DIGIT AID",
    ​​​​      "touchpoint_id": "18 DIGIT TOUCHPOINT ID"
    ​​​​}
    
    ​​​​// Response on 200
    ​​​​{}
    
    ​​​​//Response on 400
    ​​​​{
    ​​​​    "error_message": "error message"
    ​​​​}
    

Package Endpoint

  • https://instance_url.salesforce.com/services/apexrest/DS_Packages/DialSourceCadenceServices

    When DialSourceCadenceServices receives a POST with an event of email_{Status}, the package will update the Touchpoint and/or Conquer Error object depending on the Status. Actions performed by the package will be dependent on the event on the request.

    • email_sent
      No new information will be added on the request for email_sent events. The package will be responsible for updating the status and error fields if applicable on the Touchpoint.
    • email_error
      On email_error, the email service will send a new field called error_message. The package will use the error_message and event (email status) to update the Touchpoint with the new Action Status and create the Conquer Error child object with the error_message.
    • email_rate_limited
      On an event of, email_rate_limited, the package will need to create a new Conquer Error child object and update the status of the touchpoint. No new information will be added on the request for email_rate_limited events
      Have the package check and make sure this email hasn't already been set to sent so we don't process an older error message. An email should not regress from sent.
    ​​​​// POST Request
    ​​​​{
    ​​​​    "event": "email_{error, rate_limited}", 
    ​​​​    "touchpoint_id": "a00XXXXXXXXXXXXXXX",
    ​​​​    "error_message": "error string"
    ​​​​}
    

Go Data Api Timers

RetryTimer

// TimerType types of timers
Enum TimerType {
	string TimerTypeUndefined = 0;
	string TimerType AutomatedEmail = 1;
    string TimerTypeDecisionPoint = 2;
}

// RetryTimerRequest attempts to retry a timer. Currently only supports TimerTypes of AutomatedEmail
// TimerID will be constructed from the touchpoint_id and aid in the form of cadence-autoemail-{aid}-{touchpoint_id}
// On retry, deleted_at, executed_at, served_at, and error will be cleared with NULL and the previous values will be written to previous_deleted_at, previous_executed_at, previous_served_at, and previous_error respectively.
// Additionally retry_count will be incremented by one. 
Message RetryTimerRequest {
	string aid = 1;
	string Touchpoint_id = 2;
	TimerType timer_type = 3;
} 

// MessageRetryTimerResponse
Message RetryTimerResponse {}

Include an overview and implentation details for the endpoint here

// NewRpcRequest include comments for the request object. 
message NewRpcRequest {
    string key1
    int32 key2 // required if key1 = "test"
}

// NewRpcResponse include comments for the response objects. 
// Detail possible returned errors here
message NewRpcResponse {}

// NewRpc include details relevant to the client here 
rpc NewRpc (NewRpcRequest) returns (NewRpcResponse) {}

Mocks

Adobe XD Mocks - Missing Resend Email Button

Security Concerns

None to date

Questions

Question Answer

Sign Off

Reviewer Approval
Doua Yang Yes