Expose Application flag to displayname templates

Fixes #94
This commit is contained in:
Tulir Asokan
2023-06-21 01:38:56 +03:00
parent d39499cdcf
commit 200c4fc9d0
11 changed files with 61 additions and 36 deletions

View File

@@ -254,11 +254,11 @@ func (portal *Portal) convertMessageBatch(log zerolog.Logger, source *User, mess
for _, msg := range messages {
for _, mention := range msg.Mentions {
puppet := portal.bridge.GetPuppetByID(mention.ID)
puppet.UpdateInfo(nil, mention, "")
puppet.UpdateInfo(nil, mention, nil)
}
puppet := portal.bridge.GetPuppetByID(msg.Author.ID)
puppet.UpdateInfo(source, msg.Author, msg.WebhookID)
puppet.UpdateInfo(source, msg.Author, msg)
intent := puppet.IntentFor(portal)
replyTo := portal.getReplyTarget(source, discordThreadID, msg.MessageReference, msg.Embeds, true)
mentions := portal.convertDiscordMentions(msg, false)

View File

@@ -292,12 +292,17 @@ func (bc BridgeConfig) FormatUsername(userID string) string {
type DisplaynameParams struct {
*discordgo.User
Webhook bool
Webhook bool
Application bool
}
func (bc BridgeConfig) FormatDisplayname(user *discordgo.User, webhook bool) string {
func (bc BridgeConfig) FormatDisplayname(user *discordgo.User, webhook, application bool) string {
var buffer strings.Builder
_ = bc.displaynameTemplate.Execute(&buffer, &DisplaynameParams{user, webhook})
_ = bc.displaynameTemplate.Execute(&buffer, &DisplaynameParams{
User: user,
Webhook: webhook,
Application: application,
})
return buffer.String()
}

View File

@@ -11,7 +11,7 @@ import (
const (
puppetSelect = "SELECT id, name, name_set, avatar, avatar_url, avatar_set," +
" contact_info_set, global_name, username, discriminator, is_bot, is_webhook, custom_mxid, access_token, next_batch" +
" contact_info_set, global_name, username, discriminator, is_bot, is_webhook, is_application, custom_mxid, access_token, next_batch" +
" FROM puppet "
)
@@ -80,6 +80,7 @@ type Puppet struct {
Discriminator string
IsBot bool
IsWebhook bool
IsApplication bool
CustomMXID id.UserID
AccessToken string
@@ -91,7 +92,7 @@ func (p *Puppet) Scan(row dbutil.Scannable) *Puppet {
var customMXID, accessToken, nextBatch sql.NullString
err := row.Scan(&p.ID, &p.Name, &p.NameSet, &p.Avatar, &avatarURL, &p.AvatarSet, &p.ContactInfoSet,
&p.GlobalName, &p.Username, &p.Discriminator, &p.IsBot, &p.IsWebhook, &customMXID, &accessToken, &nextBatch)
&p.GlobalName, &p.Username, &p.Discriminator, &p.IsBot, &p.IsWebhook, &p.IsApplication, &customMXID, &accessToken, &nextBatch)
if err != nil {
if err != sql.ErrNoRows {
@@ -114,13 +115,13 @@ func (p *Puppet) Insert() {
query := `
INSERT INTO puppet (
id, name, name_set, avatar, avatar_url, avatar_set, contact_info_set,
global_name, username, discriminator, is_bot, is_webhook,
global_name, username, discriminator, is_bot, is_webhook, is_application,
custom_mxid, access_token, next_batch
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
`
_, err := p.db.Exec(query, p.ID, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet,
p.GlobalName, p.Username, p.Discriminator, p.IsBot, p.IsWebhook,
p.GlobalName, p.Username, p.Discriminator, p.IsBot, p.IsWebhook, p.IsApplication,
strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch))
if err != nil {
@@ -132,14 +133,14 @@ func (p *Puppet) Insert() {
func (p *Puppet) Update() {
query := `
UPDATE puppet SET name=$1, name_set=$2, avatar=$3, avatar_url=$4, avatar_set=$5, contact_info_set=$6,
global_name=$7, username=$8, discriminator=$9, is_bot=$10, is_webhook=$11,
custom_mxid=$12, access_token=$13, next_batch=$14
WHERE id=$15
global_name=$7, username=$8, discriminator=$9, is_bot=$10, is_webhook=$11, is_application=$12,
custom_mxid=$13, access_token=$14, next_batch=$15
WHERE id=$16
`
_, err := p.db.Exec(
query,
p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet,
p.GlobalName, p.Username, p.Discriminator, p.IsBot, p.IsWebhook,
p.GlobalName, p.Username, p.Discriminator, p.IsBot, p.IsWebhook, p.IsApplication,
strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch),
p.ID,
)

View File

@@ -1,4 +1,4 @@
-- v0 -> v22 (compatible with v19+): Latest revision
-- v0 -> v23 (compatible with v19+): Latest revision
CREATE TABLE guild (
dcid TEXT PRIMARY KEY,
@@ -71,11 +71,12 @@ CREATE TABLE puppet (
contact_info_set BOOLEAN NOT NULL DEFAULT false,
global_name TEXT NOT NULL DEFAULT '',
username TEXT NOT NULL DEFAULT '',
discriminator TEXT NOT NULL DEFAULT '',
is_bot BOOLEAN NOT NULL DEFAULT false,
is_webhook BOOLEAN NOT NULL DEFAULT false,
global_name TEXT NOT NULL DEFAULT '',
username TEXT NOT NULL DEFAULT '',
discriminator TEXT NOT NULL DEFAULT '',
is_bot BOOLEAN NOT NULL DEFAULT false,
is_webhook BOOLEAN NOT NULL DEFAULT false,
is_application BOOLEAN NOT NULL DEFAULT false,
custom_mxid TEXT,
access_token TEXT,

View File

@@ -0,0 +1,2 @@
-- v23 (compatible with v19+): Store is application status for puppets
ALTER TABLE puppet ADD COLUMN is_application BOOLEAN NOT NULL DEFAULT false;

View File

@@ -92,7 +92,8 @@ bridge:
# .Discriminator - The 4 numbers after the name on Discord
# .Bot - Whether the user is a bot
# .System - Whether the user is an official system user
# .Webhook - Whether the user is a webhook
# .Webhook - Whether the user is a webhook and is not an application
# .Application - Whether the user is an application
displayname_template: '{{or .GlobalName .Username}}{{if .Bot}} (bot){{end}}'
# Displayname template for Discord channels (bridged as rooms, or spaces when type=4).
# Available variables:

2
go.mod
View File

@@ -38,4 +38,4 @@ require (
maunium.net/go/mauflag v1.0.0 // indirect
)
replace github.com/bwmarrin/discordgo => github.com/beeper/discordgo v0.0.0-20230618183737-3c7afd8d8596
replace github.com/bwmarrin/discordgo => github.com/beeper/discordgo v0.0.0-20230620222529-2cb9d9280e37

4
go.sum
View File

@@ -1,6 +1,6 @@
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/beeper/discordgo v0.0.0-20230618183737-3c7afd8d8596 h1:PxtbetWbVi2OlACDNtx6YJahhXt/rhiEsGqtOOLSx4o=
github.com/beeper/discordgo v0.0.0-20230618183737-3c7afd8d8596/go.mod h1:59+AOzzjmL6onAh62nuLXmn7dJCaC/owDLWbGtjTcFA=
github.com/beeper/discordgo v0.0.0-20230620222529-2cb9d9280e37 h1:N0c/439VcoHGc+gL1lb3vUjr6vUbXz+vor7SLnBOhJU=
github.com/beeper/discordgo v0.0.0-20230620222529-2cb9d9280e37/go.mod h1:59+AOzzjmL6onAh62nuLXmn7dJCaC/owDLWbGtjTcFA=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

View File

@@ -625,7 +625,7 @@ func (portal *Portal) handleDiscordMessageCreate(user *User, msg *discordgo.Mess
log.Debug().Msg("Starting handling of Discord message")
puppet := portal.bridge.GetPuppetByID(msg.Author.ID)
puppet.UpdateInfo(user, msg.Author, msg.WebhookID)
puppet.UpdateInfo(user, msg.Author, msg)
intent := puppet.IntentFor(portal)
var discordThreadID string
@@ -990,7 +990,7 @@ func (portal *Portal) handleDiscordTyping(evt *discordgo.TypingStart) {
func (portal *Portal) syncParticipant(source *User, participant *discordgo.User, remove bool) {
puppet := portal.bridge.GetPuppetByID(participant.ID)
puppet.UpdateInfo(source, participant, "")
puppet.UpdateInfo(source, participant, nil)
log := portal.log.With().
Str("participant_id", participant.ID).
Str("ghost_mxid", puppet.MXID.String()).
@@ -1017,7 +1017,7 @@ func (portal *Portal) syncParticipant(source *User, participant *discordgo.User,
func (portal *Portal) syncParticipants(source *User, participants []*discordgo.User) {
for _, participant := range participants {
puppet := portal.bridge.GetPuppetByID(participant.ID)
puppet.UpdateInfo(source, participant, "")
puppet.UpdateInfo(source, participant, nil)
user := portal.bridge.GetUserByID(participant.ID)
if user != nil {
@@ -1847,7 +1847,7 @@ func (portal *Portal) handleMatrixReaction(sender *User, evt *event.Event) {
func (portal *Portal) handleDiscordReaction(user *User, reaction *discordgo.MessageReaction, add bool, thread *Thread, member *discordgo.Member) {
puppet := portal.bridge.GetPuppetByID(reaction.UserID)
if member != nil {
puppet.UpdateInfo(user, member.User, "")
puppet.UpdateInfo(user, member.User, nil)
}
intent := puppet.IntentFor(portal)

View File

@@ -628,7 +628,7 @@ func (portal *Portal) convertDiscordMentions(msg *discordgo.Message, syncGhosts
for _, mention := range msg.Mentions {
puppet := portal.bridge.GetPuppetByID(mention.ID)
if syncGhosts {
puppet.UpdateInfo(nil, mention, "")
puppet.UpdateInfo(nil, mention, nil)
}
user := portal.bridge.GetUserByID(mention.ID)
if user != nil {
@@ -661,7 +661,7 @@ func (portal *Portal) convertDiscordTextMessage(ctx context.Context, intent *app
var htmlParts []string
if msg.Interaction != nil {
puppet := portal.bridge.GetPuppetByID(msg.Interaction.User.ID)
puppet.UpdateInfo(nil, msg.Interaction.User, "")
puppet.UpdateInfo(nil, msg.Interaction.User, nil)
htmlParts = append(htmlParts, fmt.Sprintf(msgInteractionTemplateHTML, puppet.MXID, puppet.Name, msg.Interaction.Name))
}
if msg.Content != "" && !isPlainGifMessage(msg) {
@@ -708,7 +708,7 @@ func (portal *Portal) convertDiscordTextMessage(ctx context.Context, intent *app
"com.beeper.linkpreviews": previews,
}
if msg.WebhookID != "" && portal.bridge.Config.Bridge.PrefixWebhookMessages {
if msg.WebhookID != "" && msg.ApplicationID == "" && portal.bridge.Config.Bridge.PrefixWebhookMessages {
content.EnsureHasHTML()
content.Body = fmt.Sprintf("%s: %s", msg.Author.Username, content.Body)
content.FormattedBody = fmt.Sprintf("<strong>%s</strong>: %s", html.EscapeString(msg.Author.Username), content.FormattedBody)

View File

@@ -195,7 +195,7 @@ func (puppet *Puppet) updatePortalMeta(meta func(portal *Portal)) {
}
func (puppet *Puppet) UpdateName(info *discordgo.User) bool {
newName := puppet.bridge.Config.Bridge.FormatDisplayname(info, puppet.IsWebhook)
newName := puppet.bridge.Config.Bridge.FormatDisplayname(info, puppet.IsWebhook, puppet.IsApplication)
if puppet.Name == newName && puppet.NameSet {
return false
}
@@ -285,7 +285,7 @@ func (puppet *Puppet) UpdateAvatar(info *discordgo.User) bool {
return true
}
func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User, webhookID string) {
func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User, message *discordgo.Message) {
puppet.syncLock.Lock()
defer puppet.syncLock.Unlock()
@@ -308,9 +308,24 @@ func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User, webhookID s
}
changed := false
if webhookID != "" && webhookID == info.ID && !puppet.IsWebhook {
puppet.IsWebhook = true
changed = true
if message != nil {
if message.WebhookID != "" && message.ApplicationID == "" && !puppet.IsWebhook {
puppet.log.Debug().
Str("message_id", message.ID).
Str("webhook_id", message.WebhookID).
Msg("Found webhook ID in message, marking ghost as a webhook")
puppet.IsWebhook = true
changed = true
}
if message.ApplicationID != "" && !puppet.IsApplication {
puppet.log.Debug().
Str("message_id", message.ID).
Str("application_id", message.ApplicationID).
Msg("Found application ID in message, marking ghost as an application")
puppet.IsApplication = true
puppet.IsWebhook = false
changed = true
}
}
changed = puppet.UpdateContactInfo(info) || changed
changed = puppet.UpdateName(info) || changed