Add ability to delay text message sending
This commit is contained in:
parent
ab105e16e8
commit
adc99e8871
24 changed files with 2028 additions and 28 deletions
|
|
@ -10,14 +10,21 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/config"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/nyaruka/phonenumbers"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/stephenafamo/bob/types/pgtypes"
|
||||
)
|
||||
|
||||
func StoreSources() error {
|
||||
ctx := context.TODO()
|
||||
src := phonenumbers.Format(&config.PhoneNumberReport, phonenumbers.E164)
|
||||
return ensureInDB(ctx, src)
|
||||
}
|
||||
func convertToPGData(data map[string]string) pgtypes.HStore {
|
||||
result := pgtypes.HStore{}
|
||||
for k, v := range data {
|
||||
|
|
@ -26,6 +33,21 @@ func convertToPGData(data map[string]string) pgtypes.HStore {
|
|||
return result
|
||||
}
|
||||
|
||||
func delayMessage(ctx context.Context, source string, destination string, content string, type_ enums.CommsTextjobtype) error {
|
||||
job, err := models.CommsTextJobs.Insert(&models.CommsTextJobSetter{
|
||||
Content: omit.From(content),
|
||||
Created: omit.From(time.Now()),
|
||||
Destination: omit.From(destination),
|
||||
//ID:
|
||||
Type: omit.From(type_),
|
||||
}).One(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to add delayed text job: %w", err)
|
||||
}
|
||||
log.Info().Int32("id", job.ID).Msg("Created delayed text job")
|
||||
return nil
|
||||
}
|
||||
|
||||
func ensureInDB(ctx context.Context, destination string) (err error) {
|
||||
_, err = models.FindCommsPhone(ctx, db.PGInstance.BobDB, destination)
|
||||
if err != nil {
|
||||
|
|
@ -58,6 +80,17 @@ func insertTextLog(ctx context.Context, content string, destination string, sour
|
|||
|
||||
return err
|
||||
}
|
||||
func isSubscribed(ctx context.Context, destination string) (bool, error) {
|
||||
phone, err := models.FindCommsPhone(ctx, db.PGInstance.BobDB, destination)
|
||||
if err != nil {
|
||||
if err.Error() == "sql: no rows in result set" {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to find phone number %s: %w", destination, err)
|
||||
}
|
||||
return phone.IsSubscribed, nil
|
||||
}
|
||||
|
||||
func generatePublicId(t enums.CommsMessagetypeemail, m map[string]string) string {
|
||||
if m == nil || len(m) == 0 {
|
||||
// Return hash of empty string for empty maps
|
||||
|
|
|
|||
31
comms/text/initial.go
Normal file
31
comms/text/initial.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package text
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db/models"
|
||||
)
|
||||
|
||||
func ensureInitialText(ctx context.Context, src string, dst string) error {
|
||||
//
|
||||
origin := enums.CommsTextoriginWebsiteAction
|
||||
rows, err := models.CommsTextLogs.Query(
|
||||
models.SelectWhere.CommsTextLogs.Destination.EQ(dst),
|
||||
models.SelectWhere.CommsTextLogs.IsWelcome.EQ(true),
|
||||
).All(ctx, db.PGInstance.BobDB)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to query text logs: %w", err)
|
||||
}
|
||||
if len(rows) > 0 {
|
||||
return nil
|
||||
}
|
||||
content := "Welcome to Report Mosquitoes Online. We received your request and want to confirm text updates. Reply YES to continue. Reply STOP at any time to unsubscribe"
|
||||
err = sendText(ctx, src, dst, content, origin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to send initial confirmation: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -48,9 +48,24 @@ func sendReportSubscription(ctx context.Context, job Job) error {
|
|||
return fmt.Errorf("job is not for report subscription confirmation")
|
||||
}
|
||||
|
||||
err := sendText(ctx, j.src, j.dst, j.content(), enums.CommsTextoriginWebsiteAction)
|
||||
sub, err := isSubscribed(ctx, job.destination())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to send report subscription confirmation: %w", err)
|
||||
return fmt.Errorf("Failed to check if subscribed: %w", err)
|
||||
}
|
||||
if !sub {
|
||||
err = sendText(ctx, j.source(), j.destination(), j.content(), enums.CommsTextoriginWebsiteAction)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to send report subscription confirmation: %w", err)
|
||||
}
|
||||
} else {
|
||||
err = delayMessage(ctx, j.source(), j.destination(), j.content(), enums.CommsTextjobtypeReportConfirmation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to delay report subscription message: %w", err)
|
||||
}
|
||||
err := ensureInitialText(ctx, j.source(), j.destination())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to ensure initial text has been sent: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@ func ParsePhoneNumber(input string) (*E164, error) {
|
|||
return phonenumbers.Parse(input, "US")
|
||||
}
|
||||
|
||||
func sendText(ctx context.Context, source E164, destination E164, message string, origin enums.CommsTextorigin) error {
|
||||
src := phonenumbers.Format(&source, phonenumbers.E164)
|
||||
dest := phonenumbers.Format(&destination, phonenumbers.E164)
|
||||
err := ensureInDB(ctx, dest)
|
||||
func sendText(ctx context.Context, source string, destination string, message string, origin enums.CommsTextorigin) error {
|
||||
err := ensureInDB(ctx, destination)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to ensure text message destination is in the DB: %w", err)
|
||||
}
|
||||
err = insertTextLog(ctx, message, dest, src, origin)
|
||||
err = insertTextLog(ctx, message, destination, source, origin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to insert text message in the DB: %w", err)
|
||||
}
|
||||
|
|
@ -36,16 +34,16 @@ func sendText(ctx context.Context, source E164, destination E164, message string
|
|||
params.SetMessagingServiceSid(config.TwilioMessagingServiceSID)
|
||||
|
||||
params.SetBody(message)
|
||||
params.SetTo(dest)
|
||||
params.SetTo(destination)
|
||||
resp, err := client.Api.CreateMessage(params)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create message to %s: %w", dest, err)
|
||||
return fmt.Errorf("Failed to create message to %s: %w", destination, err)
|
||||
} else {
|
||||
if resp.Body != nil {
|
||||
log.Info().Str("dest", dest).Str("body", *resp.Body).Msg("Text message response")
|
||||
log.Info().Str("dest", destination).Str("body", *resp.Body).Msg("Text message response")
|
||||
} else {
|
||||
log.Info().Str("dest", dest).Msg("Text message response is nil")
|
||||
log.Info().Str("dest", destination).Msg("Text message response is nil")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue