浏览代码

Store global name and webhook status for puppets

Tulir Asokan 2 年之前
父节点
当前提交
824dea4745
共有 7 个文件被更改,包括 44 次插入19 次删除
  1. 2 2
      backfill.go
  2. 21 9
      database/puppet.go
  3. 3 1
      database/upgrades/00-latest-revision.sql
  4. 3 0
      database/upgrades/20-more-puppet-info.sql
  5. 4 4
      portal.go
  6. 2 2
      portal_convert.go
  7. 9 1
      puppet.go

+ 2 - 2
backfill.go

@@ -211,11 +211,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, "")
 		}
 
 		puppet := portal.bridge.GetPuppetByID(msg.Author.ID)
-		puppet.UpdateInfo(source, msg.Author)
+		puppet.UpdateInfo(source, msg.Author, msg.WebhookID)
 		intent := puppet.IntentFor(portal)
 		replyTo, replySenderMXID := portal.getReplyTarget(source, "", msg.MessageReference, msg.Embeds, true)
 		mentions := portal.convertDiscordMentions(msg, replySenderMXID, false)

+ 21 - 9
database/puppet.go

@@ -11,7 +11,7 @@ import (
 
 const (
 	puppetSelect = "SELECT id, name, name_set, avatar, avatar_url, avatar_set," +
-		" contact_info_set, username, discriminator, is_bot, custom_mxid, access_token, next_batch" +
+		" contact_info_set, global_name, username, discriminator, is_bot, is_webhook, custom_mxid, access_token, next_batch" +
 		" FROM puppet "
 )
 
@@ -75,9 +75,11 @@ type Puppet struct {
 
 	ContactInfoSet bool
 
+	GlobalName    string
 	Username      string
 	Discriminator string
 	IsBot         bool
+	IsWebhook     bool
 
 	CustomMXID  id.UserID
 	AccessToken string
@@ -89,7 +91,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.Username, &p.Discriminator, &p.IsBot, &customMXID, &accessToken, &nextBatch)
+		&p.GlobalName, &p.Username, &p.Discriminator, &p.IsBot, &p.IsWebhook, &customMXID, &accessToken, &nextBatch)
 
 	if err != nil {
 		if err != sql.ErrNoRows {
@@ -110,11 +112,16 @@ func (p *Puppet) Scan(row dbutil.Scannable) *Puppet {
 
 func (p *Puppet) Insert() {
 	query := `
-		INSERT INTO puppet (id, name, name_set, avatar, avatar_url, avatar_set, contact_info_set, username, discriminator, is_bot, custom_mxid, access_token, next_batch)
-		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
+		INSERT INTO puppet (
+			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
+		)
+		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
 	`
 	_, err := p.db.Exec(query, p.ID, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet,
-		p.Username, p.Discriminator, p.IsBot, strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch))
+		p.GlobalName, p.Username, p.Discriminator, p.IsBot, p.IsWebhook,
+		strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch))
 
 	if err != nil {
 		p.log.Warnfln("Failed to insert %s: %v", p.ID, err)
@@ -125,12 +132,17 @@ 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,
-		                  username=$7, discriminator=$8, is_bot=$9, custom_mxid=$10, access_token=$11, next_batch=$12
+		                  global_name=$7, username=$8, discriminator=$9, is_bot=$10, is_webhook=$11,
+		                  custom_mxid=$12, access_token=$13, next_batch=$14
 		WHERE id=$13
 	`
-	_, err := p.db.Exec(query, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet,
-		p.Username, p.Discriminator, p.IsBot, strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch),
-		p.ID)
+	_, 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,
+		strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch),
+		p.ID,
+	)
 
 	if err != nil {
 		p.log.Warnfln("Failed to update %s: %v", p.ID, err)

+ 3 - 1
database/upgrades/00-latest-revision.sql

@@ -1,4 +1,4 @@
--- v0 -> v20 (compatible with v19+): Latest revision
+-- v0 -> v21 (compatible with v19+): Latest revision
 
 CREATE TABLE guild (
     dcid       TEXT PRIMARY KEY,
@@ -71,9 +71,11 @@ 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,
 
     custom_mxid  TEXT,
     access_token TEXT,

+ 3 - 0
database/upgrades/20-more-puppet-info.sql

@@ -0,0 +1,3 @@
+-- v21 (compatible with v19+): Store global displayname and is webhook status for puppets
+ALTER TABLE puppet ADD COLUMN global_name TEXT NOT NULL DEFAULT '';
+ALTER TABLE puppet ADD COLUMN is_webhook BOOLEAN NOT NULL DEFAULT false;

+ 4 - 4
portal.go

@@ -620,7 +620,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)
+	puppet.UpdateInfo(user, msg.Author, msg.WebhookID)
 	intent := puppet.IntentFor(portal)
 
 	var discordThreadID string
@@ -970,7 +970,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, "")
 	log := portal.log.With().
 		Str("participant_id", participant.ID).
 		Str("ghost_mxid", puppet.MXID.String()).
@@ -997,7 +997,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, "")
 
 		user := portal.bridge.GetUserByID(participant.ID)
 		if user != nil {
@@ -1826,7 +1826,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, "")
 	}
 	intent := puppet.IntentFor(portal)
 

+ 2 - 2
portal_convert.go

@@ -545,7 +545,7 @@ func (portal *Portal) convertDiscordMentions(msg *discordgo.Message, replySender
 	for _, mention := range msg.Mentions {
 		puppet := portal.bridge.GetPuppetByID(mention.ID)
 		if syncGhosts {
-			puppet.UpdateInfo(nil, mention)
+			puppet.UpdateInfo(nil, mention, "")
 		}
 		user := portal.bridge.GetUserByID(mention.ID)
 		if user != nil {
@@ -581,7 +581,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, "")
 		htmlParts = append(htmlParts, fmt.Sprintf(msgInteractionTemplateHTML, puppet.MXID, puppet.Name, msg.Interaction.Name))
 	}
 	if msg.Content != "" && !isPlainGifMessage(msg) {

+ 9 - 1
puppet.go

@@ -271,7 +271,7 @@ func (puppet *Puppet) UpdateAvatar(info *discordgo.User) bool {
 	return true
 }
 
-func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User) {
+func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User, webhookID string) {
 	puppet.syncLock.Lock()
 	defer puppet.syncLock.Unlock()
 
@@ -294,6 +294,10 @@ func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User) {
 	}
 
 	changed := false
+	if webhookID != "" && webhookID == info.ID && !puppet.IsWebhook {
+		puppet.IsWebhook = true
+		changed = true
+	}
 	changed = puppet.UpdateContactInfo(info) || changed
 	changed = puppet.UpdateName(info) || changed
 	changed = puppet.UpdateAvatar(info) || changed
@@ -308,6 +312,10 @@ func (puppet *Puppet) UpdateContactInfo(info *discordgo.User) bool {
 		puppet.Username = info.Username
 		changed = true
 	}
+	if puppet.GlobalName != info.GlobalName {
+		puppet.GlobalName = info.GlobalName
+		changed = true
+	}
 	if puppet.Discriminator != info.Discriminator {
 		puppet.Discriminator = info.Discriminator
 		changed = true