welcome message: link @zio with a mention entity
This commit is contained in:
parent
f8aefb7fd5
commit
233a2399e9
2 changed files with 68 additions and 4 deletions
|
|
@ -6,7 +6,12 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const officialWelcomeMessageTemplate = "👋 Welcome to OwpenGram!\n\nYou just signed in via %s.\n\nIf this wasn't you, revoke this session from \"Settings > Privacy and Security > Active sessions\" immediately.\n\nIf you haven't already, feel free to join @zio for all the latest updates!"
|
||||
// officialUpdatesChannelMention is the public @username of the updates channel
|
||||
// linked from the welcome message. It is carried both in the template text and
|
||||
// in a MessageEntityMention so clients render it as a tappable link.
|
||||
const officialUpdatesChannelMention = "@zio"
|
||||
|
||||
const officialWelcomeMessageTemplate = "👋 Welcome to OwpenGram!\n\nYou just signed in via %s.\n\nIf this wasn't you, revoke this session from \"Settings > Privacy and Security > Active sessions\" immediately.\n\nIf you haven't already, feel free to join " + officialUpdatesChannelMention + " for all the latest updates!"
|
||||
|
||||
// OfficialWelcomeMessage builds the account-visible incoming message sent
|
||||
// from the official system account on every completed sign-in (SignUp and
|
||||
|
|
@ -20,13 +25,43 @@ func OfficialWelcomeMessage(userID int64, method string, date int) (Message, err
|
|||
if userID <= 0 || IsSystemUserID(userID) || method == "" || date < 0 || date > math.MaxInt32 {
|
||||
return Message{}, fmt.Errorf("%w: user=%d method=%q date=%d", ErrLoginCodeDeliveryInvalid, userID, method, date)
|
||||
}
|
||||
return Message{
|
||||
body := fmt.Sprintf(officialWelcomeMessageTemplate, method)
|
||||
msg := Message{
|
||||
OwnerUserID: userID,
|
||||
Peer: Peer{Type: PeerTypeUser, ID: OfficialSystemUserID},
|
||||
From: Peer{Type: PeerTypeUser, ID: OfficialSystemUserID},
|
||||
Date: date,
|
||||
Body: fmt.Sprintf(officialWelcomeMessageTemplate, method),
|
||||
}, nil
|
||||
Body: body,
|
||||
}
|
||||
if ent, ok := usernameMentionEntity(body, officialUpdatesChannelMention); ok {
|
||||
msg.Entities = []MessageEntity{ent}
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// usernameMentionEntity locates mention ("@name") in text and returns a
|
||||
// MessageEntityMention spanning it, with the UTF-16 offset/length clients expect.
|
||||
func usernameMentionEntity(text, mention string) (MessageEntity, bool) {
|
||||
before, _, found := strings.Cut(text, mention)
|
||||
if !found {
|
||||
return MessageEntity{}, false
|
||||
}
|
||||
return MessageEntity{
|
||||
Type: MessageEntityMention,
|
||||
Offset: utf16Len(before),
|
||||
Length: utf16Len(mention),
|
||||
}, true
|
||||
}
|
||||
|
||||
func utf16Len(s string) int {
|
||||
n := 0
|
||||
for _, r := range s {
|
||||
n++
|
||||
if r > 0xffff {
|
||||
n++
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// SignInMethodLabel returns the human-readable method name embedded in
|
||||
|
|
|
|||
29
internal/domain/welcome_message_test.go
Normal file
29
internal/domain/welcome_message_test.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
func TestOfficialWelcomeMessageLinksUpdatesChannel(t *testing.T) {
|
||||
for _, method := range []string{"phone number", "email"} {
|
||||
msg, err := OfficialWelcomeMessage(1780243200, method, 1_700_000_000)
|
||||
if err != nil {
|
||||
t.Fatalf("method %q: %v", method, err)
|
||||
}
|
||||
if len(msg.Entities) != 1 {
|
||||
t.Fatalf("method %q: entities = %+v, want one mention", method, msg.Entities)
|
||||
}
|
||||
ent := msg.Entities[0]
|
||||
if ent.Type != MessageEntityMention {
|
||||
t.Fatalf("entity type = %q, want mention", ent.Type)
|
||||
}
|
||||
units := utf16.Encode([]rune(msg.Body))
|
||||
if ent.Offset < 0 || ent.Length <= 0 || ent.Offset+ent.Length > len(units) {
|
||||
t.Fatalf("entity %+v out of bounds for body of %d utf16 units", ent, len(units))
|
||||
}
|
||||
if got := string(utf16.Decode(units[ent.Offset : ent.Offset+ent.Length])); got != officialUpdatesChannelMention {
|
||||
t.Fatalf("entity spans %q, want %q", got, officialUpdatesChannelMention)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue