fix: truncate long activity fields to prevent Discord rejection #18
@@ -224,6 +224,18 @@ func (r *discordRPC) processImage(imageURL, clientID, token string, ttl int64) (
|
||||
func (r *discordRPC) sendActivity(clientID, username, token string, data activity) error {
|
||||
pdk.Log(pdk.LogInfo, fmt.Sprintf("Sending activity for user %s: %s - %s", username, data.Details, data.State))
|
||||
|
||||
// Truncate text fields to Discord's 128-character limit
|
||||
data.Name = truncateText(data.Name)
|
||||
data.Details = truncateText(data.Details)
|
||||
data.State = truncateText(data.State)
|
||||
data.Assets.LargeText = truncateText(data.Assets.LargeText)
|
||||
|
||||
// Omit URLs that exceed Discord's 256-character limit
|
||||
data.DetailsURL = truncateURL(data.DetailsURL)
|
||||
data.StateURL = truncateURL(data.StateURL)
|
||||
data.Assets.LargeURL = truncateURL(data.Assets.LargeURL)
|
||||
data.Assets.SmallURL = truncateURL(data.Assets.SmallURL)
|
||||
|
||||
// Try track artwork first, fall back to Navidrome logo
|
||||
usingDefaultImage := false
|
||||
processedImage, err := r.processImage(data.Assets.LargeImage, clientID, token, imageCacheTTL)
|
||||
|
||||
+43
@@ -435,6 +435,49 @@ var _ = Describe("discordRPC", func() {
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("truncates long text fields and omits long URLs", func() {
|
||||
host.CacheMock.On("GetString", discordImageKey).Return("mp:cached/art", true, nil).Once()
|
||||
host.CacheMock.On("GetString", discordImageKey).Return("mp:cached/logo", true, nil).Once()
|
||||
|
||||
longName := strings.Repeat("N", 200)
|
||||
longTitle := strings.Repeat("T", 200)
|
||||
longArtist := strings.Repeat("A", 200)
|
||||
longAlbum := strings.Repeat("B", 200)
|
||||
longURL := "https://example.com/" + strings.Repeat("x", 237)
|
||||
|
||||
host.WebSocketMock.On("SendText", "testuser", mock.MatchedBy(func(msg string) bool {
|
||||
// Text fields should be truncated to 128 runes (127 + "…")
|
||||
truncatedName := strings.Repeat("N", 127) + "…"
|
||||
truncatedTitle := strings.Repeat("T", 127) + "…"
|
||||
truncatedArtist := strings.Repeat("A", 127) + "…"
|
||||
truncatedAlbum := strings.Repeat("B", 127) + "…"
|
||||
return strings.Contains(msg, truncatedName) &&
|
||||
strings.Contains(msg, truncatedTitle) &&
|
||||
strings.Contains(msg, truncatedArtist) &&
|
||||
strings.Contains(msg, truncatedAlbum) &&
|
||||
!strings.Contains(msg, longURL) // URL should be omitted
|
||||
})).Return(nil)
|
||||
|
||||
err := r.sendActivity("client123", "testuser", "token123", activity{
|
||||
Application: "client123",
|
||||
Name: longName,
|
||||
Type: 2,
|
||||
Details: longTitle,
|
||||
DetailsURL: longURL,
|
||||
State: longArtist,
|
||||
StateURL: longURL,
|
||||
Assets: activityAssets{
|
||||
LargeImage: "https://example.com/art.jpg",
|
||||
LargeText: longAlbum,
|
||||
LargeURL: longURL,
|
||||
SmallImage: navidromeLogoURL,
|
||||
SmallText: "Navidrome",
|
||||
SmallURL: longURL,
|
||||
},
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("clearActivity", func() {
|
||||
|
||||
Reference in New Issue
Block a user