From e094ed3d0d66381e82c3b7f4a1169e9418e6d575 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Thu, 29 Jan 2026 22:36:16 +0000 Subject: [PATCH] Move Twilio-specific parsing to twilio incoming API --- api/twilio.go | 47 ++++++++++++++++++++++++++++++++++++++-- platform/text/text.go | 50 +++++-------------------------------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/api/twilio.go b/api/twilio.go index 75f9f4f3..30d7a606 100644 --- a/api/twilio.go +++ b/api/twilio.go @@ -3,6 +3,7 @@ package api import ( "fmt" "net/http" + "strings" "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/platform/text" @@ -10,6 +11,40 @@ import ( "github.com/twilio/twilio-go/twiml" ) +// Translate from Twilio's representation of a RCS message sender to our concept of a phone number +// From: rcs:dev_report_mosquitoes_online_dosrvwxm_agent +// To: +16235525879 +func getDst(to string) (string, error) { + + if to == config.TwilioRCSSenderRMO { + return config.PhoneNumberReportStr, nil + } + /* + phone, err := models.FindCommsPhone(ctx, db.PGInstance.BobDB, to) + if err != nil { + return "", fmt.Errorf("Failed to search for dest phone %s: %w", to, err) + } + return phone.E164, nil + */ + return "", fmt.Errorf("Cannot match phone number to '%s'", to) +} + +func splitPhoneSource(s string) (string, string) { + parts := strings.Split(s, ":") + switch len(parts) { + case 0: + return "this isn't", "possible" + case 1: + return "", s + case 2: + return parts[0], parts[1] + default: + log.Warn().Str("s", s).Msg("Got an incomprehensible number of parts of a phone number") + return parts[0], parts[1] + } + +} + func twilioMessagePost(w http.ResponseWriter, r *http.Request) { message_sid := r.PostFormValue("MessageSid") log.Info().Str("sid", message_sid).Msg("Twilio Message POST") @@ -93,10 +128,18 @@ func twilioTextPost(w http.ResponseWriter, r *http.Request) { to_state := r.PostFormValue("ToState") to_zip := r.PostFormValue("ToZip") to_country := r.PostFormValue("ToCountry") - log.Info().Str("message_sid", message_sid).Str("account_sid", account_sid).Str("messaging_service_sid", messaging_service_sid).Str("from", from).Str("to_", to_).Str("body", body).Str("num_media", num_media).Str("num_segments", num_segments).Str("media_content_type0", media_content_type0).Str("media_url0", media_url0).Str("from_city", from_city).Str("from_state", from_state).Str("from_zip", from_zip).Str("from_country", from_country).Str("to_city", to_city).Str("to_state", to_state).Str("to_zip", to_zip).Str("to_country", to_country).Msg("got text") + type_, src := splitPhoneSource(from) + log.Info().Str("message_sid", message_sid).Str("account_sid", account_sid).Str("messaging_service_sid", messaging_service_sid).Str("from", from).Str("to_", to_).Str("body", body).Str("num_media", num_media).Str("num_segments", num_segments).Str("media_content_type0", media_content_type0).Str("media_url0", media_url0).Str("from_city", from_city).Str("from_state", from_state).Str("from_zip", from_zip).Str("from_country", from_country).Str("to_city", to_city).Str("to_state", to_state).Str("to_zip", to_zip).Str("to_country", to_country).Str("type_", type_).Msg("got text") twiml, _ := twiml.Messages([]twiml.Element{}) - go text.HandleTextMessage(from, to_, body) + + dst, err := getDst(to_) + if err != nil { + log.Error().Err(err).Str("to", to_).Msg("Failed to get dst") + return + } + + go text.HandleTextMessage(src, dst, body) w.Header().Set("Content-Type", "text/xml") fmt.Fprintf(w, "%s", twiml) } diff --git a/platform/text/text.go b/platform/text/text.go index b32a9583..949412e4 100644 --- a/platform/text/text.go +++ b/platform/text/text.go @@ -23,16 +23,10 @@ import ( type E164 = phonenumbers.PhoneNumber -func HandleTextMessage(from string, to string, body string) { +func HandleTextMessage(src string, dst string, body string) { ctx := context.Background() - type_, src := splitPhoneSource(from) - dst, err := getDst(ctx, to) - if err != nil { - log.Error().Err(err).Str("to", to).Msg("Failed to get dst") - return - } - _, err = insertTextLog(ctx, body, dst, src, enums.CommsTextoriginCustomer, false, true) + _, err := insertTextLog(ctx, body, dst, src, enums.CommsTextoriginCustomer, false, true) if err != nil { log.Error().Err(err).Str("dst", dst).Msg("Failed to add text message log") return @@ -74,13 +68,13 @@ func HandleTextMessage(from string, to string, body string) { } previous_messages, err := loadPreviousMessagesForLLM(ctx, dst, src) if err != nil { - log.Error().Err(err).Str("dst", dst).Str("src", from).Msg("Failed to get previous messages") + log.Error().Err(err).Str("dst", dst).Str("src", src).Msg("Failed to get previous messages") return } log.Info().Int("len", len(previous_messages)).Msg("passing") next_message, err := generateNextMessage(ctx, previous_messages, src) if err != nil { - log.Error().Err(err).Str("dst", dst).Str("src", from).Msg("Failed to generate next message") + log.Error().Err(err).Str("dst", dst).Str("src", src).Msg("Failed to generate next message") return } err = sendText(ctx, dst, src, next_message.Content, enums.CommsTextoriginLLM, false, true) @@ -88,7 +82,7 @@ func HandleTextMessage(from string, to string, body string) { log.Error().Err(err).Str("src", src).Str("dst", dst).Str("content", next_message.Content).Msg("Failed to send response text") return } - log.Info().Str("from", from).Str("from-type", type_).Str("to", to).Str("src", src).Str("dst", dst).Str("body", body).Str("reply", next_message.Content).Msg("Handled text message") + log.Info().Str("src", src).Str("dst", dst).Str("body", body).Str("reply", next_message.Content).Msg("Handled text message") } func ParsePhoneNumber(input string) (*E164, error) { @@ -217,24 +211,6 @@ func generateNextMessage(ctx context.Context, history []llm.Message, customer_ph return llm.GenerateNextMessage(ctx, history, _handle_report_status, _handle_contact_district, _handle_contact_supervisor) } -// Translate from Twilio's representation of a RCS message sender to our concept of a phone number -// From: rcs:dev_report_mosquitoes_online_dosrvwxm_agent -// To: +16235525879 -func getDst(ctx context.Context, to string) (string, error) { - - if to == config.TwilioRCSSenderRMO { - return config.PhoneNumberReportStr, nil - } - /* - phone, err := models.FindCommsPhone(ctx, db.PGInstance.BobDB, to) - if err != nil { - return "", fmt.Errorf("Failed to search for dest phone %s: %w", to, err) - } - return phone.E164, nil - */ - return "", fmt.Errorf("Cannot match phone number to '%s'", to) -} - func handleWaitingTextJobs(ctx context.Context, src string) { jobs, err := models.CommsTextJobs.Query( models.SelectWhere.CommsTextJobs.Destination.EQ(src), @@ -361,22 +337,6 @@ func sendText(ctx context.Context, source string, destination string, message st return nil } -func splitPhoneSource(s string) (string, string) { - parts := strings.Split(s, ":") - switch len(parts) { - case 0: - return "this isn't", "possible" - case 1: - return "", s - case 2: - return parts[0], parts[1] - default: - log.Warn().Str("s", s).Msg("Got an incomprehensible number of parts of a phone number") - return parts[0], parts[1] - } - -} - func setSubscribed(ctx context.Context, src string, is_subscribed bool) error { phone, err := models.FindCommsPhone(ctx, db.PGInstance.BobDB, src) if err != nil {