forked from jshiffer/matterbridge
2f33fe86f5
* Update dependencies and build to go1.22 * Fix api changes wrt to dependencies * Update golangci config
175 lines
4.5 KiB
Go
175 lines
4.5 KiB
Go
package slack
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
)
|
|
|
|
const (
|
|
// APIURL of the slack api.
|
|
APIURL = "https://slack.com/api/"
|
|
// WEBAPIURLFormat ...
|
|
WEBAPIURLFormat = "https://%s.slack.com/api/users.admin.%s?t=%d"
|
|
)
|
|
|
|
// httpClient defines the minimal interface needed for an http.Client to be implemented.
|
|
type httpClient interface {
|
|
Do(*http.Request) (*http.Response, error)
|
|
}
|
|
|
|
// ResponseMetadata holds pagination metadata
|
|
type ResponseMetadata struct {
|
|
Cursor string `json:"next_cursor"`
|
|
Messages []string `json:"messages"`
|
|
Warnings []string `json:"warnings"`
|
|
}
|
|
|
|
func (t *ResponseMetadata) initialize() *ResponseMetadata {
|
|
if t != nil {
|
|
return t
|
|
}
|
|
|
|
return &ResponseMetadata{}
|
|
}
|
|
|
|
// 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"`
|
|
// EnterpriseID is only returned when an enterprise id present
|
|
EnterpriseID string `json:"enterprise_id,omitempty"`
|
|
BotID string `json:"bot_id"`
|
|
}
|
|
|
|
type authTestResponseFull struct {
|
|
SlackResponse
|
|
AuthTestResponse
|
|
}
|
|
|
|
// Client for the slack api.
|
|
type ParamOption func(*url.Values)
|
|
|
|
type Client struct {
|
|
token string
|
|
appLevelToken string
|
|
configToken string
|
|
configRefreshToken string
|
|
endpoint string
|
|
debug bool
|
|
log ilogger
|
|
httpclient httpClient
|
|
}
|
|
|
|
// Option defines an option for a Client
|
|
type Option func(*Client)
|
|
|
|
// OptionHTTPClient - provide a custom http client to the slack client.
|
|
func OptionHTTPClient(client httpClient) func(*Client) {
|
|
return func(c *Client) {
|
|
c.httpclient = client
|
|
}
|
|
}
|
|
|
|
// OptionDebug enable debugging for the client
|
|
func OptionDebug(b bool) func(*Client) {
|
|
return func(c *Client) {
|
|
c.debug = b
|
|
}
|
|
}
|
|
|
|
// OptionLog set logging for client.
|
|
func OptionLog(l logger) func(*Client) {
|
|
return func(c *Client) {
|
|
c.log = internalLog{logger: l}
|
|
}
|
|
}
|
|
|
|
// OptionAPIURL set the url for the client. only useful for testing.
|
|
func OptionAPIURL(u string) func(*Client) {
|
|
return func(c *Client) { c.endpoint = u }
|
|
}
|
|
|
|
// OptionAppLevelToken sets an app-level token for the client.
|
|
func OptionAppLevelToken(token string) func(*Client) {
|
|
return func(c *Client) { c.appLevelToken = token }
|
|
}
|
|
|
|
// OptionConfigToken sets a configuration token for the client.
|
|
func OptionConfigToken(token string) func(*Client) {
|
|
return func(c *Client) { c.configToken = token }
|
|
}
|
|
|
|
// OptionConfigRefreshToken sets a configuration refresh token for the client.
|
|
func OptionConfigRefreshToken(token string) func(*Client) {
|
|
return func(c *Client) { c.configRefreshToken = token }
|
|
}
|
|
|
|
// New builds a slack client from the provided token and options.
|
|
func New(token string, options ...Option) *Client {
|
|
s := &Client{
|
|
token: token,
|
|
endpoint: APIURL,
|
|
httpclient: &http.Client{},
|
|
log: log.New(os.Stderr, "slack-go/slack", log.LstdFlags|log.Lshortfile),
|
|
}
|
|
|
|
for _, opt := range options {
|
|
opt(s)
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// AuthTest tests if the user is able to do authenticated requests or not
|
|
func (api *Client) AuthTest() (response *AuthTestResponse, error error) {
|
|
return api.AuthTestContext(context.Background())
|
|
}
|
|
|
|
// AuthTestContext tests if the user is able to do authenticated requests or not with a custom context
|
|
func (api *Client) AuthTestContext(ctx context.Context) (response *AuthTestResponse, err error) {
|
|
api.Debugf("Challenging auth...")
|
|
responseFull := &authTestResponseFull{}
|
|
err = api.postMethod(ctx, "auth.test", url.Values{"token": {api.token}}, responseFull)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &responseFull.AuthTestResponse, responseFull.Err()
|
|
}
|
|
|
|
// Debugf print a formatted debug line.
|
|
func (api *Client) Debugf(format string, v ...interface{}) {
|
|
if api.debug {
|
|
api.log.Output(2, fmt.Sprintf(format, v...))
|
|
}
|
|
}
|
|
|
|
// Debugln print a debug line.
|
|
func (api *Client) Debugln(v ...interface{}) {
|
|
if api.debug {
|
|
api.log.Output(2, fmt.Sprintln(v...))
|
|
}
|
|
}
|
|
|
|
// Debug returns if debug is enabled.
|
|
func (api *Client) Debug() bool {
|
|
return api.debug
|
|
}
|
|
|
|
// post to a slack web method.
|
|
func (api *Client) postMethod(ctx context.Context, path string, values url.Values, intf interface{}) error {
|
|
return postForm(ctx, api.httpclient, api.endpoint+path, values, intf, api)
|
|
}
|
|
|
|
// get a slack web method.
|
|
func (api *Client) getMethod(ctx context.Context, path string, token string, values url.Values, intf interface{}) error {
|
|
return getResource(ctx, api.httpclient, api.endpoint+path, token, values, intf, api)
|
|
}
|