Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infer Slack Bolt TypeScript types #955

Closed
erkand-imeri opened this issue Jun 3, 2021 · 5 comments
Closed

Infer Slack Bolt TypeScript types #955

erkand-imeri opened this issue Jun 3, 2021 · 5 comments
Labels
bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented question M-T: User needs support to use the project TypeScript-specific
Milestone

Comments

@erkand-imeri
Copy link

Hello, after upgrading to Slack bolt "@slack/bolt": "^3.3.0",, i am getting this TypeScript errors for types not existing.

Was trying to dig deep into Slack Bolt framework to figure out the types but to no avail so far.

Any help would be much appreciated. Thanks in advance.

 export const isThreadReply = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ event, next }): Promise<void> => {
    if (event.thread_ts && next) {
      await next();
    }
  };
};

Property 'thread_ts' does not exist on type 'KnownEventFromType<"message">'. Property 'thread_ts' does not exist on type 'EKMAccessDeniedMessageEvent'.ts(2339)

export const isParentMessageFromBot = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ context, message, next }): Promise<void> => {
    if (context.botUserId === message.parent_user_id && next) {
      await next();
    }
  };
};

Property 'parent_user_id' does not exist on type 'KnownEventFromType<"message">'. Property 'parent_user_id' does not exist on type 'BotMessageEvent'.ts(2339)

export const isNotBotMessage = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
return async ({ event, next }): Promise<void> => {
  if (!event.bot_profile && next) {
    await next();
  }
};
};

Property 'bot_profile' does not exist on type 'KnownEventFromType<"message">'. Property 'bot_profile' does not exist on type 'GenericMessageEvent'.ts(2339)

@gitwave gitwave bot added the untriaged label Jun 3, 2021
@erkand-imeri
Copy link
Author

Hello, anyone can give me any hint?

@seratch seratch added bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented question M-T: User needs support to use the project TypeScript-specific and removed untriaged labels Jun 3, 2021
@seratch seratch added this to the 3.4.0 milestone Jun 3, 2021
@seratch
Copy link
Member

seratch commented Jun 3, 2021

@erkand-imeri Thanks for flagging this.

Unfortunately, the pull request #709 (included in v2.6.0) changed the behavior around message events. The change is good for safer typing, but it became more confusing for users. I'm going to improve this at #904 in the near future.

For this moment, if/else statements can help the TypeScript compiler understand which type should be chosen from the union type MessageEvent.

For instance, the following code compiles as event.subtype === undefined helps TS compiler determine the type of event as GenericMessageEvent.

export const isThreadReply = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ event, next }): Promise<void> => {
    if (event.subtype === undefined && event.thread_ts && next) {
      await next();
    }
  };
};

Similarly, the following works for the second example:

export const isParentMessageFromBot = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ context, message, next }): Promise<void> => {
    if (message.subtype === undefined && context.botUserId === message.parent_user_id && next) {
      await next();
    }
  };
};

But I found that even the latest revision does not work with the last example. I will include a fix for this in the next version, which we will release shortly.

Again, we'll improve this issue at #904. v3.5 or later should be working better for you. I do understand this type of error is frustrating when you use TypeScript. It'd be appreciated if you could understand the current situation around this project.

@erkand-imeri
Copy link
Author

erkand-imeri commented Jun 4, 2021

Hello @seratch thanks a lot for the response, in one of my other code example, i did this, i want your opinion if it's a good approach.

So, basically i am casting the message as GenericMessageEvent.

export const extractAttachments = (
  slackApp: App,
): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ context, message, next }): Promise<void> => {
    const genericMessage = message as GenericMessageEvent;

    try {
      const attachments = extractFileAttachments(genericMessage).attachments;
      context.attachmentData = await downloadAttachmentData(attachments);

      if (next) {
        await next();
      }
    } catch (e) {
      await writeFailedMessageReply({
        slackApp,
        channelId: genericMessage.channel,
        parentThreadId: String(genericMessage.thread_ts),
        who: genericMessage.user,
        what: e.message,
      });
    }
  };
};

Also, one more thing.

export const isNotBotMessage = (): Middleware<SlackEventMiddlewareArgs<'message'>> => {
  return async ({ event, next }): Promise<void> => {
    if (event.subtype === undefined && !event.bot_profile && next) {
      await next();
    }
  };
};

I am getting this error

Property 'bot_profile' does not exist on type 'GenericMessageEvent'.ts(2339)

I have checked the GenericMessageEvent interface and bot_profile does exist there.

export interface GenericMessageEvent {
  type: 'message';
  subtype: undefined;
  event_ts: string;
  team?: string;
  channel: string;
  user: string;
  bot_id?: string;
  bot_profile?: BotProfile;
  text?: string;
  ts: string;
  thread_ts?: string;
  channel_type: channelTypes;
  attachments?: MessageAttachment[];
  blocks?: (KnownBlock | Block)[];
  files?: File[];
  edited?: {
    user: string;
    ts: string;
  };
  client_msg_id?: string;
  parent_user_id?: string;

  // TODO: optional types that maybe should flow into other subtypes?
  is_starred?: boolean;
  pinned_to?: string[];
  reactions?: {
    name: string;
    count: number;
    users: string[];
  }[];
}

Why is it throwing an error?

@seratch
Copy link
Member

seratch commented Jun 4, 2021

@erkand-imeri Can you upgrade the bolt version to the latest v3.4.0, which was just released? It should work with the version (the reason why bot_profile exists is that I added by #957 and the change is included in v.3.4.0)

@erkand-imeri
Copy link
Author

Thanks a lot @seratch , that worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented question M-T: User needs support to use the project TypeScript-specific
Projects
None yet
Development

No branches or pull requests

2 participants