[#105] Resolve "respond to sms messages"
Closes #105 (closed)
Context:
- we would like to provide fallback SMS messages to new users to try to send "HELLO" (or the like) to signalboost numbers b/c they don't understand or yet have signal
- but we also don't want to open signalboost up to a resource starvation attack from a malicious user who floods us with text messages we can't pay to respond to
- this MR provides a method for responding to SMS messages only for users who have not exceeded a quota of 3 inbound messages (which is reset every month)
Changes
Foundation
-
add a
smsSenders
table- use it to track who sent incoming messages and when
-
add an
smsSenderRepository
-
#countMessage
increments themessagesSent
count of ansmsSender
-
#hasReachedQuota
checks whether a sender has reached their quota of responses (currently 3/month) -
#deleteExpired
deletes all records older than a month (to preserve privacy of sms senders and allow quotas to reset)
-
-
add
language
module- extract constants for supported languages from
app.constants
to here -
#languageForPhoneNumber
leverages newlibphonenumber-js
dependency to parse the country code from a phone number, and use that to infer the (most likely) language spoken by the sms sender (via country -> language mapping provided inlanguageForCountry
)
- extract constants for supported languages from
Interface
-
to handle incoming messages:
- add
registrar.sms
module, use it to expose#handleSms
to the/twilioSms
route, which:- tries to parse a signal verification code from a message, and if successful, dispatches to verification flow in
registrar.register.verify
- if message is not a verification code, it:
- use
smsRepository.hasReachedQuota
to see if we should respond - if so, use
languages.languageForPhoneNumber
to generate localized response to wrap in a TWIML message (where TWIML is twilio-flavored XML -- a thing we can respond to twilio callbacks with to get it to send sms's with arbitrary content)
- use
- tries to parse a signal verification code from a message, and if successful, dispatches to verification flow in
- add
-
for record scrubbing:
- call `` from the main loop in
registrar.run
- since this runs roughly every 24 hours after db database backup restarts the app, we have a loose guarantee that sms sender records older than 1 month will be deleted every day
- call `` from the main loop in