From 67ff1ca58de4e5b6d0059f36cfd5720bafd15f98 Mon Sep 17 00:00:00 2001 From: Tim Zabel Date: Sat, 16 May 2020 20:06:28 -0400 Subject: [PATCH] Add zero width space between Telegram usernames to prevent pinging across platforms. ResolveUserName is now used instead of user.String() for retrieving username information. For additional details, see: https://github.com/42wim/matterbridge/issues/175. --- internal/handlers/telegram/handler.go | 14 ++++++++------ internal/handlers/telegram/handler_test.go | 2 +- internal/handlers/telegram/helpers.go | 19 ++++++++++++++++--- internal/handlers/telegram/helpers_test.go | 15 ++++++++++++--- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/internal/handlers/telegram/handler.go b/internal/handlers/telegram/handler.go index 270f52c9..da964a2f 100644 --- a/internal/handlers/telegram/handler.go +++ b/internal/handlers/telegram/handler.go @@ -54,9 +54,10 @@ messageHandler handles the Message Telegram Object, which formats the Telegram update into a simple string for IRC. */ func messageHandler(tg *Client, u tgbotapi.Update) { + username := ResolveUserName(u.Message.From) formatted := fmt.Sprintf("%s%s%s %s", tg.Settings.Prefix, - u.Message.From.String(), + username, tg.Settings.Suffix, // Trim unexpected trailing whitespace strings.Trim(u.Message.Text, " ")) @@ -69,7 +70,7 @@ joinHandler handles when users join the Telegram group func joinHandler(tg *Client, users *[]tgbotapi.User) { if tg.IRCSettings.ShowJoinMessage { for _, user := range *users { - username := GetUsername(&user) + username := GetFullUsername(&user) formatted := username + " has joined the Telegram Group!" tg.sendToIrc(formatted) } @@ -81,7 +82,7 @@ partHandler handles when users leave the Telegram group */ func partHandler(tg *Client, user *tgbotapi.User) { if tg.IRCSettings.ShowLeaveMessage { - username := GetUsername(user) + username := GetFullUsername(user) formatted := username + " has left the Telegram Group!" tg.sendToIrc(formatted) @@ -108,8 +109,8 @@ photoHandler handles the Message.Photo Telegram object. Only acknowledges Photo exists, and sends notification to IRC */ func photoHandler(tg *Client, u tgbotapi.Update) { - user := u.Message.From - formatted := user.String() + " shared a photo on Telegram with caption: '" + + username := ResolveUserName(u.Message.From) + formatted := username + " shared a photo on Telegram with caption: '" + u.Message.Caption + "'" tg.sendToIrc(formatted) @@ -120,7 +121,8 @@ documentHandler receives a document object from Telegram, and sends a notification to IRC. */ func documentHandler(tg *Client, u *tgbotapi.Message) { - formatted := u.From.String() + " shared a file" + username := ResolveUserName(u.From) + formatted := username + " shared a file" if u.Document.MimeType != "" { formatted += " (" + u.Document.MimeType + ")" } diff --git a/internal/handlers/telegram/handler_test.go b/internal/handlers/telegram/handler_test.go index 14a50e0b..cc31e0f2 100644 --- a/internal/handlers/telegram/handler_test.go +++ b/internal/handlers/telegram/handler_test.go @@ -505,7 +505,7 @@ func TestMessageRandomWithoutUsername(t *testing.T) { FirstName: "testing", LastName: "123", } - correct := fmt.Sprintf("<%s> Random Text", testUser.String()) + correct := fmt.Sprintf("<%s> Random Text", testUser.FirstName) updateObj := tgbotapi.Update{ Message: &tgbotapi.Message{ diff --git a/internal/handlers/telegram/helpers.go b/internal/handlers/telegram/helpers.go index e954d744..bf6170a5 100644 --- a/internal/handlers/telegram/helpers.go +++ b/internal/handlers/telegram/helpers.go @@ -5,12 +5,25 @@ import ( ) /* -GetUsername returns the name and username of a user. Since usernames are optional +ResolveUserName does basic cleanup if a user does not have a username on Telegram. +*/ +func ResolveUserName(u *tgbotapi.User) string { + if u.UserName == "" { + return u.FirstName + } + // Add ZWSP to prevent pinging across platforms + // See https://github.com/42wim/matterbridge/issues/175 + username := u.UserName[:1] + "" + u.UserName[1:] + return username +} + +/* +GetFullUsername returns the name and username of a user. Since usernames are optional on Telegram, we first need to check to see if they have one set. */ -func GetUsername(u *tgbotapi.User) string { +func GetFullUsername(u *tgbotapi.User) string { if u.UserName == "" { return u.FirstName } - return u.FirstName + " (@" + u.UserName + ")" + return u.FirstName + " (@" + u.UserName[:1] + "" + u.UserName[1:] + ")" } diff --git a/internal/handlers/telegram/helpers_test.go b/internal/handlers/telegram/helpers_test.go index 4e554aea..6018be52 100644 --- a/internal/handlers/telegram/helpers_test.go +++ b/internal/handlers/telegram/helpers_test.go @@ -8,8 +8,9 @@ import ( func TestGetUsername(t *testing.T) { username := &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"} - correct := username.FirstName + " (@" + username.UserName + ")" - name := GetUsername(username) + correct := username.FirstName + " (@" + username.UserName[:1] + + "" + username.UserName[1:] + ")" + name := GetFullUsername(username) assert.Equal(t, correct, name) } @@ -17,7 +18,15 @@ func TestGetUsername(t *testing.T) { func TestGetNoUsername(t *testing.T) { username := &tgbotapi.User{ID: 1, FirstName: "John"} correct := username.FirstName - name := GetUsername(username) + name := GetFullUsername(username) + + assert.Equal(t, correct, name) +} + +func TestResolveUserName(t *testing.T) { + username := &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"} + correct := username.UserName[:1] + "" + username.UserName[1:] + name := ResolveUserName(username) assert.Equal(t, correct, name) }