Restore functionality of edits, deletes and boundedmap uses UUID now
This commit is contained in:
@@ -186,8 +186,9 @@ func (b *Bridge) onDiscordMessageCreate(s *discordgo.Session, m *discordgo.Messa
|
||||
|
||||
if m.ReferencedMessage != nil {
|
||||
refDiscordID := parseMessageID(m.ReferencedMessage.ID)
|
||||
if sneedIDInt, ok := b.discordToSneed.Get(refDiscordID); ok {
|
||||
if uname, ok2 := b.sneedUsernames.Get(sneedIDInt.(int)); ok2 {
|
||||
if sneedUUIDVal, ok := b.discordToSneed.Get(strconv.Itoa(refDiscordID)); ok {
|
||||
sneedUUID := sneedUUIDVal.(string)
|
||||
if uname, ok2 := b.sneedUsernames.Get(sneedUUID); ok2 {
|
||||
contentText = fmt.Sprintf("@%s, %s", uname.(string), contentText)
|
||||
}
|
||||
}
|
||||
@@ -289,14 +290,14 @@ func (b *Bridge) onDiscordMessageEdit(s *discordgo.Session, m *discordgo.Message
|
||||
return
|
||||
}
|
||||
discordID := parseMessageID(m.ID)
|
||||
sneedIDInt, ok := b.discordToSneed.Get(discordID)
|
||||
sneedUUIDVal, ok := b.discordToSneed.Get(strconv.Itoa(discordID))
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
sneedID := sneedIDInt.(int)
|
||||
payload := map[string]interface{}{"id": sneedID, "message": strings.TrimSpace(m.Content)}
|
||||
sneedUUID := sneedUUIDVal.(string)
|
||||
payload := map[string]interface{}{"uuid": sneedUUID, "message": strings.TrimSpace(m.Content)}
|
||||
data, _ := json.Marshal(payload)
|
||||
log.Printf("↩️ Discord edit -> Sneedchat (sneed_id=%d)", sneedID)
|
||||
log.Printf("↩️ Discord edit -> Sneedchat (sneed_uuid=%s)", sneedUUID)
|
||||
b.sneed.Send(fmt.Sprintf("/edit %s", string(data)))
|
||||
}
|
||||
|
||||
@@ -305,12 +306,13 @@ func (b *Bridge) onDiscordMessageDelete(s *discordgo.Session, m *discordgo.Messa
|
||||
return
|
||||
}
|
||||
discordID := parseMessageID(m.ID)
|
||||
sneedIDInt, ok := b.discordToSneed.Get(discordID)
|
||||
sneedUUIDVal, ok := b.discordToSneed.Get(strconv.Itoa(discordID))
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Printf("↩️ Discord delete -> Sneedchat (sneed_id=%d)", sneedIDInt.(int))
|
||||
b.sneed.Send(fmt.Sprintf("/delete %d", sneedIDInt.(int)))
|
||||
sneedUUID := sneedUUIDVal.(string)
|
||||
log.Printf("↩️ Discord delete -> Sneedchat (sneed_uuid=%s)", sneedUUID)
|
||||
b.sneed.Send(fmt.Sprintf("/delete %s", sneedUUID))
|
||||
}
|
||||
|
||||
func (b *Bridge) onSneedMessage(msg map[string]interface{}) {
|
||||
@@ -348,17 +350,17 @@ func (b *Bridge) onSneedMessage(msg map[string]interface{}) {
|
||||
log.Printf("✅ Sent Sneedchat → Discord: %s", username)
|
||||
|
||||
if sent != nil {
|
||||
if mid, ok := msg["message_id"].(int); ok && mid > 0 {
|
||||
if uuid, ok := msg["message_uuid"].(string); ok && uuid != "" {
|
||||
discordMsgID := parseMessageID(sent.ID)
|
||||
b.sneedToDiscord.Set(mid, discordMsgID)
|
||||
b.discordToSneed.Set(discordMsgID, mid)
|
||||
b.sneedUsernames.Set(mid, username)
|
||||
b.sneedToDiscord.Set(uuid, discordMsgID)
|
||||
b.discordToSneed.Set(strconv.Itoa(discordMsgID), uuid)
|
||||
b.sneedUsernames.Set(uuid, username)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bridge) handleSneedEdit(sneedID int, newContent string) {
|
||||
discordIDInt, ok := b.sneedToDiscord.Get(sneedID)
|
||||
func (b *Bridge) handleSneedEdit(sneedUUID string, newContent string) {
|
||||
discordIDInt, ok := b.sneedToDiscord.Get(sneedUUID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -371,11 +373,11 @@ func (b *Bridge) handleSneedEdit(sneedID int, newContent string) {
|
||||
log.Printf("❌ Failed to edit Discord message id=%d: %v", discordID, err)
|
||||
return
|
||||
}
|
||||
log.Printf("✏️ Edited Discord (webhook) message id=%d (sneed_id=%d)", discordID, sneedID)
|
||||
log.Printf("✏️ Edited Discord (webhook) message id=%d (sneed_uuid=%s)", discordID, sneedUUID)
|
||||
}
|
||||
|
||||
func (b *Bridge) handleSneedDelete(sneedID int) {
|
||||
discordIDInt, ok := b.sneedToDiscord.Get(sneedID)
|
||||
func (b *Bridge) handleSneedDelete(sneedUUID string) {
|
||||
discordIDInt, ok := b.sneedToDiscord.Get(sneedUUID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -386,10 +388,10 @@ func (b *Bridge) handleSneedDelete(sneedID int) {
|
||||
log.Printf("❌ Failed to delete Discord message id=%d: %v", discordID, err)
|
||||
return
|
||||
}
|
||||
log.Printf("🗑️ Deleted Discord (webhook) message id=%d (sneed_id=%d)", discordID, sneedID)
|
||||
b.sneedToDiscord.Delete(sneedID)
|
||||
b.discordToSneed.Delete(discordID)
|
||||
b.sneedUsernames.Delete(sneedID)
|
||||
log.Printf("🗑️ Deleted Discord (webhook) message id=%d (sneed_uuid=%s)", discordID, sneedUUID)
|
||||
b.sneedToDiscord.Delete(sneedUUID)
|
||||
b.discordToSneed.Delete(strconv.Itoa(discordID))
|
||||
b.sneedUsernames.Delete(sneedUUID)
|
||||
}
|
||||
|
||||
func (b *Bridge) onSneedConnect() {
|
||||
@@ -575,11 +577,11 @@ func (b *Bridge) recentOutboundIter() []map[string]interface{} {
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *Bridge) mapDiscordSneed(discordID, sneedID int, username string) {
|
||||
b.discordToSneed.Set(discordID, sneedID)
|
||||
b.sneedToDiscord.Set(sneedID, discordID)
|
||||
b.sneedUsernames.Set(sneedID, username)
|
||||
log.Printf("Mapped sneed_id=%d <-> discord_id=%d (username='%s')", sneedID, discordID, username)
|
||||
func (b *Bridge) mapDiscordSneed(sneedUUID string, discordID int, username string) {
|
||||
b.discordToSneed.Set(strconv.Itoa(discordID), sneedUUID)
|
||||
b.sneedToDiscord.Set(sneedUUID, discordID)
|
||||
b.sneedUsernames.Set(sneedUUID, username)
|
||||
log.Printf("Mapped sneed_uuid=%s <-> discord_id=%d (username='%s')", sneedUUID, discordID, username)
|
||||
}
|
||||
|
||||
func (b *Bridge) sendUploadStatusMessage(channelID, mention string, attachmentCount int) (*discordgo.Message, error) {
|
||||
@@ -629,7 +631,7 @@ func (b *Bridge) awaitSneedConfirmation(discordID int, channelID, statusMessageI
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if _, ok := b.discordToSneed.Get(discordID); ok {
|
||||
if _, ok := b.discordToSneed.Get(strconv.Itoa(discordID)); ok {
|
||||
desc := "Delivered to Sneedchat."
|
||||
b.editUploadStatusMessage(channelID, statusMessageID, b.uploadStatusTitle("complete"), desc, UploadStatusColorSuccess)
|
||||
b.scheduleUploadStatusDeletion(channelID, statusMessageID, UploadStatusCleanupDelay)
|
||||
|
||||
@@ -58,13 +58,13 @@ type Client struct {
|
||||
messageEditDates *utils.BoundedMap
|
||||
|
||||
OnMessage func(map[string]interface{})
|
||||
OnEdit func(int, string)
|
||||
OnDelete func(int)
|
||||
OnEdit func(string, string)
|
||||
OnDelete func(string)
|
||||
OnConnect func()
|
||||
OnDisconnect func()
|
||||
|
||||
recentOutboundIter func() []map[string]interface{}
|
||||
mapDiscordSneed func(int, int, string)
|
||||
mapDiscordSneed func(string, int, string)
|
||||
|
||||
bridgeUserID int
|
||||
bridgeUsername string
|
||||
@@ -367,23 +367,14 @@ func (c *Client) handleIncoming(raw string) {
|
||||
log.Printf("📦 payload: msgs=%d msg=%v del=%v", len(payload.Messages), payload.Message != nil, payload.Delete != nil)
|
||||
}
|
||||
|
||||
if payload.Delete != nil {
|
||||
var ids []int
|
||||
switch v := payload.Delete.(type) {
|
||||
case float64:
|
||||
ids = []int{int(v)}
|
||||
case []interface{}:
|
||||
for _, x := range v {
|
||||
if fid, ok := x.(float64); ok {
|
||||
ids = append(ids, int(fid))
|
||||
}
|
||||
}
|
||||
for _, uuid := range payload.Delete {
|
||||
if uuid == "" {
|
||||
continue
|
||||
}
|
||||
for _, id := range ids {
|
||||
c.messageEditDates.Delete(id)
|
||||
if c.OnDelete != nil {
|
||||
c.OnDelete(id)
|
||||
}
|
||||
c.messageEditDates.Delete(uuid)
|
||||
c.removeFromProcessed(uuid)
|
||||
if c.OnDelete != nil {
|
||||
c.OnDelete(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,10 +409,10 @@ func (c *Client) processMessage(m SneedMessage) {
|
||||
editDate := m.MessageEditDate
|
||||
deleted := m.Deleted || m.IsDeleted
|
||||
if deleted {
|
||||
c.messageEditDates.Delete(m.MessageID)
|
||||
c.messageEditDates.Delete(uuid)
|
||||
c.removeFromProcessed(uuid)
|
||||
if c.OnDelete != nil {
|
||||
c.OnDelete(m.MessageID)
|
||||
c.OnDelete(uuid)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -438,7 +429,7 @@ func (c *Client) processMessage(m SneedMessage) {
|
||||
if ts, ok := entry["ts"].(time.Time); ok {
|
||||
if content == messageText && now.Sub(ts) <= OutboundMatchWindow {
|
||||
if discordID, ok := entry["discord_id"].(int); ok {
|
||||
c.mapDiscordSneed(discordID, m.MessageID, username)
|
||||
c.mapDiscordSneed(uuid, discordID, username)
|
||||
entry["mapped"] = true
|
||||
break
|
||||
}
|
||||
@@ -447,16 +438,16 @@ func (c *Client) processMessage(m SneedMessage) {
|
||||
}
|
||||
}
|
||||
c.addToProcessed(uuid)
|
||||
c.messageEditDates.Set(m.MessageID, editDate)
|
||||
c.messageEditDates.Set(uuid, editDate)
|
||||
return
|
||||
}
|
||||
|
||||
if c.isProcessed(uuid) {
|
||||
if prev, exists := c.messageEditDates.Get(m.MessageID); exists {
|
||||
if prev, exists := c.messageEditDates.Get(uuid); exists {
|
||||
if editDate > prev.(int) {
|
||||
c.messageEditDates.Set(m.MessageID, editDate)
|
||||
c.messageEditDates.Set(uuid, editDate)
|
||||
if c.OnEdit != nil {
|
||||
c.OnEdit(m.MessageID, messageText)
|
||||
c.OnEdit(uuid, messageText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -464,15 +455,16 @@ func (c *Client) processMessage(m SneedMessage) {
|
||||
}
|
||||
|
||||
c.addToProcessed(uuid)
|
||||
c.messageEditDates.Set(m.MessageID, editDate)
|
||||
c.messageEditDates.Set(uuid, editDate)
|
||||
|
||||
if c.OnMessage != nil {
|
||||
c.OnMessage(map[string]interface{}{
|
||||
"username": username,
|
||||
"content": messageText,
|
||||
"message_id": m.MessageID,
|
||||
"author_id": userID,
|
||||
"raw": m,
|
||||
"username": username,
|
||||
"content": messageText,
|
||||
"message_uuid": uuid,
|
||||
"message_id": m.MessageID,
|
||||
"author_id": userID,
|
||||
"raw": m,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -522,7 +514,7 @@ func (c *Client) SetOutboundIter(f func() []map[string]interface{}) {
|
||||
c.recentOutboundIter = f
|
||||
}
|
||||
|
||||
func (c *Client) SetMapDiscordSneed(f func(int, int, string)) {
|
||||
func (c *Client) SetMapDiscordSneed(f func(string, int, string)) {
|
||||
c.mapDiscordSneed = f
|
||||
}
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@ type SneedMessage struct {
|
||||
type SneedPayload struct {
|
||||
Messages []SneedMessage `json:"messages"`
|
||||
Message *SneedMessage `json:"message"`
|
||||
Delete interface{} `json:"delete"`
|
||||
Delete []string `json:"delete"`
|
||||
}
|
||||
|
||||
@@ -7,24 +7,24 @@ import (
|
||||
|
||||
type BoundedMap struct {
|
||||
mu sync.RWMutex
|
||||
data map[int]interface{}
|
||||
timestamps map[int]time.Time
|
||||
data map[string]interface{}
|
||||
timestamps map[string]time.Time
|
||||
maxSize int
|
||||
maxAge time.Duration
|
||||
keys []int
|
||||
keys []string
|
||||
}
|
||||
|
||||
func NewBoundedMap(maxSize int, maxAge time.Duration) *BoundedMap {
|
||||
return &BoundedMap{
|
||||
data: make(map[int]interface{}),
|
||||
timestamps: make(map[int]time.Time),
|
||||
data: make(map[string]interface{}),
|
||||
timestamps: make(map[string]time.Time),
|
||||
maxSize: maxSize,
|
||||
maxAge: maxAge,
|
||||
keys: make([]int, 0, maxSize),
|
||||
keys: make([]string, 0, maxSize),
|
||||
}
|
||||
}
|
||||
|
||||
func (bm *BoundedMap) Set(key int, value interface{}) {
|
||||
func (bm *BoundedMap) Set(key string, value interface{}) {
|
||||
bm.mu.Lock()
|
||||
defer bm.mu.Unlock()
|
||||
if _, ok := bm.data[key]; ok {
|
||||
@@ -50,14 +50,14 @@ func (bm *BoundedMap) Set(key int, value interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func (bm *BoundedMap) Get(key int) (interface{}, bool) {
|
||||
func (bm *BoundedMap) Get(key string) (interface{}, bool) {
|
||||
bm.mu.RLock()
|
||||
defer bm.mu.RUnlock()
|
||||
v, ok := bm.data[key]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (bm *BoundedMap) Delete(key int) {
|
||||
func (bm *BoundedMap) Delete(key string) {
|
||||
bm.mu.Lock()
|
||||
defer bm.mu.Unlock()
|
||||
delete(bm.data, key)
|
||||
|
||||
Reference in New Issue
Block a user