marianoguerra/slack/client does not have a README file

    Client

    pub struct Client {
    transport : &
    Transport

    token : String
    base_url : String
    bool_style :
    BoolStyle

    extra_headers : Map[String, String]
    team_id : String?
    }

    Client::api_test

    https://docs.slack.dev/reference/methods/api.test

    Echoes its arguments back. Genuinely useful: it is the one call that proves the transport works without needing a valid token.

    Client::auth_revoke

    https://docs.slack.dev/reference/methods/auth.revoke dry_run is Slack's test argument, renamed because test is a MoonBit keyword. Set it to check whether the token WOULD be revoked without revoking it.

    Client::auth_test

    https://docs.slack.dev/reference/methods/auth.test

    The call to make first. It answers with the team, the user and the bot id the token belongs to -- which is the only way to find out what a token actually is, since the xoxb- prefix says almost nothing.

    Client::bookmarks_add

    async fn Client::bookmarks_add(self : Client, channel_id~ : String, title~ : String, type_~ : String, link? : String, emoji? : String, entity_id? : String, parent_id? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/bookmarks.add

    Client::bookmarks_list

    https://docs.slack.dev/reference/methods/bookmarks.list

    Client::call

    Call any Web API method.

    The escape hatch that keeps all 326 methods reachable: the typed builders below cover the families most apps use, and everything else is this.

    Raises rather than returning ok: false as a value. A refusal from Slack is an error in every sense that matters to a caller -- they asked for something and did not get it -- and making it a return value means every call site either checks or silently proceeds on a message that was never posted. PlatformError carries the whole response for the cases that want it.

    Client::chat_delete

    async fn Client::chat_delete(self : Client, channel~ : String, ts~ : String, as_user? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.delete

    Client::chat_delete_scheduled_message

    async fn Client::chat_delete_scheduled_message(self : Client, channel~ : String, scheduled_message_id~ : String, as_user? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.deleteScheduledMessage
    async fn Client::chat_get_permalink(self : Client, channel~ : String, message_ts~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.getPermalink

    Client::chat_me_message

    async fn Client::chat_me_message(self : Client, channel~ : String, text~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.meMessage

    Client::chat_post_ephemeral

    async fn Client::chat_post_ephemeral(self : Client, channel~ : String, user~ : String, text? : String, blocks? : Array[
    LayoutBlock
    ], attachments? : Json, thread_ts? : String, parse? : String, link_names? : Bool, username? : String, icon_emoji? : String, icon_url? : String, markdown_text? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.postEphemeral

    Visible to one user, and never stored. There is no ts to update or delete afterwards.

    Client::chat_post_message

    async fn Client::chat_post_message(self : Client, channel~ : String, text? : String, blocks? : Array[
    LayoutBlock
    ], attachments? : Json, thread_ts? : String, reply_broadcast? : Bool, unfurl_links? : Bool, unfurl_media? : Bool, mrkdwn? : Bool, parse? : String, link_names? : Bool, username? : String, icon_emoji? : String, icon_url? : String, metadata? : Json, markdown_text? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.postMessage

    text is optional in the schema but should almost always be set even when blocks is: it is what shows in notifications, in the sidebar preview and in clients that cannot render blocks. node-slack-sdk warns when it is missing; this library documents it here instead of logging at you.

    Client::chat_schedule_message

    async fn Client::chat_schedule_message(self : Client, channel~ : String, post_at~ : Int64, text? : String, blocks? : Array[
    LayoutBlock
    ], attachments? : Json, thread_ts? : String, reply_broadcast? : Bool, unfurl_links? : Bool, unfurl_media? : Bool, metadata? : Json, markdown_text? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.scheduleMessage

    Client::chat_scheduled_messages_list

    async fn Client::chat_scheduled_messages_list(self : Client, channel? : String, cursor? : String, limit? : Int, latest? : String, oldest? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.scheduledMessages.list

    Client::chat_unfurl

    async fn Client::chat_unfurl(self : Client, channel~ : String, ts~ : String, unfurls~ : Json, user_auth_required? : Bool, user_auth_message? : String, user_auth_url? : String, user_auth_blocks? : Array[
    LayoutBlock
    ]) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.unfurl

    user_auth_blocks is spelled that way on the wire; java-slack-sdk's RequestFormBuilderTest has a case for it precisely because the field name does not match the Java one.

    Client::chat_update

    async fn Client::chat_update(self : Client, channel~ : String, ts~ : String, text? : String, blocks? : Array[
    LayoutBlock
    ], attachments? : Json, link_names? : Bool, parse? : String, metadata? : Json, markdown_text? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/chat.update

    Note what an omitted blocks means here: the existing blocks stay. To REMOVE them, pass an empty list -- which serialises to [] rather than vanishing, exactly as java-slack-sdk pins.

    Client::conversations_archive

    async fn Client::conversations_archive(self : Client, channel~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.archive

    Client::conversations_close

    https://docs.slack.dev/reference/methods/conversations.close

    Client::conversations_create

    async fn Client::conversations_create(self : Client, name~ : String, is_private? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.create

    Client::conversations_history

    async fn Client::conversations_history(self : Client, channel~ : String, cursor? : String, limit? : Int, latest? : String, oldest? : String, inclusive? : Bool, include_all_metadata? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.history

    Client::conversations_history_all

    async fn Client::conversations_history_all(self : Client, channel~ : String, latest? : String, oldest? : String, page_size? : Int, max_pages? : Int) -> Array[Json] raise
    SlackError

    Every message in a channel, oldest page last.

    Client::conversations_info

    async fn Client::conversations_info(self : Client, channel~ : String, include_locale? : Bool, include_num_members? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.info

    Client::conversations_invite

    async fn Client::conversations_invite(self : Client, channel~ : String, users~ : Array[String], force? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.invite

    users is comma-joined, up to 1,000 ids. java-slack-sdk joins this field by hand for exactly this reason.

    Client::conversations_join

    https://docs.slack.dev/reference/methods/conversations.join

    Client::conversations_kick

    async fn Client::conversations_kick(self : Client, channel~ : String, user~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.kick

    Client::conversations_leave

    https://docs.slack.dev/reference/methods/conversations.leave

    Client::conversations_list

    async fn Client::conversations_list(self : Client, types? : Array[String], exclude_archived? : Bool, limit? : Int, cursor? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.list

    types is comma-joined on the wire: public_channel,private_channel,mpim,im. That is a per-field fact from Slack's docs, which is why it is Csv here and not a JSON array.

    Client::conversations_list_all

    async fn Client::conversations_list_all(self : Client, types? : Array[String], exclude_archived? : Bool, page_size? : Int, max_pages? : Int) -> Array[Json] raise
    SlackError

    Every conversation, across every page.

    Tier 2 at 20 requests a minute, and a large workspace has tens of thousands of channels -- so this is the call that will get you rate-limited if anything does. Pass max_pages when you only need a sample.

    Client::conversations_mark

    async fn Client::conversations_mark(self : Client, channel~ : String, ts~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.mark

    Client::conversations_members

    async fn Client::conversations_members(self : Client, channel~ : String, cursor? : String, limit? : Int) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.members

    Client::conversations_members_all

    async fn Client::conversations_members_all(self : Client, channel~ : String, page_size? : Int, max_pages? : Int) -> Array[Json] raise
    SlackError

    Client::conversations_open

    async fn Client::conversations_open(self : Client, channel? : String, users? : Array[String], return_im? : Bool, prevent_creation? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.open

    With users, opens a DM or group DM; with channel, resumes an existing one.

    Client::conversations_rename

    async fn Client::conversations_rename(self : Client, channel~ : String, name~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.rename

    Client::conversations_replies

    async fn Client::conversations_replies(self : Client, channel~ : String, ts~ : String, cursor? : String, limit? : Int, latest? : String, oldest? : String, inclusive? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.replies

    ts is the PARENT message's timestamp. The first item that comes back is that parent, not the first reply.

    Client::conversations_set_purpose

    async fn Client::conversations_set_purpose(self : Client, channel~ : String, purpose~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.setPurpose

    Client::conversations_set_topic

    async fn Client::conversations_set_topic(self : Client, channel~ : String, topic~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/conversations.setTopic

    Client::files_complete_upload_external

    async fn Client::files_complete_upload_external(self : Client, files~ : Json, channel_id? : String, initial_comment? : String, thread_ts? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/files.completeUploadExternal

    Client::files_delete

    https://docs.slack.dev/reference/methods/files.delete

    Client::files_get_upload_url_external

    async fn Client::files_get_upload_url_external(self : Client, filename~ : String, length~ : Int, alt_txt? : String, snippet_type? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/files.getUploadURLExternal

    Step one of the upload dance: ask for a URL, PUT the bytes to it yourself, then call files.completeUploadExternal. The PUT is not a Web API call and this library does not do it -- see the README.

    Client::files_info

    async fn Client::files_info(self : Client, file~ : String, cursor? : String, limit? : Int) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/files.info

    Client::files_list

    async fn Client::files_list(self : Client, channel? : String, user? : String, types? : Array[String], ts_from? : String, ts_to? : String, count? : Int, page? : Int) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/files.list

    Client::interpret

    Turn one HTTP response into a result or an error.

    Separate from call and synchronous, so the status-handling rules are testable without a transport at all.

    Client::new

    fn Client::new(transport : &
    Transport
    , token : String, base_url? : String, bool_style? :
    BoolStyle
    , extra_headers? : Map[String, String], team_id? : String) -> Client

    Client::paginate

    async fn Client::paginate(self : Client, api_method : String, params :
    Params
    , on_page : (
    ApiResponse
    ) -> Bool, page_size? : Int, cursor? : String, max_pages? : Int) -> Int raise
    SlackError

    Walk every page of a paginated method.

    on_page is called with each page and returns false to stop early -- node-slack-sdk's shouldStop, inverted so that the common case is _ => true. Returns the number of pages fetched.

    A callback rather than an iterator because MoonBit's async iteration would force this whole package to depend on a runtime; the callback costs one closure and keeps @client buildable on wasm.

    Client::paginate_collect

    async fn Client::paginate_collect(self : Client, api_method : String, params :
    Params
    , key : String, page_size? : Int, max_pages? : Int) -> Array[Json] raise
    SlackError

    Walk every page and concatenate the items under key.

    key is the collection's name in the response -- channels for conversations.list, members for users.list, messages for conversations.history. Slack has no single name for it, so it cannot be inferred.

    Client::pins_add

    async fn Client::pins_add(self : Client, channel~ : String, timestamp? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/pins.add

    Client::pins_list

    https://docs.slack.dev/reference/methods/pins.list

    Client::pins_remove

    async fn Client::pins_remove(self : Client, channel~ : String, timestamp? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/pins.remove

    Client::reactions_add

    async fn Client::reactions_add(self : Client, channel~ : String, timestamp~ : String, name~ : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/reactions.add

    name is the shortcode WITHOUT colons: thumbsup, not :thumbsup:.

    Client::reactions_get

    async fn Client::reactions_get(self : Client, channel? : String, timestamp? : String, file? : String, file_comment? : String, full? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/reactions.get

    Client::reactions_list

    async fn Client::reactions_list(self : Client, user? : String, cursor? : String, limit? : Int, full? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/reactions.list

    Client::reactions_remove

    async fn Client::reactions_remove(self : Client, name~ : String, channel? : String, timestamp? : String, file? : String, file_comment? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/reactions.remove

    Client::team_info

    async fn Client::team_info(self : Client, team? : String, domain? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/team.info

    Client::team_profile_get

    https://docs.slack.dev/reference/methods/team.profile.get

    Client::usergroups_create

    async fn Client::usergroups_create(self : Client, name~ : String, handle? : String, description? : String, channels? : Array[String], include_count? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/usergroups.create

    Client::usergroups_list

    async fn Client::usergroups_list(self : Client, include_disabled? : Bool, include_count? : Bool, include_users? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/usergroups.list

    Client::usergroups_users_list

    async fn Client::usergroups_users_list(self : Client, usergroup~ : String, include_disabled? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/usergroups.users.list

    Client::usergroups_users_update

    async fn Client::usergroups_users_update(self : Client, usergroup~ : String, users~ : Array[String], include_count? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/usergroups.users.update

    Replaces the membership wholesale; it is not an "add". Reading usergroups.users.list first and sending the union is on the caller.

    Client::users_conversations

    async fn Client::users_conversations(self : Client, user? : String, types? : Array[String], exclude_archived? : Bool, cursor? : String, limit? : Int) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/users.conversations

    Client::users_get_presence

    https://docs.slack.dev/reference/methods/users.getPresence

    Client::users_info

    async fn Client::users_info(self : Client, user~ : String, include_locale? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/users.info

    Client::users_list

    async fn Client::users_list(self : Client, cursor? : String, limit? : Int, include_locale? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/users.list

    Client::users_list_all

    async fn Client::users_list_all(self : Client, include_locale? : Bool, page_size? : Int, max_pages? : Int) -> Array[Json] raise
    SlackError

    Every member, across every page. The collection is called members, not users.

    Client::users_lookup_by_email

    https://docs.slack.dev/reference/methods/users.lookupByEmail

    Client::users_profile_get

    async fn Client::users_profile_get(self : Client, user? : String, include_labels? : Bool) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/users.profile.get

    Client::users_profile_set

    async fn Client::users_profile_set(self : Client, user? : String, profile? : Json, name? : String, value? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/users.profile.set

    Client::users_set_presence

    https://docs.slack.dev/reference/methods/users.setPresence

    Client::views_open

    async fn Client::views_open(self : Client, trigger_id~ : String, view~ : Json) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/views.open

    trigger_id expires three seconds after the interaction that produced it. A modal that "sometimes fails to open" is almost always this.

    Client::views_publish

    async fn Client::views_publish(self : Client, user_id~ : String, view~ : Json, hash? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/views.publish

    The App Home tab. hash is the same lost-update guard as on views.update.

    Client::views_push

    async fn Client::views_push(self : Client, trigger_id~ : String, view~ : Json) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/views.push

    Client::views_update

    async fn Client::views_update(self : Client, view~ : Json, view_id? : String, external_id? : String, hash? : String) ->
    ApiResponse
    raise
    SlackError

    https://docs.slack.dev/reference/methods/views.update

    Identify the view by view_id or by external_id, not both. hash guards against a lost update when two handlers race.

    Paginator

    pub struct Paginator {
    page_size : Int
    cursor : String?
    finished : Bool
    pages : Int
    }

    Paginator::accept

    Record a page and work out whether there is another.

    An absent cursor ends the walk, and so does an EMPTY one: Slack sends "next_cursor": "" on the last page, and a client that treats that as a cursor asks for the same page forever. node-slack-sdk's paginationOptionsForNextPage checks for both, and so does this.

    Paginator::cursor

    fn Paginator::cursor(self : Paginator) -> String?

    Paginator::is_finished

    fn Paginator::is_finished(self : Paginator) -> Bool

    Paginator::new

    fn Paginator::new(page_size? : Int, cursor? : String) -> Paginator

    A paginator over one method.

    cursor resumes a walk that was interrupted -- a job that paged through 40,000 conversations and died at 30,000 should not start again.

    Paginator::next

    The extra parameters for the next request, or None when there are no more pages.

    limit is sent on EVERY request, including the first. node-slack-sdk adds it only from the second request onward, which means page one comes back at whatever default the method happens to have (usually 100) and every later page holds 200 -- a difference the caller never asked for and will only notice as an odd row count. Sending it consistently is a deliberate divergence.

    Paginator::pages

    fn Paginator::pages(self : Paginator) -> Int

    Paginator::stop

    fn Paginator::stop(self : Paginator) -> Unit

    Stop early, whatever the cursor says. The caller's own decision -- "I have enough", "I found what I was looking for" -- rather than Slack's.

    default_page_size

    let default_page_size : Int

    node-slack-sdk's defaultPageSize.

    home_view

    fn home_view(blocks : Array[
    LayoutBlock
    ], callback_id? : String, private_metadata? : String) -> Json

    An App Home tab view.

    interpret_response

    The rules, as a free function.

    Slack answers a refusal with HTTP 200 and {"ok": false}, so the status code and ok are two different questions: 429 and 5xx are infrastructure, ok: false is Slack declining.

    merge_params

    Merge a paginator's parameters into a caller's, without mutating theirs.

    The paginator's values win: a caller who passed limit in the base params AND a page_size meant the page size, and two limit fields on the wire would let Slack pick.
    fn modal(title : String, blocks : Array[
    LayoutBlock
    ], submit? : String, close? : String, callback_id? : String, private_metadata? : String) -> Json

    A modal view. title and submit are what Slack requires of one.

    page_items

    fn page_items(response :
    ApiResponse
    , key : String) -> Array[Json]

    Pull the items out of a paged response.

    Slack has no single name for "the collection": conversations.list answers with channels, users.list with members, conversations.history with messages. So the key is the caller's to supply, and an absent or non-array key yields nothing rather than raising -- a page with no items is a normal thing on the last page of a filtered query.

    view

    fn view(type_ : String, blocks : Array[
    LayoutBlock
    ], title? : String, submit? : String, close? : String, callback_id? : String, private_metadata? : String, external_id? : String, clear_on_close? : Bool, notify_on_close? : Bool) -> Json

    Build a view payload from typed blocks.

    Views are not blocks and not LayoutBlocks, but the only part of one a caller usually cares about is its block list -- so this assembles the rest.