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

No way to get at concrete Event Types #2316

Closed
alper opened this issue Nov 2, 2024 · 5 comments
Closed

No way to get at concrete Event Types #2316

alper opened this issue Nov 2, 2024 · 5 comments
Labels
question M-T: User needs support to use the project TypeScript-specific

Comments

@alper
Copy link

alper commented Nov 2, 2024

Not sure what's happening, I have:

 @Event('message')
  public message_event(args: SlackEventMiddlewareArgs<"message">) {
    this.logger.error({msg: "Received a message"});

    const event = args.message as GenericMessageEvent

    this.logger.error({msg: args.message.type});

  }
}

But GenericMessageEvent is not exported?

I see no real way to go from KnownEventFromType<'message'> to an actual SlackEvent. What's the point here?

Similar to #904 and #955

@alper
Copy link
Author

alper commented Nov 2, 2024

OK. The solution is to drop Typescript, JSON.stringify the args into something like this:

{
    "body": {
        "token": "j98k5l0eEFEgLTwbwVKyGmoK",
        "team_id": "T07UH71FE9Z",
        "context_team_id": "T07UH71FE9Z",
        "context_enterprise_id": null,
        "api_app_id": "A07UH7DHLDR",
        "event": {
            "user": "U07U2P6N4K1",
            "type": "message",
            "ts": "1730507274.093719",
            "client_msg_id": "31365da1-4076-4d1c-a540-0ba4b347d4d8",
            "text": "Fuck",
            "team": "T07UH71FE9Z",
            "blocks": [
                {
                    "type": "rich_text",
                    "block_id": "tOdIz",
                    "elements": [
                        {
                            "type": "rich_text_section",
                            "elements": [
                                {
                                    "type": "text",
                                    "text": "Fuck"
                                }
                            ]
                        }
                    ]
                }
            ],
            "channel": "C07UEE5DRMK",
            "event_ts": "1730507274.093719",
            "channel_type": "channel"
        },
        "type": "event_callback",
        "event_id": "Ev07UKCNUD4K",
        "event_time": 1730507274,
        "authorizations": [
            {
                "enterprise_id": null,
                "team_id": "T07UH71FE9Z",
                "user_id": "U07U32JN3C7",
                "is_bot": true,
                "is_enterprise_install": false
            }
        ],
        "is_ext_shared_channel": false,
        "event_context": "4-eyJldCI6Im1lc3NhZ2UiLCJ0aWQiOiJUMDdVSDcxRkU5WiIsImFpZCI6IkEwN1VIN0RITERSIiwiY2lkIjoiQzA3VUVFNURSTUsifQ"
    },
    "payload": {
        "user": "U07U2P6N4K1",
        "type": "message",
        "ts": "1730507274.093719",
        "client_msg_id": "31365da1-4076-4d1c-a540-0ba4b347d4d8",
        "text": "Fuck",
        "team": "T07UH71FE9Z",
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "tOdIz",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "text",
                                "text": "Fuck"
                            }
                        ]
                    }
                ]
            }
        ],
        "channel": "C07UEE5DRMK",
        "event_ts": "1730507274.093719",
        "channel_type": "channel"
    },
    "event": {
        "user": "U07U2P6N4K1",
        "type": "message",
        "ts": "1730507274.093719",
        "client_msg_id": "31365da1-4076-4d1c-a540-0ba4b347d4d8",
        "text": "Fuck",
        "team": "T07UH71FE9Z",
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "tOdIz",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "text",
                                "text": "Fuck"
                            }
                        ]
                    }
                ]
            }
        ],
        "channel": "C07UEE5DRMK",
        "event_ts": "1730507274.093719",
        "channel_type": "channel"
    },
    "message": {
        "user": "U07U2P6N4K1",
        "type": "message",
        "ts": "1730507274.093719",
        "client_msg_id": "31365da1-4076-4d1c-a540-0ba4b347d4d8",
        "text": "Fuck",
        "team": "T07UH71FE9Z",
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "tOdIz",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "text",
                                "text": "Fuck"
                            }
                        ]
                    }
                ]
            }
        ],
        "channel": "C07UEE5DRMK",
        "event_ts": "1730507274.093719",
        "channel_type": "channel"
    },
    "context": {
        "isEnterpriseInstall": false,
        "botToken": "xoxb-7969239524339-7955086751415-ZlMSZQ0zf3SyEp8Cq6sSoL4O",
        "botUserId": "U07U32JN3C7",
        "botId": "B07V6CGMMG8",
        "userId": "U07U2P6N4K1",
        "teamId": "T07UH71FE9Z",
        "retryNum": 0,
        "retryReason": ""
    },
    "client": {
        "_events": {},
        "_eventsCount": 0,
        "admin": {
            "analytics": {},
            "apps": {
                "approved": {},
                "requests": {},
                "restricted": {},
                "activities": {}
            },
            "auth": {
                "policy": {}
            },
            "barriers": {},
            "conversations": {
                "ekm": {},
                "restrictAccess": {}
            },
            "emoji": {},
            "functions": {
                "permissions": {}
            },
            "inviteRequests": {
                "approved": {},
                "denied": {}
            },
            "teams": {
                "admins": {},
                "owners": {},
                "settings": {}
            },
            "roles": {},
            "usergroups": {},
            "users": {
                "session": {},
                "unsupportedVersions": {}
            },
            "workflows": {
                "collaborators": {},
                "permissions": {}
            }
        },
        "api": {},
        "apps": {
            "connections": {},
            "event": {
                "authorizations": {}
            },
            "manifest": {}
        },
        "assistant": {
            "threads": {}
        },
        "auth": {
            "teams": {}
        },
        "bots": {},
        "bookmarks": {},
        "calls": {
            "participants": {}
        },
        "chat": {
            "scheduledMessages": {}
        },
        "conversations": {},
        "dialog": {},
        "dnd": {},
        "emoji": {},
        "files": {
            "comments": {},
            "remote": {}
        },
        "functions": {},
        "migration": {},
        "oauth": {
            "v2": {}
        },
        "openid": {
            "connect": {}
        },
        "pins": {},
        "reactions": {},
        "reminders": {},
        "rtm": {},
        "search": {},
        "stars": {},
        "team": {
            "billing": {},
            "preferences": {},
            "profile": {}
        },
        "tooling": {
            "tokens": {}
        },
        "usergroups": {
            "users": {}
        },
        "users": {
            "profile": {}
        },
        "views": {},
        "workflows": {},
        "channels": {},
        "groups": {},
        "im": {},
        "mpim": {},
        "token": "xoxb-7969239524339-7955086751415-ZlMSZQ0zf3SyEp8Cq6sSoL4O",
        "slackApiUrl": "https://slack.com/api/",
        "retryConfig": {
            "retries": 100,
            "factor": 1.3
        },
        "requestQueue": {
            "_events": {},
            "_eventsCount": 0,
            "_intervalCount": 0,
            "_intervalEnd": 0,
            "_pendingCount": 0,
            "_carryoverConcurrencyCount": false,
            "_isIntervalIgnored": true,
            "_intervalCap": null,
            "_interval": 0,
            "_queue": {
                "_queue": []
            },
            "_concurrency": 100,
            "_throwOnTimeout": false,
            "_isPaused": false
        },
        "tlsConfig": {},
        "rejectRateLimitedCalls": false,
        "teamId": "T07UH71FE9Z",
        "logger": {
            "context": "Slack",
            "options": {},
            "level": "log",
            "localInstanceRef": {
                "context": "Slack",
                "options": {
                    "logLevels": [
                        "log"
                    ]
                },
                "originalContext": "Slack"
            }
        }
    },
    "logger": {
        "context": "Slack",
        "options": {},
        "level": "log",
        "localInstanceRef": {
            "context": "Slack",
            "options": {
                "logLevels": [
                    "log"
                ]
            },
            "originalContext": "Slack"
        }
    }
}

