mirror of
https://github.com/PrivateCaptcha/PrivateCaptcha.git
synced 2026-05-14 08:59:23 -05:00
Attempt to guess first name for welcome email
This commit is contained in:
@@ -5,6 +5,7 @@ import "net/http"
|
||||
const (
|
||||
DefaultOrgName = "My Organization"
|
||||
PrivateCaptcha = "Private Captcha"
|
||||
PrivateCaptchaTeam = "Private Captcha Team"
|
||||
StageDev = "dev"
|
||||
StageStaging = "staging"
|
||||
StageTest = "test"
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/jpillora/backoff"
|
||||
)
|
||||
@@ -98,6 +99,52 @@ func ParseBoolean(value string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func containsAlphabetic(s string) bool {
|
||||
for _, r := range s {
|
||||
if unicode.IsLetter(r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func onlyAlphabetic(s string) bool {
|
||||
for _, r := range s {
|
||||
if !unicode.IsLetter(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isLowerCase(s string) bool {
|
||||
for _, r := range s {
|
||||
if !unicode.IsLower(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func GuessFirstName(username string) string {
|
||||
parts := strings.Fields(username)
|
||||
|
||||
for _, p := range parts {
|
||||
if containsAlphabetic(p) {
|
||||
if onlyAlphabetic(p) && isLowerCase(p) {
|
||||
runes := []rune(p)
|
||||
runes[0] = unicode.ToUpper(runes[0])
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
return username
|
||||
}
|
||||
|
||||
func ChunkedCleanup(ctx context.Context, minInterval, maxInterval time.Duration, defaultChunkSize int, deleter func(context.Context, time.Time, int) int) {
|
||||
b := &backoff.Backoff{
|
||||
Min: minInterval,
|
||||
|
||||
@@ -123,3 +123,29 @@ func TestSubDomain(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGuessFirstName(t *testing.T) {
|
||||
tests := []struct {
|
||||
username string
|
||||
expected string
|
||||
}{
|
||||
{"john doe", "John"},
|
||||
{"123 alice 456", "Alice"},
|
||||
{"bob123 charlie", "bob123"},
|
||||
{"david", "David"},
|
||||
{"123 456 789", "123 456 789"},
|
||||
{"", ""},
|
||||
{" ", " "},
|
||||
{"!@# john_doe", "john_doe"},
|
||||
{"___123___", "___123___"},
|
||||
{" emily rose ", "Emily"},
|
||||
{"123 456abc", "456abc"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
actual := GuessFirstName(tt.username)
|
||||
if actual != tt.expected {
|
||||
t.Errorf("GuessFirstName(%q) = %q; want %q", tt.username, actual, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ func (j *UserEmailNotificationsJob) processNotificationsChunk(ctx context.Contex
|
||||
Subject: un.Subject,
|
||||
EmailTo: n.Email,
|
||||
EmailFrom: emailFrom,
|
||||
NameFrom: common.PrivateCaptcha,
|
||||
NameFrom: common.PrivateCaptchaTeam,
|
||||
ReplyTo: replyToEmail,
|
||||
HTMLBody: htmlBodyTpl.String(),
|
||||
TextBody: textBodyTpl.String(),
|
||||
|
||||
+2
-2
@@ -93,7 +93,7 @@ func (pm *PortalMailer) SendTwoFactor(ctx context.Context, email string, code in
|
||||
Subject: fmt.Sprintf("[%s] Your verification code is %v", common.PrivateCaptcha, data.Code),
|
||||
EmailTo: email,
|
||||
EmailFrom: pm.EmailFrom.Value(),
|
||||
NameFrom: common.PrivateCaptcha,
|
||||
NameFrom: common.PrivateCaptchaTeam,
|
||||
}
|
||||
|
||||
clog := slog.With("email", email, "code", data.Code)
|
||||
@@ -151,7 +151,7 @@ func (pm *PortalMailer) SendWelcome(ctx context.Context, email, name string) err
|
||||
Subject: "Welcome to Private Captcha",
|
||||
EmailTo: email,
|
||||
EmailFrom: pm.EmailFrom.Value(),
|
||||
NameFrom: common.PrivateCaptcha,
|
||||
NameFrom: common.PrivateCaptchaTeam,
|
||||
ReplyTo: pm.ReplyToEmail.Value(),
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,5 +36,5 @@ func (j *onboardUserJob) InitialPause() time.Duration {
|
||||
}
|
||||
|
||||
func (j *onboardUserJob) RunOnce(ctx context.Context) error {
|
||||
return j.mailer.SendWelcome(ctx, j.user.Email, j.user.Name)
|
||||
return j.mailer.SendWelcome(ctx, j.user.Email, common.GuessFirstName(j.user.Name))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user