slackapi / node-slack-sdk

Slack Developer Kit for Node.js
https://slack.dev/node-slack-sdk
MIT License
3.26k stars 656 forks source link

Typescript type error for `web.files.uploadV2()` arguments when using `file_uploads` #1743

Closed petgus-lyko closed 4 months ago

petgus-lyko commented 5 months ago

Packages:

Select all that apply:

Reproducible in:

The Slack SDK version

"slack/web-api": "^7.0.1",

Node.js runtime version

v18.16.0

OS info

ProductName: macOS ProductVersion: 14.1.2 BuildVersion: 23B92 Darwin Kernel Version 23.1.0: Mon Oct 9 21:27:27 PDT 2023; root:xnu-10002.41.9~6/RELEASE_X86_64

Steps to reproduce:

Here's a code example including some comments regarding the problem I'm facing.

import { WebAPICallResult, WebClient } from '@slack/web-api';

if (!process.env.SLACK_APP_INTEGRATION_TOKEN) {
  throw new Error('SLACK_APP_INTEGRATION_TOKEN environment variable is required');
}

const slackToken = process.env.SLACK_APP_INTEGRATION_TOKEN;

/**
 * Post a message with attached images to a Slack channel
 */
export async function notify(channelId: string, text: string, images: string[] | undefined) {
  try {
    const web = new WebClient(slackToken);

    let result: WebAPICallResult;

    if (images && images.length > 0) {
      // This works and is the recommended way to upload multiple files
      // https://slack.dev/node-slack-sdk/web-api#new-way---upload-multiple-files
      // But I get a type error so I disable type checking
      // @ts-ignore
      result = await web.files.uploadV2({
        initial_comment: text,
        channel_id: channelId,
        file_uploads: images.map(image => {
          return {
            file: image,
            filename: image.split('/').pop() || 'image',
          };
        }),
      });
    } else {
      result = await web.chat.postMessage({
        channel: channelId,
        text,
      });
    }

    if (result.ok) {
      console.info('Message posted successfully:', result);
      return;
    }

    console.error('Error posting message to Slack:', result);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

const [channel, message, ...images] = process.argv.slice(2);

if (!channel || !message) {
  console.error('Error: Missing required arguments');
  console.info('Usage: e2e-notify-slack.ts <channel_id> <message> <image1> <image2> ...');
  console.info('Example: e2e-notify-slack.ts XXXXXXXXX "Hello, world!" ./image1.png ./image2.png');
  process.exit(1);
}
notify(channel, message, images);

Expected result:

No typescript type errors

Actual result:

Argument of type '{ initial_comment: string; channel_id: string; file_uploads: { file: string; filename: string; }[]; }' is not assignable to parameter of type 'FilesUploadV2Arguments'.
  Type '{ initial_comment: string; channel_id: string; file_uploads: { file: string; filename: string; }[]; }' is not assignable to type 'FileUploadBinaryContents & FileThreadDestinationArgumentChannels & FileType & { filename?: string | undefined; initial_comment?: string | undefined; title?: string | undefined; } & { ...; } & TokenOverridable & { ...; }'.
    Property 'file' is missing in type '{ initial_comment: string; channel_id: string; file_uploads: { file: string; filename: string; }[]; }' but required in type 'FileUploadBinaryContents'.ts(2345)
files.d.ts(109, 5): 'file' is declared here.
zimeg commented 5 months ago

👋 Hey @petgus-lyko, thanks for raising this! I can confirm the same behavior and it seems like a bug with the types. We'll look into fixing this soon, but for now I think the @ts-ignore comment is needed.

zimeg commented 4 months ago

A fix for this just went out in @slack/web-api@7.0.2! Thank you again for sharing this and please let me know if there seems to be any more strangeness here 🙌