diff --git a/.changeset/fix-upload-image-alt-text.md b/.changeset/fix-upload-image-alt-text.md new file mode 100644 index 000000000..bc8545ae1 --- /dev/null +++ b/.changeset/fix-upload-image-alt-text.md @@ -0,0 +1,5 @@ +--- +"@slack/web-api": patch +--- + +fix: image alt text passed to `files.uploadV2` is now saved. Before, it was sent as `alt_text`, which Slack ignores. Add `alt_txt` to `files.uploadV2` and `files.getUploadURLExternal` arguments, and deprecate `alt_text` in both. A deprecated `alt_text` passed to `files.uploadV2` is still sent as `alt_txt` ([#2788](https://github.com/slackapi/node-slack-sdk/issues/2788)) diff --git a/docs/english/web-api.md b/docs/english/web-api.md index bbc601029..702aaeed0 100644 --- a/docs/english/web-api.md +++ b/docs/english/web-api.md @@ -498,7 +498,7 @@ are marked "public" when shared to a provided `channel_id`. Multiple files can also be uploaded at once, without needing to write a loop, using the `files_uploads` parameter. This accepts similar attributes as a single file: -* `alt_text`: A description of images for a screen-reader. +* `alt_txt`: A description of images for a screen-reader. * `content`: The file contents as a string. If omitted, `file` must be provided. * `file`: The file path or data to upload. If omitted, `content` must be provided. * `filename`: The name of the file. diff --git a/packages/web-api/src/WebClient.test.ts b/packages/web-api/src/WebClient.test.ts index 6d4984f05..65eac962c 100644 --- a/packages/web-api/src/WebClient.test.ts +++ b/packages/web-api/src/WebClient.test.ts @@ -1662,7 +1662,7 @@ describe('WebClient', () => { it('uploads multiple files', async () => { const scope = nock('https://slack.com') - .post('/api/files.getUploadURLExternal', { filename: 'test-png.png', length: 55292 }) + .post('/api/files.getUploadURLExternal', { filename: 'test-png.png', length: 55292, alt_txt: 'A test image' }) .reply(200, { ok: true, file_id: 'F0000000001', @@ -1717,6 +1717,7 @@ describe('WebClient', () => { { file: fs.createReadStream('./test/fixtures/test-png.png'), filename: 'test-png.png', + alt_txt: 'A test image', }, ], }); diff --git a/packages/web-api/src/WebClient.ts b/packages/web-api/src/WebClient.ts index e212cf5dd..23f1a6de1 100644 --- a/packages/web-api/src/WebClient.ts +++ b/packages/web-api/src/WebClient.ts @@ -502,7 +502,7 @@ export class WebClient extends Methods { const options = { filename: upload.filename, length: upload.length, - alt_text: upload.alt_text, + alt_txt: upload.alt_txt, snippet_type: upload.snippet_type, } as FilesGetUploadURLExternalArguments; if ('token' in upload) { diff --git a/packages/web-api/src/file-upload.test.ts b/packages/web-api/src/file-upload.test.ts index bd38a440e..f1b88cdb3 100644 --- a/packages/web-api/src/file-upload.test.ts +++ b/packages/web-api/src/file-upload.test.ts @@ -38,18 +38,29 @@ describe('file-upload', () => { sandbox.restore(); }); describe('getFileUploadJob', () => { + it('maps the deprecated alt_text to alt_txt', async () => { + const res = await getFileUploadJob( + { + filename: 'test.txt', + file: Buffer.from('test'), + alt_text: 'an image of a thing', + }, + logger, + ); + assert.strictEqual(res.alt_txt, 'an image of a thing'); + }); it('returns a fileUploadEntry', async () => { const valid = { filename: 'test.txt', file: Buffer.from('test'), title: 'My title', - alt_text: 'an image of a thing', + alt_txt: 'an image of a thing', initial_comment: 'lorem ipsum', }; const res = await getFileUploadJob(valid, logger); // supplied values assert.strictEqual(valid.initial_comment, res.initial_comment); - assert.strictEqual(valid.alt_text, res.alt_text); + assert.strictEqual(valid.alt_txt, res.alt_txt); assert.strictEqual(valid.title, res.title); assert.strictEqual(valid.filename, res.filename); @@ -116,7 +127,7 @@ describe('file-upload', () => { { file: './test/fixtures/test-png.png', filename: 'watermelon.png', - alt_text: 'cubed fruit for box eats', + alt_txt: 'cubed fruit for box eats', }, { content: 'howdy world!', @@ -136,7 +147,7 @@ describe('file-upload', () => { assert.strictEqual(valid.token, res[1].token); assert.strictEqual(valid.file_uploads[0].file, (res[0] as FileUploadBinaryContents).file); assert.strictEqual(valid.file_uploads[0].filename, res[0].filename); - assert.strictEqual(valid.file_uploads[0].alt_text, res[0].alt_text); + assert.strictEqual(valid.file_uploads[0].alt_txt, res[0].alt_txt); assert.strictEqual(valid.file_uploads[1].content, (res[1] as FileUploadStringContents).content); assert.strictEqual(valid.file_uploads[1].filename, res[1].filename); diff --git a/packages/web-api/src/file-upload.ts b/packages/web-api/src/file-upload.ts index ca6b707e1..09d54a624 100644 --- a/packages/web-api/src/file-upload.ts +++ b/packages/web-api/src/file-upload.ts @@ -26,7 +26,7 @@ export async function getFileUploadJob( const fileUploadJob: Record = { // supplied by user - alt_text: options.alt_text, + alt_txt: options.alt_txt ?? options.alt_text, blocks: options.blocks, channel_id: options.channels ?? options.channel_id, filename: options.filename ?? fileName, diff --git a/packages/web-api/src/methods.ts b/packages/web-api/src/methods.ts index d684ea1d4..5e19b8470 100644 --- a/packages/web-api/src/methods.ts +++ b/packages/web-api/src/methods.ts @@ -2130,7 +2130,7 @@ export abstract class Methods extends EventEmitter { * Supports a single file upload * Supply: * - (required) single file or content - * - (optional) channel, alt_text, snippet_type, + * - (optional) channel, alt_txt, snippet_type, * Supports multiple file uploads * Supply: * - multiple upload_files diff --git a/packages/web-api/src/types/request/files.ts b/packages/web-api/src/types/request/files.ts index af0794c94..228006ca5 100644 --- a/packages/web-api/src/types/request/files.ts +++ b/packages/web-api/src/types/request/files.ts @@ -95,6 +95,8 @@ export interface FilesGetUploadURLExternalArguments extends TokenOverridable { /** @description Size in bytes of the file being uploaded. */ length: number; /** @description Description of image for screen-reader. */ + alt_txt?: string; + /** @deprecated Slack does not use this. Use `alt_txt`. */ alt_text?: string; /** @description Syntax type of the snippet being uploaded. E.g. `python`. */ snippet_type?: string; @@ -158,7 +160,9 @@ type FileUpload = FileUploadContents & title?: string; }; export type FileUploadV2 = FileUpload & { - /** @description Description of image for screen-reader. */ + /** @description A description of images for a screen-reader. */ + alt_txt?: string; + /** @deprecated Use `alt_txt`. */ alt_text?: string; /** * @description An array of structured rich text blocks. If the `initial_comment` field is provided, the `blocks` field is ignored.