diff --git a/examples/getting-started-typescript/src/app.ts b/examples/getting-started-typescript/src/app.ts index e5f944b65..f78d351e8 100644 --- a/examples/getting-started-typescript/src/app.ts +++ b/examples/getting-started-typescript/src/app.ts @@ -1,7 +1,5 @@ -/* eslint-disable no-console */ -/* eslint-disable import/no-internal-modules */ import './utils/env'; -import { App, LogLevel } from '@slack/bolt'; +import { App, type BlockButtonAction, LogLevel } from '@slack/bolt'; const app = new App({ token: process.env.SLACK_BOT_TOKEN, @@ -41,12 +39,11 @@ app.message('hello', async ({ message, say }) => { } }); -app.action('button_click', async ({ body, ack, say }) => { +app.action('button_click', async ({ body, ack, say }) => { // Acknowledge the action await ack(); // we know that this event comes from a button click from a message in a channel, so `say` will be available. - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await say!(`<@${body.user.id}> clicked the button`); + await say(`<@${body.user.id}> clicked the button`); }); (async () => { diff --git a/examples/getting-started-typescript/src/basic.ts b/examples/getting-started-typescript/src/basic.ts index e58f9ddc6..6a690d546 100644 --- a/examples/getting-started-typescript/src/basic.ts +++ b/examples/getting-started-typescript/src/basic.ts @@ -1,6 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable no-console */ -/* eslint-disable import/no-internal-modules */ import './utils/env'; import { App, type BlockAction, type BotMessageEvent, LogLevel, subtype } from '@slack/bolt'; @@ -77,6 +74,7 @@ app.event('team_join', async ({ event, client, logger }) => { }); app.message(subtype('bot_message'), async ({ message, logger }) => { + // TODO: the need to cast here is due to https://github.com/slackapi/bolt-js/issues/796 const botMessage = message as BotMessageEvent; logger.info(`The bot user ${botMessage.user} said ${botMessage.text}`); }); @@ -118,11 +116,11 @@ app.action( await ack(); try { // Make sure the event is not in a view - if (body.message) { + if (body.message && body.channel) { await client.reactions.add({ name: 'white_check_mark', - timestamp: body.message?.ts, - channel: body.channel!.id, // if the body has a message, we know it has a channel, too. + timestamp: body.message.ts, + channel: body.channel.id, // if the body has a message, we know it has a channel, too. }); } } catch (error) { @@ -132,14 +130,10 @@ app.action( ); // Your middleware will be called every time an interactive component with the action_id “approve_button” is triggered -app.action('approve_button', async ({ ack, say }) => { +app.action('approve_button', async ({ ack, say }) => { // Acknowledge action request await ack(); - // `say` is possibly undefined because an action could come from a surface where we cannot post message, e.g. a view. - // we will use a non-null assertion (!) to tell TypeScript to ignore the fact it may be undefined, - // but take care about the originating surface for these events when using these utilities! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await say!('Request approved 👍'); + await say('Request approved 👍'); }); (async () => { diff --git a/src/types/actions/block-action.ts b/src/types/actions/block-action.ts index 9c49a0534..1a0b4d71e 100644 --- a/src/types/actions/block-action.ts +++ b/src/types/actions/block-action.ts @@ -248,6 +248,7 @@ export interface BlockAction inputs?: FunctionInputs; } & (Action extends Exclude ? // all action types except dialog submission and steps from apps have a channel context + // TODO: not exactly true: a block action could occur from a view. should improve this. { say: SayFn } : unknown);