Conversation
|
It would be better to separate the Slack scrobbler as a standalone plugin, similar to the Discord RPC. The Scrobbler plugin is intended for services like LastFM or Listenbrainz. |
|
e.g. |
|
OK, I'll rework this as a standalone plugin. |
- Add isSlackNowPlayingConfig type guard function for better type checking - Replace unsafe type assertions with proper type guards
|
I wouldn't recommend adding a dependency like axios, especially in 2025, when the built-in fetch is as good. |
…node in Slack client
|
Why the extra dependency for formdata? |
That was a leftover when I was trying formdata instead of |
package.json
Outdated
| "fetch-blob": "^4.0.0", | ||
| "file-type": "^20.5.0", | ||
| "filenamify": "6.0.0", | ||
| "formdata-node": "^6.0.3", |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
package.json
Outdated
| "es-hangul": "2.3.3", | ||
| "fast-average-color": "9.5.0", | ||
| "fast-equals": "5.2.2", | ||
| "fetch-blob": "^4.0.0", |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
why so many polyfills? |
|
I believe that I've addressed all of the feedback that you've given. If there's something I've missed, or a new issue, please let me know. |
|
It would be hypocritical of me to say this in another PR and not here as well, so here we go.
Please do not use |
Reverted all languages except EN & ES (since I speak those languages and know that the meaning is correct). |
|
I've updated this PR with the latest commits from master. Is there any interest in merging it? |
There was a problem hiding this comment.
Pull Request Overview
This PR adds a Slack Now Playing plugin that allows users to automatically set their Slack status to the currently playing song. The plugin integrates with Slack's API to update user status with song information and album art as custom emojis.
- Implements a Slack API client with caching and rate limiting
- Creates a configuration interface for Slack tokens and emoji settings
- Adds internationalization support for English and Spanish
Reviewed Changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/plugins/slack-now-playing/slack-api-client.ts |
Core Slack API client with rate limiting, caching, and error handling |
src/plugins/slack-now-playing/main.ts |
Main plugin logic for status updates and emoji management |
src/plugins/slack-now-playing/menu.ts |
Configuration UI for Slack tokens and settings |
src/plugins/slack-now-playing/index.ts |
Plugin entry point and configuration |
src/i18n/resources/en.json |
English translations for the plugin |
src/i18n/resources/es.json |
Spanish translations for the plugin |
package.json |
Development environment configuration update |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| // @ts-ignore | ||
| fetchOptions.agent = new https.Agent({ rejectUnauthorized: false }); |
There was a problem hiding this comment.
Use a proper type assertion instead of @ts-ignore. Consider creating a proper type for the agent option or using a more specific type annotation.
| // @ts-ignore | |
| fetchOptions.agent = new https.Agent({ rejectUnauthorized: false }); | |
| (fetchOptions as any).agent = new https.Agent({ rejectUnauthorized: false }); |
| } | ||
|
|
||
| // Prepare the form data for the API request using native Node.js APIs | ||
| const formData = new FormData(); |
There was a problem hiding this comment.
FormData is imported from 'formdata-node' but being used as native FormData here. This could cause issues since the import at the top suggests the intention is to use the Node.js compatible FormData.
| // Emoji not found, no need to delete | ||
| console.error(`Unexpected error deleting emoji: ${apiError.message}`, { | ||
| name: apiError.name, | ||
| stack: apiError.stack | ||
| }); |
There was a problem hiding this comment.
The error message and logging logic is incorrect. When emoji_not_found is encountered, it should be treated as success, not logged as an error.
| // Emoji not found, no need to delete | |
| console.error(`Unexpected error deleting emoji: ${apiError.message}`, { | |
| name: apiError.name, | |
| stack: apiError.stack | |
| }); | |
| // Emoji not found, no need to delete; treat as success. | |
| // No error to log here. |
| /** Base URL for all Slack API requests */ | ||
| private readonly baseUrl = 'https://slack.com/api'; | ||
| /** Cache for GET requests to reduce API calls */ | ||
| private readonly cache: Map<string, CacheEntry<any>> = new Map(); |
There was a problem hiding this comment.
Using 'any' type reduces type safety. Consider using generics or a more specific type for the cache values.
| private readonly cache: Map<string, CacheEntry<any>> = new Map(); | |
| private readonly cache: Map<string, CacheEntry<TCache>> = new Map(); |
| // Read the file as a Buffer and append directly to FormData | ||
| const fileBuffer = await fs.promises.readFile(filePath); | ||
| const filename = path.basename(filePath) || 'emoji.png'; | ||
| const imageFile = new File([fileBuffer], filename); |
There was a problem hiding this comment.
The File constructor is a Web API that may not be available in Node.js environment. This could cause runtime errors in the Electron main process.
There was a problem hiding this comment.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
eslint
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ········(error.message.includes('token')·||·error.message.includes('authentication')) with ······(error.message.includes('token')·||⏎········error.message.includes('authentication'))⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.' with ⏎········'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.',⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·update·Slack·status:·${validationResult.errors.join(',·')} with ⏎········Cannot·update·Slack·status:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace songInfo:·SongInfo,·config:·SlackNowPlayingConfig with ⏎··songInfo:·SongInfo,⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace await·uploadEmojiToSlack(songInfo,·config with (await·uploadEmojiToSlack(songInfo,·config)
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace songInfo:·SongInfo,·config:·SlackNowPlayingConfig with ⏎··songInfo:·SongInfo,⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·upload·emoji·to·Slack:·${validationResult.errors.join(',·')} with ⏎········Cannot·upload·emoji·to·Slack:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ⏎
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·preparing·album·art·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)} with ⏎········Error·preparing·album·art·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Invalid·emoji·name:·${config.emojiName}.·Emoji·names·can·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores. with ⏎············Invalid·emoji·name:·${config.emojiName}.·Emoji·names·can·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores.,⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Album·art·image·is·too·large·for·Slack·emoji·(max·128KB).' with ⏎············'Album·art·image·is·too·large·for·Slack·emoji·(max·128KB).',⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Emoji·name·'${config.emojiName}'·is·already·taken.·This·should·not·happen·as·we·check·for·existing·emojis. with ⏎············Emoji·name·'${config.emojiName}'·is·already·taken.·This·should·not·happen·as·we·check·for·existing·emojis.,⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``Error·uploading·emoji:·${errorCode},·apiError.responseData with `⏎············`Error·uploading·emoji:·${errorCode}`,⏎············apiError.responseData,⏎··········`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·uploading·emoji·to·Slack:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)} with ⏎··········Error·uploading·emoji·to·Slack:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)},⏎········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``Unexpected·error·uploading·emoji·to·Slack:·${error.message}, with `⏎········`Unexpected·error·uploading·emoji·to·Slack:·${error.message}`,⏎·······`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace stack:·error.stack with ··stack:·error.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace } with ··},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Unexpected·error·uploading·emoji·to·Slack:·${String(error)} with ⏎········Unexpected·error·uploading·emoji·to·Slack:·${String(error)},⏎······
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Failed·to·fetch·album·art:·HTTP·${response.status}·${response.statusText} with ⏎··········Failed·to·fetch·album·art:·HTTP·${response.status}·${response.statusText},⏎········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Network·error·fetching·album·art:·${fetchError·instanceof·Error·?·fetchError.message·:·String(fetchError)} with ⏎········Network·error·fetching·album·art:·${fetchError·instanceof·Error·?·fetchError.message·:·String(fetchError)},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·processing·album·art·data:·${bufferError·instanceof·Error·?·bufferError.message·:·String(bufferError)} with ⏎········Error·processing·album·art·data:·${bufferError·instanceof·Error·?·bufferError.message·:·String(bufferError)},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·writing·album·art·to·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)} with ⏎········Error·writing·album·art·to·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)},⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace config:·SlackNowPlayingConfig with ⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·check·emoji·existence:·${validationResult.errors.join(',·')} with ⏎········Cannot·check·emoji·existence:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace response.emoji·&&·typeof·response.emoji·===·'object'·&&·config.emojiName·in·response.emoji with ⏎········response.emoji·&&⏎········typeof·response.emoji·===·'object'·&&⏎········config.emojiName·in·response.emoji⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.' with ⏎············'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.',⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Slack·API·rate·limit·exceeded.·Please·try·again·later.' with ⏎············'Slack·API·rate·limit·exceeded.·Please·try·again·later.',⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·checking·emoji·list:·${errorCode·||·apiError.message} with ⏎············Error·checking·emoji·list:·${errorCode·||·apiError.message},⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Error·checking·emoji·list:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)} with ⏎··········[Slack]·Error·checking·emoji·list:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)},⏎········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${error.message}, with `⏎········`[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${error.message}`,⏎·······`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace stack:·error.stack with ··stack:·error.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ······} with ········},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${String(error)} with ⏎········[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${String(error)},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace config:·SlackNowPlayingConfig with ⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·delete·emoji:·${validationResult.errors.join(',·')} with ⏎········Cannot·delete·emoji:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``Unexpected·error·deleting·emoji:·${apiError.message}, with `⏎············`Unexpected·error·deleting·emoji:·${apiError.message}`,⏎···········`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ············stack:·apiError.stack with ··············stack:·apiError.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··········} with ············},⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``[Slack]·Unexpected·error·in·deleteExistingEmoji:·${error.message}, with `⏎········`[Slack]·Unexpected·error·in·deleteExistingEmoji:·${error.message}`,⏎·······`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ········stack:·error.stack with ··········stack:·error.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ······} with ········},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Unexpected·error·in·deleteExistingEmoji:·${String(error)} with ⏎········[Slack]·Unexpected·error·in·deleteExistingEmoji:·${String(error)},⏎······
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace signal with (signal)
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-unsafe-call> reported by reviewdog 🐶
Unsafe call of a(n) error type typed value.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Slack·Now·Playing·configuration·validation·failed:·${validationResult.errors.join(',·')} with ⏎··············Slack·Now·Playing·configuration·validation·failed:·${validationResult.errors.join(',·')},⏎············
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type any assigned to a parameter of type SongInfo.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ⏎··········.catch(error with .catch((error)
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ············ with ··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·············· with ············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··············if·(error.message.includes('authentication')·||·error.message.includes('token') with ············if·(⏎··············error.message.includes('authentication')·||⏎··············error.message.includes('token')⏎············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ················console.error('Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.'); with ··············console.error(⏎················'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.',
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace } with );
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··········}⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··else·if·(error.message.includes('rate·limit')·||·error.message.includes('rate_limited') with else·if·(⏎··············error.message.includes('rate·limit')·||⏎··············error.message.includes('rate_limited')⏎············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ················console.error('Slack·API·rate·limit·exceeded.·Please·try·again·later.'); with ··············console.error(⏎················'Slack·API·rate·limit·exceeded.·Please·try·again·later.',
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace } with );
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··········}⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·············· with ············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any value.
🚫 [eslint] <@typescript-eslint/no-unsafe-call> reported by reviewdog 🐶
Unsafe call of a(n) any typed value.
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .getConfig on an any value.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Slack·Now·Playing·configuration·validation·failed:·${error·instanceof·Error·?·error.message·:·String(error)} with ⏎············Slack·Now·Playing·configuration·validation·failed:·${error·instanceof·Error·?·error.message·:·String(error)},⏎··········
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/consistent-type-imports> reported by reviewdog 🐶
Imports "BrowserWindow" are only used as type.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶
There should be at least one empty line between import groups
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Invalid·Slack·cookie·token·format·(should·start·with·"xoxd-")' with ⏎······'Invalid·Slack·cookie·token·format·(should·start·with·"xoxd-")',⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Invalid·emoji·name·format·(should·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores)' with ⏎······'Invalid·emoji·name·format·(should·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores)',⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/await-thenable> reported by reviewdog 🐶
Unexpected await of a non-Promise (non-"Thenable") value.
🚫 [eslint] <@typescript-eslint/require-await> reported by reviewdog 🐶
Async arrow function 'onMenu' has no 'await' expression.
🚫 [eslint] <@typescript-eslint/consistent-type-imports> reported by reviewdog 🐶
All imports in the declaration are only used as types. Use import type.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶
There should be at least one empty line between import groups
🚫 [eslint] <importPlugin/no-unresolved> reported by reviewdog 🐶
Unable to resolve path to module 'formdata-node'.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶node:https import should occur before import of formdata-node
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·string·|·number·|·boolean·|·null·|·undefined·|·string[] with ⏎····|·string⏎····|·number⏎····|·boolean⏎····|·null⏎····|·undefined⏎····|·string[]⏎···
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace headers:·Record<string,·string>,·options:·{·disableSSLValidation?:·boolean·}·=·{} with ⏎····headers:·Record<string,·string>,⏎····options:·{·disableSSLValidation?:·boolean·}·=·{},⏎··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/ban-ts-comment> reported by reviewdog 🐶
Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-redundant-type-constituents> reported by reviewdog 🐶
'FormData' is an 'error' type that acts as 'any' and overrides all other types in this union type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prefer-const> reported by reviewdog 🐶
'headers' is never reassigned. Use 'const' instead.
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an error typed value.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an error typed value.
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type error typed assigned to a parameter of type { [s: string]: unknown; } | ArrayLike<unknown>.
🚫 [eslint] <@typescript-eslint/no-base-to-string> reported by reviewdog 🐶
'value' will use Object's default stringification format ('[object Object]') when stringified.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·!process.env.NODE_ENV·||·process.env.NODE_ENV·===·'development'·||·process.env.NODE_ENV·===·'test' with ⏎··········!process.env.NODE_ENV·||⏎··········process.env.NODE_ENV·===·'development'·||⏎··········process.env.NODE_ENV·===·'test',
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any value.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-unnecessary-type-assertion> reported by reviewdog 🐶
This assertion is unnecessary since it does not change the type of the expression.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace string,·string·|·number·|·boolean·|·string[]·|·number[] with ⏎······string,⏎······string·|·number·|·boolean·|·string[]·|·number[]⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ⏎·······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·!process.env.NODE_ENV·||·process.env.NODE_ENV·===·'development'·||·process.env.NODE_ENV·===·'test' with ⏎··········!process.env.NODE_ENV·||⏎··········process.env.NODE_ENV·===·'development'·||⏎··········process.env.NODE_ENV·===·'test',
🚫 [eslint] <@typescript-eslint/no-unnecessary-type-assertion> reported by reviewdog 🐶
This assertion is unnecessary since it does not change the type of the expression.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
There was a problem hiding this comment.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
eslint
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·writing·album·art·to·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)} with ⏎········Error·writing·album·art·to·file:·${fileError·instanceof·Error·?·fileError.message·:·String(fileError)},⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace config:·SlackNowPlayingConfig with ⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·check·emoji·existence:·${validationResult.errors.join(',·')} with ⏎········Cannot·check·emoji·existence:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace response.emoji·&&·typeof·response.emoji·===·'object'·&&·config.emojiName·in·response.emoji with ⏎········response.emoji·&&⏎········typeof·response.emoji·===·'object'·&&⏎········config.emojiName·in·response.emoji⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.' with ⏎············'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.',⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Slack·API·rate·limit·exceeded.·Please·try·again·later.' with ⏎············'Slack·API·rate·limit·exceeded.·Please·try·again·later.',⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Error·checking·emoji·list:·${errorCode·||·apiError.message} with ⏎············Error·checking·emoji·list:·${errorCode·||·apiError.message},⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Error·checking·emoji·list:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)} with ⏎··········[Slack]·Error·checking·emoji·list:·${apiError·instanceof·Error·?·apiError.message·:·String(apiError)},⏎········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${error.message}, with `⏎········`[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${error.message}`,⏎·······`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace stack:·error.stack with ··stack:·error.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ······} with ········},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${String(error)} with ⏎········[Slack]·Unexpected·error·in·ensureEmojiDoesNotExist:·${String(error)},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace config:·SlackNowPlayingConfig with ⏎··config:·SlackNowPlayingConfig,⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Cannot·delete·emoji:·${validationResult.errors.join(',·')} with ⏎········Cannot·delete·emoji:·${validationResult.errors.join(',·')},⏎······
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``Unexpected·error·deleting·emoji:·${apiError.message}, with `⏎············`Unexpected·error·deleting·emoji:·${apiError.message}`,⏎···········`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ············stack:·apiError.stack with ··············stack:·apiError.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··········} with ············},⏎··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ``[Slack]·Unexpected·error·in·deleteExistingEmoji:·${error.message}, with `⏎········`[Slack]·Unexpected·error·in·deleteExistingEmoji:·${error.message}`,⏎·······`
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ········stack:·error.stack with ··········stack:·error.stack,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ······} with ········},⏎······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace [Slack]·Unexpected·error·in·deleteExistingEmoji:·${String(error)} with ⏎········[Slack]·Unexpected·error·in·deleteExistingEmoji:·${String(error)},⏎······
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace signal with (signal)
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
'error' is defined but never used.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-unsafe-call> reported by reviewdog 🐶
Unsafe call of a(n) error type typed value.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Slack·Now·Playing·configuration·validation·failed:·${validationResult.errors.join(',·')} with ⏎··············Slack·Now·Playing·configuration·validation·failed:·${validationResult.errors.join(',·')},⏎············
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type any assigned to a parameter of type SongInfo.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ⏎··········.catch(error with .catch((error)
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ············ with ··········
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·············· with ············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··············if·(error.message.includes('authentication')·||·error.message.includes('token') with ············if·(⏎··············error.message.includes('authentication')·||⏎··············error.message.includes('token')⏎············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ················console.error('Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.'); with ··············console.error(⏎················'Slack·authentication·failed.·Please·check·your·API·token·and·cookie·token.',
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace } with );
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··········}⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ··else·if·(error.message.includes('rate·limit')·||·error.message.includes('rate_limited') with else·if·(⏎··············error.message.includes('rate·limit')·||⏎··············error.message.includes('rate_limited')⏎············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ················console.error('Slack·API·rate·limit·exceeded.·Please·try·again·later.'); with ··············console.error(⏎················'Slack·API·rate·limit·exceeded.·Please·try·again·later.',
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace } with );
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ··········}⏎
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·············· with ············
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ··
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any value.
🚫 [eslint] <@typescript-eslint/no-unsafe-call> reported by reviewdog 🐶
Unsafe call of a(n) any typed value.
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .getConfig on an any value.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace Slack·Now·Playing·configuration·validation·failed:·${error·instanceof·Error·?·error.message·:·String(error)} with ⏎············Slack·Now·Playing·configuration·validation·failed:·${error·instanceof·Error·?·error.message·:·String(error)},⏎··········
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/consistent-type-imports> reported by reviewdog 🐶
Imports "BrowserWindow" are only used as type.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶
There should be at least one empty line between import groups
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Invalid·Slack·cookie·token·format·(should·start·with·"xoxd-")' with ⏎······'Invalid·Slack·cookie·token·format·(should·start·with·"xoxd-")',⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace 'Invalid·emoji·name·format·(should·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores)' with ⏎······'Invalid·emoji·name·format·(should·only·contain·lowercase·letters,·numbers,·hyphens,·and·underscores)',⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/await-thenable> reported by reviewdog 🐶
Unexpected await of a non-Promise (non-"Thenable") value.
🚫 [eslint] <@typescript-eslint/require-await> reported by reviewdog 🐶
Async arrow function 'onMenu' has no 'await' expression.
🚫 [eslint] <@typescript-eslint/consistent-type-imports> reported by reviewdog 🐶
All imports in the declaration are only used as types. Use import type.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶
There should be at least one empty line between import groups
🚫 [eslint] <importPlugin/no-unresolved> reported by reviewdog 🐶
Unable to resolve path to module 'formdata-node'.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶node:https import should occur before import of formdata-node
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·string·|·number·|·boolean·|·null·|·undefined·|·string[] with ⏎····|·string⏎····|·number⏎····|·boolean⏎····|·null⏎····|·undefined⏎····|·string[]⏎···
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace headers:·Record<string,·string>,·options:·{·disableSSLValidation?:·boolean·}·=·{} with ⏎····headers:·Record<string,·string>,⏎····options:·{·disableSSLValidation?:·boolean·}·=·{},⏎··
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/ban-ts-comment> reported by reviewdog 🐶
Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-redundant-type-constituents> reported by reviewdog 🐶
'FormData' is an 'error' type that acts as 'any' and overrides all other types in this union type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prefer-const> reported by reviewdog 🐶
'headers' is never reassigned. Use 'const' instead.
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an error typed value.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an error typed value.
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type error typed assigned to a parameter of type { [s: string]: unknown; } | ArrayLike<unknown>.
🚫 [eslint] <@typescript-eslint/no-base-to-string> reported by reviewdog 🐶
'value' will use Object's default stringification format ('[object Object]') when stringified.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·!process.env.NODE_ENV·||·process.env.NODE_ENV·===·'development'·||·process.env.NODE_ENV·===·'test' with ⏎··········!process.env.NODE_ENV·||⏎··········process.env.NODE_ENV·===·'development'·||⏎··········process.env.NODE_ENV·===·'test',
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any value.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-unnecessary-type-assertion> reported by reviewdog 🐶
This assertion is unnecessary since it does not change the type of the expression.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace string,·string·|·number·|·boolean·|·string[]·|·number[] with ⏎······string,⏎······string·|·number·|·boolean·|·string[]·|·number[]⏎····
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ⏎·······
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace ·!process.env.NODE_ENV·||·process.env.NODE_ENV·===·'development'·||·process.env.NODE_ENV·===·'test' with ⏎··········!process.env.NODE_ENV·||⏎··········process.env.NODE_ENV·===·'development'·||⏎··········process.env.NODE_ENV·===·'test',
🚫 [eslint] <@typescript-eslint/no-unnecessary-type-assertion> reported by reviewdog 🐶
This assertion is unnecessary since it does not change the type of the expression.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ,
- Send token in request body instead of Authorization header - URL-encode cookie value for proper handling of + and / chars - Use native Node.js fetch (Chromium's net.fetch forbids Cookie headers) - Remove unused formdata-node dependency, use native FormData - Fix TypeScript strict mode issues (any → unknown, proper type guards) - Sync with upstream pear-devs/pear-desktop 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tive fetch - Use session.fromPartition for dedicated Slack API session - Set URL-encoded cookie via session.cookies.set() - Use session.fetch with credentials: 'include' - More consistent with other plugins in the codebase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
71752b9 to
4121ff1
Compare
|
I've finally gotten some free time to rework this plugin and I think it's ready for prime time. Thanks for your patience on this one! |
I'd like to thank our users for their patience, since the entire project is moving really slowly 😔 |
I wanted to be able to push my "Now Playing" status to my company's Slack.