Skip to content

Commit 8749bb4

Browse files
fix(twilio): rename RCSSenderID to RCSSenderSID and update related validation
1 parent 3bbf8bf commit 8749bb4

File tree

5 files changed

+36
-21
lines changed

5 files changed

+36
-21
lines changed

config/config.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type Config struct {
116116

117117
MessagingServiceSID string `public:"true" info:"If set, replaces the use of From Number for SMS notifications."`
118118

119-
RCSSenderID string `info:"The sender ID for RCS messages. Required if RCS is enabled for the FromNumber or MessagingServiceSID."`
119+
RCSSenderSID string `info:"The sender SID for RCS messages. Required if RCS is enabled for the MessagingServiceSID."`
120120

121121
DisableTwoWaySMS bool `info:"Disables SMS reply codes for alert messages."`
122122
SMSCarrierLookup bool `info:"Perform carrier lookup of SMS contact methods (required for SMSFromNumberOverride). Extra charges may apply."`
@@ -510,6 +510,12 @@ func (cfg Config) Validate() error {
510510
if cfg.Twilio.MessagingServiceSID != "" {
511511
err = validate.Many(err, validate.TwilioSID("Twilio.MessagingServiceSID", "MG", cfg.Twilio.MessagingServiceSID))
512512
}
513+
if cfg.Twilio.RCSSenderSID != "" {
514+
err = validate.Many(err, validate.TwilioSID("Twilio.RCSSenderSID", "XE", cfg.Twilio.RCSSenderSID))
515+
if cfg.Twilio.MessagingServiceSID == "" {
516+
err = validate.Many(err, validation.NewFieldError("Twilio.MessagingServiceSID", "required when Twilio.RCSSenderSID is set"))
517+
}
518+
}
513519
if cfg.Mailgun.EmailDomain != "" {
514520
err = validate.Many(err, validate.Email("Mailgun.EmailDomain", "example@"+cfg.Mailgun.EmailDomain))
515521
}

graphql2/mapconfig.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

notification/store.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"encoding/binary"
88
"fmt"
99
"math/rand"
10+
"strings"
1011
"time"
1112

13+
"github.com/target/goalert/config"
1214
"github.com/target/goalert/gadb"
1315
"github.com/target/goalert/permission"
1416
"github.com/target/goalert/search"
@@ -136,10 +138,12 @@ func (s *Store) OriginalMessageStatus(ctx context.Context, alertID int, dstID De
136138
return nil, err
137139
}
138140

139-
return outgoingMessageToSendResult(row.OutgoingMessage, row.CmDest, row.ChDest)
141+
return outgoingMessageToSendResult(ctx, row.OutgoingMessage, row.CmDest, row.ChDest)
140142
}
141143

142-
func outgoingMessageToSendResult(msg gadb.OutgoingMessage, cm, ch gadb.NullDestV1) (*SendResult, error) {
144+
func outgoingMessageToSendResult(ctx context.Context, msg gadb.OutgoingMessage, cm, ch gadb.NullDestV1) (*SendResult, error) {
145+
cfg := config.FromContext(ctx)
146+
143147
res := SendResult{
144148
ID: msg.ID.String(),
145149
ProviderMessageID: msg.ProviderMsgID,
@@ -157,11 +161,19 @@ func outgoingMessageToSendResult(msg gadb.OutgoingMessage, cm, ch gadb.NullDestV
157161
return nil, err
158162
}
159163

164+
srcValue := msg.SrcValue.String
165+
if cm.DestV1.Type == "builtin-twilio-sms" && strings.HasPrefix(srcValue, "rcs:") {
166+
// Hack: Twilio currently has no way to fetch the Display Name of the RCS sender, so we use the application name as a fallback.
167+
//
168+
// In the future, we can use the RCSSenderSID to fetch the actual display name.
169+
srcValue = cfg.ApplicationName()
170+
}
171+
160172
res.Status = Status{
161173
State: state,
162174
Details: msg.StatusDetails,
163175
Sequence: int(msg.ProviderSeq),
164-
SrcValue: msg.SrcValue.String,
176+
SrcValue: srcValue,
165177
}
166178
if msg.LastStatusAt.Valid {
167179
res.Status.Age = msg.LastStatusAt.Time.Sub(msg.CreatedAt)
@@ -381,7 +393,7 @@ func (s *Store) FindManyMessageStatuses(ctx context.Context, strIDs []string) ([
381393

382394
var result []SendResult
383395
for _, r := range rows {
384-
res, err := outgoingMessageToSendResult(r.OutgoingMessage, r.CmDest, r.ChDest)
396+
res, err := outgoingMessageToSendResult(ctx, r.OutgoingMessage, r.CmDest, r.ChDest)
385397
if err != nil {
386398
return nil, err
387399
}
@@ -416,7 +428,7 @@ func (s *Store) LastMessageStatus(ctx context.Context, typ gadb.EnumOutgoingMess
416428
return nil, time.Time{}, err
417429
}
418430

419-
sendRes, err := outgoingMessageToSendResult(row.OutgoingMessage, row.CmDest, row.ChDest)
431+
sendRes, err := outgoingMessageToSendResult(ctx, row.OutgoingMessage, row.CmDest, row.ChDest)
420432
if err != nil {
421433
return nil, time.Time{}, err
422434
}

notification/twilio/sms.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,17 @@ func (s *SMS) ServeStatusCallback(w http.ResponseWriter, req *http.Request) {
168168
return
169169
}
170170
ctx := req.Context()
171-
cfg := config.FromContext(ctx)
172171
status := MessageStatus(req.FormValue("MessageStatus"))
173172
sid := validSID(req.FormValue("MessageSid"))
174-
var number string
175-
if cfg.Twilio.RCSSenderID != "" && req.FormValue("From") == "rcs:"+cfg.Twilio.RCSSenderID {
176-
number = req.FormValue("To")
177-
} else {
178-
number = validPhone(req.FormValue("To"))
179-
}
180-
if status == "" || sid == "" || number == "" {
173+
if status == "" || sid == "" {
181174
http.Error(w, "", http.StatusBadRequest)
182175
return
183176
}
184177

185178
ctx = log.WithFields(ctx, log.Fields{
186179
"Status": status,
187180
"SID": sid,
188-
"Phone": number,
181+
"Phone": req.FormValue("To"),
189182
"Type": "TwilioSMS",
190183
})
191184
msg := Message{SID: sid, Status: status, From: strings.TrimPrefix(req.FormValue("From"), "rcs:")}
@@ -228,8 +221,12 @@ func (s *SMS) ServeMessage(w http.ResponseWriter, req *http.Request) {
228221
ctx := req.Context()
229222
cfg := config.FromContext(ctx)
230223
from := validPhone(strings.TrimPrefix(req.FormValue("From"), "rcs:"))
231-
if from == "" || from == cfg.Twilio.FromNumber || from == cfg.Twilio.RCSSenderID {
232-
http.Error(w, "", http.StatusBadRequest)
224+
if from == cfg.Twilio.FromNumber || req.FormValue("From") == req.FormValue("To") {
225+
http.Error(w, "ignoring message loop", http.StatusBadRequest)
226+
return
227+
}
228+
if from == "" {
229+
http.Error(w, "invalid from number", http.StatusBadRequest)
233230
return
234231
}
235232

web/src/schema.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1652,7 +1652,7 @@ type ConfigID =
16521652
| 'Twilio.AlternateAuthToken'
16531653
| 'Twilio.FromNumber'
16541654
| 'Twilio.MessagingServiceSID'
1655-
| 'Twilio.RCSSenderID'
1655+
| 'Twilio.RCSSenderSID'
16561656
| 'Twilio.DisableTwoWaySMS'
16571657
| 'Twilio.SMSCarrierLookup'
16581658
| 'Twilio.SMSFromNumberOverride'

0 commit comments

Comments
 (0)