Documentation
¶
Overview ¶
Package client is a thin Slack Web API client scoped to the surface area the Nuon slackbot integration needs:
- oauth.v2.access — exchange OAuth code for a workspace bot token
- chat.postMessage — post lifecycle / approval messages
- chat.update — edit a previously posted message (e.g. mark approved)
- conversations.list — enumerate channels for the /nuon subscribe flow
- auth.test — probe a token (used after install to capture bot_user_id, app_id, etc.)
We avoid pulling in a third-party Slack SDK because the surface area is small, easy to review, and we want full control over JSON shape, retry behavior, and observability.
Index ¶
- Constants
- type AuthTestResponse
- type Client
- func (c *Client) AuthTest(ctx context.Context, botToken string) (*AuthTestResponse, error)
- func (c *Client) ConversationsList(ctx context.Context, botToken string, req ConversationsListRequest) (*ConversationsListResponse, error)
- func (c *Client) OAuthV2Access(ctx context.Context, req OAuthV2AccessRequest) (*OAuthV2AccessResponse, error)
- func (c *Client) PostMessage(ctx context.Context, botToken string, req PostMessageRequest) (*PostMessageResponse, error)
- func (c *Client) UpdateMessage(ctx context.Context, botToken string, req UpdateMessageRequest) (*UpdateMessageResponse, error)
- func (c *Client) ViewsOpen(ctx context.Context, botToken string, req ViewsOpenRequest) (*ViewsResponse, error)
- func (c *Client) ViewsPush(ctx context.Context, botToken string, req ViewsPushRequest) (*ViewsResponse, error)
- func (c *Client) ViewsUpdate(ctx context.Context, botToken string, req ViewsUpdateRequest) (*ViewsResponse, error)
- type Conversation
- type ConversationsListRequest
- type ConversationsListResponse
- type OAuthV2AccessRequest
- type OAuthV2AccessResponse
- type Option
- type PostMessageRequest
- type PostMessageResponse
- type UpdateMessageRequest
- type UpdateMessageResponse
- type ViewsOpenRequest
- type ViewsPushRequest
- type ViewsResponse
- type ViewsUpdateRequest
Constants ¶
const BaseURL = "https://slack.com/api"
BaseURL is the public Slack Web API endpoint. Tests override this.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthTestResponse ¶
type AuthTestResponse struct {
URL string `json:"url"`
Team string `json:"team"`
User string `json:"user"`
TeamID string `json:"team_id"`
UserID string `json:"user_id"`
BotID string `json:"bot_id"`
EnterpriseID string `json:"enterprise_id,omitempty"`
// contains filtered or unexported fields
}
AuthTestResponse is the response from auth.test.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Slack Web API client. Construct via New.
func (*Client) AuthTest ¶
AuthTest probes a bot token. Useful immediately after install to verify scope grants and capture the bot user id / team id from the token itself.
func (*Client) ConversationsList ¶
func (c *Client) ConversationsList(ctx context.Context, botToken string, req ConversationsListRequest) (*ConversationsListResponse, error)
ConversationsList enumerates channels visible to the bot.
func (*Client) OAuthV2Access ¶
func (c *Client) OAuthV2Access(ctx context.Context, req OAuthV2AccessRequest) (*OAuthV2AccessResponse, error)
OAuthV2Access exchanges an OAuth code for a workspace access token.
func (*Client) PostMessage ¶
func (c *Client) PostMessage(ctx context.Context, botToken string, req PostMessageRequest) (*PostMessageResponse, error)
PostMessage posts a message to a channel as the supplied bot token.
func (*Client) UpdateMessage ¶
func (c *Client) UpdateMessage(ctx context.Context, botToken string, req UpdateMessageRequest) (*UpdateMessageResponse, error)
UpdateMessage edits a previously posted message.
func (*Client) ViewsOpen ¶
func (c *Client) ViewsOpen(ctx context.Context, botToken string, req ViewsOpenRequest) (*ViewsResponse, error)
ViewsOpen opens a new modal anchored to the given trigger_id. Trigger ids are short-lived (~3s) so callers must not block before invoking this.
func (*Client) ViewsPush ¶
func (c *Client) ViewsPush(ctx context.Context, botToken string, req ViewsPushRequest) (*ViewsResponse, error)
ViewsPush stacks a new modal on top of the current one.
func (*Client) ViewsUpdate ¶
func (c *Client) ViewsUpdate(ctx context.Context, botToken string, req ViewsUpdateRequest) (*ViewsResponse, error)
ViewsUpdate edits a previously opened modal in place. Used by the unsubscribe modal's Remove buttons (re-render after each delete) and by the subscribe modal's scope/install pivots.
type Conversation ¶
type Conversation struct {
ID string `json:"id"`
Name string `json:"name"`
IsChannel bool `json:"is_channel"`
IsPrivate bool `json:"is_private"`
IsArchived bool `json:"is_archived"`
IsMember bool `json:"is_member"`
}
Conversation is a single channel entry from conversations.list.
type ConversationsListRequest ¶
type ConversationsListRequest struct {
Cursor string
Limit int
Types string // e.g. "public_channel,private_channel"
ExcludeArchived bool
}
ConversationsListRequest paginates through channel listings.
type ConversationsListResponse ¶
type ConversationsListResponse struct {
Channels []Conversation `json:"channels"`
ResponseMetadata struct {
NextCursor string `json:"next_cursor"`
} `json:"response_metadata"`
// contains filtered or unexported fields
}
ConversationsListResponse is the response from conversations.list.
type OAuthV2AccessRequest ¶
type OAuthV2AccessRequest struct {
ClientID string
ClientSecret string
Code string
RedirectURI string
}
OAuthV2AccessRequest contains the inputs for an OAuth code exchange.
type OAuthV2AccessResponse ¶
type OAuthV2AccessResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
Scope string `json:"scope"`
BotUserID string `json:"bot_user_id"`
AppID string `json:"app_id"`
Team struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"team"`
Enterprise *struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"enterprise"`
// IsEnterpriseInstall is true for org-wide (Enterprise Grid) installs.
// We reject these at the OAuth callback in v1 — see Phase 4.
IsEnterpriseInstall bool `json:"is_enterprise_install"`
AuthedUser struct {
ID string `json:"id"`
} `json:"authed_user"`
// contains filtered or unexported fields
}
OAuthV2AccessResponse is the subset of oauth.v2.access we care about.
Slack returns far more fields (incoming_webhook, authed_user, etc.) but we only persist what's needed to drive the bot: the bot token, the workspace identity, and the install-time scope grant.
type Option ¶
type Option func(*Client)
Option mutates Client during construction.
func WithBaseURL ¶
WithBaseURL overrides the default Slack API base URL (used in tests).
func WithHTTPClient ¶
WithHTTPClient overrides the default HTTP client.
type PostMessageRequest ¶
type PostMessageRequest struct {
Channel string `json:"channel"`
Text string `json:"text,omitempty"`
Blocks []any `json:"blocks,omitempty"`
ThreadTS string `json:"thread_ts,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
}
PostMessageRequest is the input for chat.postMessage.
type PostMessageResponse ¶
type PostMessageResponse struct {
Channel string `json:"channel"`
TS string `json:"ts"`
// contains filtered or unexported fields
}
PostMessageResponse mirrors chat.postMessage's response.
type UpdateMessageRequest ¶
type UpdateMessageRequest struct {
Channel string `json:"channel"`
TS string `json:"ts"`
Text string `json:"text,omitempty"`
Blocks []any `json:"blocks,omitempty"`
}
UpdateMessageRequest mutates a previously posted message.
type UpdateMessageResponse ¶
type UpdateMessageResponse struct {
Channel string `json:"channel"`
TS string `json:"ts"`
// contains filtered or unexported fields
}
UpdateMessageResponse mirrors chat.update's response.
type ViewsOpenRequest ¶
type ViewsOpenRequest struct {
TriggerID string `json:"trigger_id"`
View map[string]any `json:"view"`
}
ViewsOpenRequest opens a modal in response to a trigger_id from an interactive surface (slash command, button click, etc.). View is the Block-Kit modal definition; we accept it as a generic map so callers can build whatever shape they need without us schema-locking the modal here.
type ViewsPushRequest ¶
type ViewsPushRequest struct {
TriggerID string `json:"trigger_id"`
View map[string]any `json:"view"`
}
ViewsPushRequest pushes a new modal onto an already-open modal stack. We don't currently use push (everything fits in a single root modal) but expose it for parity with views.open / views.update.
type ViewsResponse ¶
type ViewsResponse struct {
View struct {
ID string `json:"id"`
CallbackID string `json:"callback_id"`
Hash string `json:"hash"`
} `json:"view"`
// ResponseMetadata.Messages carries Block-Kit validation errors when
// Slack rejects a view payload (e.g. an unknown block type). Surfaces
// in error messages so misshapen modals are debuggable.
ResponseMetadata struct {
Messages []string `json:"messages,omitempty"`
} `json:"response_metadata,omitempty"`
// contains filtered or unexported fields
}
ViewsResponse is the shared response shape for views.open / views.update / views.push. Slack returns the persisted view (with its allocated id) on success.
type ViewsUpdateRequest ¶
type ViewsUpdateRequest struct {
ViewID string `json:"view_id,omitempty"`
ExternalID string `json:"external_id,omitempty"`
Hash string `json:"hash,omitempty"`
View map[string]any `json:"view"`
}
ViewsUpdateRequest replaces the contents of an already-open modal. Exactly one of ViewID / ExternalID identifies the view; ViewID is the standard case (Slack provides it on every view payload).