Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kentcdodds/slack

src/send-message.ts

51 lines · 1.5 KB · TypeScript
import { slackRequest } from './request.ts'
import { inputRecord, optionalBoolean, optionalString, requiredString } from './validation.ts'

type SendMessageResponse = {
  ok: boolean
  channel?: string
  ts?: string
  message?: unknown
  [key: string]: unknown
}

/** Preview or send a Slack message as the authorizing user. */
export default async function sendMessage(params: Record<string, unknown>) {
  const input = inputRecord(params)
  const channel = requiredString(input, 'channel')
  const text = requiredString(input, 'text')
  const blocks = input.blocks
  if (blocks !== undefined && !Array.isArray(blocks)) {
    throw new Error('blocks must be an array when provided.')
  }

  const payload: Record<string, unknown> = {
    channel,
    text,
    thread_ts: optionalString(input, 'threadTs'),
    unfurl_links: optionalBoolean(input, 'unfurlLinks'),
    unfurl_media: optionalBoolean(input, 'unfurlMedia'),
  }
  if (blocks !== undefined) payload.blocks = blocks

  if (input.dryRun === true) {
    return {
      dryRun: true,
      method: 'chat.postMessage',
      identity: 'authorizing-user',
      payload,
    }
  }

  if (input.confirm !== true) {
    throw new Error('Sending a Slack message requires confirm: true after explicit user approval of the destination and content.')
  }

  const result = await slackRequest<SendMessageResponse>('chat.postMessage', payload)
  return {
    ok: true,
    channel: result.channel ?? channel,
    ts: result.ts ?? null,
    message: result.message ?? null,
  }
}