فهرست منبع

Expose Application flag to displayname templates

Fixes #94
Tulir Asokan 2 سال پیش
والد
کامیت
200c4fc9d0
11فایلهای تغییر یافته به همراه61 افزوده شده و 36 حذف شده
  1. 2 2
      backfill.go
  2. 8 3
      config/bridge.go
  3. 10 9
      database/puppet.go
  4. 7 6
      database/upgrades/00-latest-revision.sql
  5. 2 0
      database/upgrades/23-puppet-is-application.sql
  6. 2 1
      example-config.yaml
  7. 1 1
      go.mod
  8. 2 2
      go.sum
  9. 4 4
      portal.go
  10. 3 3
      portal_convert.go
  11. 20 5
      puppet.go

+ 2 - 2
backfill.go

@@ -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)

+ 8 - 3
config/bridge.go

@@ -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()
 }
 

+ 10 - 9
database/puppet.go

@@ -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,
 	)

+ 7 - 6
database/upgrades/00-latest-revision.sql

@@ -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,

+ 2 - 0
database/upgrades/23-puppet-is-application.sql

@@ -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;

+ 2 - 1
example-config.yaml

@@ -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:

+ 1 - 1
go.mod

@@ -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

+ 2 - 2
go.sum

@@ -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=

+ 4 - 4
portal.go

@@ -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)
 

+ 3 - 3
portal_convert.go

@@ -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)

+ 20 - 5
puppet.go

@@ -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