Edits history of script submission #23273 for ' Upload File (slack)'

  • bun
    One script reply has been approved by the moderators
    Ap­pro­ved
    import { WebClient } from "@slack/web-api"
    import * as wmill from "windmill-client"
    import { S3Object } from "windmill-client"
    
    export type DynSelect_channel = string
    
    // Dropdown of channels the token can see; private channels need groups:read.
    export async function channel(auth: RT.Slack) {
      if (!auth?.token) return []
      const client = new WebClient(auth.token)
      const res = await client.conversations
        .list({
          types: "public_channel,private_channel",
          exclude_archived: true,
          limit: 1000,
        })
        .catch(() =>
          client.conversations.list({ exclude_archived: true, limit: 1000 })
        )
      return (res.channels ?? []).map((c) => ({
        value: c.id!,
        label: `#${c.name}`,
      }))
    }
    
    /**
     * Upload File
     * Upload any file from Windmill object storage. With `channel` it is shared there (with an optional `initial_comment`, or as a thread reply with `thread_ts`); without it the file stays private to the uploader. Uses files.getUploadURLExternal + files.completeUploadExternal. Needs files:write (bot default; tick it for a user token); a bot must be in the channel.
     */
    export async function main(
      auth: RT.Slack,
      file: S3Object,
      filename: string,
      channel?: DynSelect_channel,
      title?: string,
      initial_comment?: string,
      thread_ts?: string
    ) {
      const bytes = await wmill.loadS3File(file)
      if (!bytes) {
        throw new Error("Could not load the file from object storage")
      }
    
      const client = new WebClient(auth.token)
      return await client.filesUploadV2(
        dropEmpty({
          file: Buffer.from(bytes),
          filename,
          channel_id: channel,
          title,
          initial_comment,
          thread_ts,
        }) as any
      )
    }
    
    function dropEmpty<T extends { [key: string]: any }>(params: T) {
      return Object.fromEntries(
        Object.entries(params).filter(
          ([, v]) => v !== undefined && v !== null && v !== ""
        )
      ) as T
    }
    

    Submitted by hugo989 2 hours ago