And then get the text with something like: (args as any).payload.text

@seratch seratch added question M-T: User needs support to use the project TypeScript-specific and removed untriaged labels Nov 2, 2024
@seratch
Copy link
Member

seratch commented Nov 2, 2024

Hi @alper, thank you for writing in.

We do understand your frustration with the message event listener types in TypeScript. The message event has several variations, which is why the type can be confusing, especially for new Slack app developers. The payload argument's type is a union data type that consists of these subtypes: https://api.slack.com/events/message#subtypes

To safely determine a specific type in TypeScript, the quickest way is to use if/else statements to check what the subtype is (or if it does not exist), as shown below:

import { App, EventFromType } from '@slack/bolt';
import { GenericMessageEvent, MessageChangedEvent } from "@slack/types";

app.event("message", async ({ payload }) => {
  // this one is still a union type of subtyped message events
  const variousMessageEventPayload: EventFromType<"message"> = payload;
  if (!payload.subtype) {
    // newly posted messages from a human do not have sutype
    // inside if block, the data type can be safely determined
    const postedMessageEventPayload: GenericMessageEvent = payload
  } else if (payload.subtype === "message_changed") {
    // there are a few other patterns; see https://api.slack.com/events/message#subtypes
    const messageChangedEventPayload: MessageChangedEvent = payload;
  }
});

This is what the past issues you've already linked try to describe and improve for the developer experience. We still cannot tell when and how this can be improved to be more intuitive, as the improvements we're considering are a breaking change to existing apps.

This library is written in TS, and users can use it in either JS or TS. Here is a project template: https://github.com/slack-samples/bolt-ts-starter-template

This message event handling is the most confusing. Other listener code should not be like that. Hope you'll like this library once you become familiar with it.

@alper
Copy link
Author

alper commented Nov 2, 2024

Ah, I need: from "@slack/types";?

That wasn't listed anywhere. I'd think it'd be best to re-export them from this package for convenience.

@seratch
Copy link
Member

seratch commented Nov 2, 2024

Most users don't need to explicitly refer to the types, so they're not mentioned in the documents. However, re-exporting the types from @slack/bolt could indeed be helpful for some developers like you. Thank you for the feedback.

@alper
Copy link
Author

alper commented Nov 2, 2024

OK. Cool but it does work either way with the types or with any.

@alper alper closed this as completed Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question M-T: User needs support to use the project TypeScript-specific
Projects
None yet
Development

No branches or pull requests

2 participants