diff options
Diffstat (limited to 'vendor/github.com/nlopes/slack/chat.go')
-rw-r--r-- | vendor/github.com/nlopes/slack/chat.go | 627 |
1 files changed, 0 insertions, 627 deletions
diff --git a/vendor/github.com/nlopes/slack/chat.go b/vendor/github.com/nlopes/slack/chat.go deleted file mode 100644 index c0744842..00000000 --- a/vendor/github.com/nlopes/slack/chat.go +++ /dev/null @@ -1,627 +0,0 @@ -package slack - -import ( - "context" - "encoding/json" - "net/http" - "net/url" - - "github.com/nlopes/slack/slackutilsx" -) - -const ( - DEFAULT_MESSAGE_USERNAME = "" - DEFAULT_MESSAGE_REPLY_BROADCAST = false - DEFAULT_MESSAGE_ASUSER = false - DEFAULT_MESSAGE_PARSE = "" - DEFAULT_MESSAGE_THREAD_TIMESTAMP = "" - DEFAULT_MESSAGE_LINK_NAMES = 0 - DEFAULT_MESSAGE_UNFURL_LINKS = false - DEFAULT_MESSAGE_UNFURL_MEDIA = true - DEFAULT_MESSAGE_ICON_URL = "" - DEFAULT_MESSAGE_ICON_EMOJI = "" - DEFAULT_MESSAGE_MARKDOWN = true - DEFAULT_MESSAGE_ESCAPE_TEXT = true -) - -type chatResponseFull struct { - Channel string `json:"channel"` - Timestamp string `json:"ts"` //Regular message timestamp - MessageTimeStamp string `json:"message_ts"` //Ephemeral message timestamp - Text string `json:"text"` - SlackResponse -} - -// getMessageTimestamp will inspect the `chatResponseFull` to ruturn a timestamp value -// in `chat.postMessage` its under `ts` -// in `chat.postEphemeral` its under `message_ts` -func (c chatResponseFull) getMessageTimestamp() string { - if len(c.Timestamp) > 0 { - return c.Timestamp - } - return c.MessageTimeStamp -} - -// PostMessageParameters contains all the parameters necessary (including the optional ones) for a PostMessage() request -type PostMessageParameters struct { - Username string `json:"username"` - AsUser bool `json:"as_user"` - Parse string `json:"parse"` - ThreadTimestamp string `json:"thread_ts"` - ReplyBroadcast bool `json:"reply_broadcast"` - LinkNames int `json:"link_names"` - UnfurlLinks bool `json:"unfurl_links"` - UnfurlMedia bool `json:"unfurl_media"` - IconURL string `json:"icon_url"` - IconEmoji string `json:"icon_emoji"` - Markdown bool `json:"mrkdwn,omitempty"` - EscapeText bool `json:"escape_text"` - - // chat.postEphemeral support - Channel string `json:"channel"` - User string `json:"user"` -} - -// NewPostMessageParameters provides an instance of PostMessageParameters with all the sane default values set -func NewPostMessageParameters() PostMessageParameters { - return PostMessageParameters{ - Username: DEFAULT_MESSAGE_USERNAME, - User: DEFAULT_MESSAGE_USERNAME, - AsUser: DEFAULT_MESSAGE_ASUSER, - Parse: DEFAULT_MESSAGE_PARSE, - ThreadTimestamp: DEFAULT_MESSAGE_THREAD_TIMESTAMP, - LinkNames: DEFAULT_MESSAGE_LINK_NAMES, - UnfurlLinks: DEFAULT_MESSAGE_UNFURL_LINKS, - UnfurlMedia: DEFAULT_MESSAGE_UNFURL_MEDIA, - IconURL: DEFAULT_MESSAGE_ICON_URL, - IconEmoji: DEFAULT_MESSAGE_ICON_EMOJI, - Markdown: DEFAULT_MESSAGE_MARKDOWN, - EscapeText: DEFAULT_MESSAGE_ESCAPE_TEXT, - } -} - -// DeleteMessage deletes a message in a channel -func (api *Client) DeleteMessage(channel, messageTimestamp string) (string, string, error) { - respChannel, respTimestamp, _, err := api.SendMessageContext(context.Background(), channel, MsgOptionDelete(messageTimestamp)) - return respChannel, respTimestamp, err -} - -// DeleteMessageContext deletes a message in a channel with a custom context -func (api *Client) DeleteMessageContext(ctx context.Context, channel, messageTimestamp string) (string, string, error) { - respChannel, respTimestamp, _, err := api.SendMessageContext(ctx, channel, MsgOptionDelete(messageTimestamp)) - return respChannel, respTimestamp, err -} - -// PostMessage sends a message to a channel. -// Message is escaped by default according to https://api.slack.com/docs/formatting -// Use http://davestevens.github.io/slack-message-builder/ to help crafting your message. -func (api *Client) PostMessage(channelID string, options ...MsgOption) (string, string, error) { - respChannel, respTimestamp, _, err := api.SendMessageContext( - context.Background(), - channelID, - MsgOptionPost(), - MsgOptionCompose(options...), - ) - return respChannel, respTimestamp, err -} - -// PostMessageContext sends a message to a channel with a custom context -// For more details, see PostMessage documentation. -func (api *Client) PostMessageContext(ctx context.Context, channelID string, options ...MsgOption) (string, string, error) { - respChannel, respTimestamp, _, err := api.SendMessageContext( - ctx, - channelID, - MsgOptionPost(), - MsgOptionCompose(options...), - ) - return respChannel, respTimestamp, err -} - -// PostEphemeral sends an ephemeral message to a user in a channel. -// Message is escaped by default according to https://api.slack.com/docs/formatting -// Use http://davestevens.github.io/slack-message-builder/ to help crafting your message. -func (api *Client) PostEphemeral(channelID, userID string, options ...MsgOption) (string, error) { - return api.PostEphemeralContext( - context.Background(), - channelID, - userID, - options..., - ) -} - -// PostEphemeralContext sends an ephemeal message to a user in a channel with a custom context -// For more details, see PostEphemeral documentation -func (api *Client) PostEphemeralContext(ctx context.Context, channelID, userID string, options ...MsgOption) (timestamp string, err error) { - _, timestamp, _, err = api.SendMessageContext(ctx, channelID, MsgOptionPostEphemeral(userID), MsgOptionCompose(options...)) - return timestamp, err -} - -// UpdateMessage updates a message in a channel -func (api *Client) UpdateMessage(channelID, timestamp string, options ...MsgOption) (string, string, string, error) { - return api.SendMessageContext(context.Background(), channelID, MsgOptionUpdate(timestamp), MsgOptionCompose(options...)) -} - -// UpdateMessageContext updates a message in a channel -func (api *Client) UpdateMessageContext(ctx context.Context, channelID, timestamp string, options ...MsgOption) (string, string, string, error) { - return api.SendMessageContext(ctx, channelID, MsgOptionUpdate(timestamp), MsgOptionCompose(options...)) -} - -// UnfurlMessage unfurls a message in a channel -func (api *Client) UnfurlMessage(channelID, timestamp string, unfurls map[string]Attachment, options ...MsgOption) (string, string, string, error) { - return api.SendMessageContext(context.Background(), channelID, MsgOptionUnfurl(timestamp, unfurls), MsgOptionCompose(options...)) -} - -// SendMessage more flexible method for configuring messages. -func (api *Client) SendMessage(channel string, options ...MsgOption) (string, string, string, error) { - return api.SendMessageContext(context.Background(), channel, options...) -} - -// SendMessageContext more flexible method for configuring messages with a custom context. -func (api *Client) SendMessageContext(ctx context.Context, channelID string, options ...MsgOption) (_channel string, _timestamp string, _text string, err error) { - var ( - req *http.Request - parser func(*chatResponseFull) responseParser - response chatResponseFull - ) - - if req, parser, err = buildSender(api.endpoint, options...).BuildRequest(api.token, channelID); err != nil { - return "", "", "", err - } - - if err = doPost(ctx, api.httpclient, req, parser(&response), api); err != nil { - return "", "", "", err - } - - return response.Channel, response.getMessageTimestamp(), response.Text, response.Err() -} - -// UnsafeApplyMsgOptions utility function for debugging/testing chat requests. -// NOTE: USE AT YOUR OWN RISK: No issues relating to the use of this function -// will be supported by the library. -func UnsafeApplyMsgOptions(token, channel, apiurl string, options ...MsgOption) (string, url.Values, error) { - config, err := applyMsgOptions(token, channel, apiurl, options...) - return config.endpoint, config.values, err -} - -func applyMsgOptions(token, channel, apiurl string, options ...MsgOption) (sendConfig, error) { - config := sendConfig{ - apiurl: apiurl, - endpoint: apiurl + string(chatPostMessage), - values: url.Values{ - "token": {token}, - "channel": {channel}, - }, - } - - for _, opt := range options { - if err := opt(&config); err != nil { - return config, err - } - } - - return config, nil -} - -func buildSender(apiurl string, options ...MsgOption) sendConfig { - return sendConfig{ - apiurl: apiurl, - options: options, - } -} - -type sendMode string - -const ( - chatUpdate sendMode = "chat.update" - chatPostMessage sendMode = "chat.postMessage" - chatDelete sendMode = "chat.delete" - chatPostEphemeral sendMode = "chat.postEphemeral" - chatResponse sendMode = "chat.responseURL" - chatMeMessage sendMode = "chat.meMessage" - chatUnfurl sendMode = "chat.unfurl" -) - -type sendConfig struct { - apiurl string - options []MsgOption - mode sendMode - endpoint string - values url.Values - attachments []Attachment - blocks Blocks - responseType string -} - -func (t sendConfig) BuildRequest(token, channelID string) (req *http.Request, _ func(*chatResponseFull) responseParser, err error) { - if t, err = applyMsgOptions(token, channelID, t.apiurl, t.options...); err != nil { - return nil, nil, err - } - - switch t.mode { - case chatResponse: - return responseURLSender{ - endpoint: t.endpoint, - values: t.values, - attachments: t.attachments, - blocks: t.blocks, - responseType: t.responseType, - }.BuildRequest() - default: - return formSender{endpoint: t.endpoint, values: t.values}.BuildRequest() - } -} - -type formSender struct { - endpoint string - values url.Values -} - -func (t formSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) { - req, err := formReq(t.endpoint, t.values) - return req, func(resp *chatResponseFull) responseParser { - return newJSONParser(resp) - }, err -} - -type responseURLSender struct { - endpoint string - values url.Values - attachments []Attachment - blocks Blocks - responseType string -} - -func (t responseURLSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) { - req, err := jsonReq(t.endpoint, Msg{ - Text: t.values.Get("text"), - Timestamp: t.values.Get("ts"), - Attachments: t.attachments, - Blocks: t.blocks, - ResponseType: t.responseType, - }) - return req, func(resp *chatResponseFull) responseParser { - return newContentTypeParser(resp) - }, err -} - -// MsgOption option provided when sending a message. -type MsgOption func(*sendConfig) error - -// MsgOptionPost posts a messages, this is the default. -func MsgOptionPost() MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatPostMessage) - config.values.Del("ts") - return nil - } -} - -// MsgOptionPostEphemeral - posts an ephemeral message to the provided user. -func MsgOptionPostEphemeral(userID string) MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatPostEphemeral) - MsgOptionUser(userID)(config) - config.values.Del("ts") - - return nil - } -} - -// MsgOptionMeMessage posts a "me message" type from the calling user -func MsgOptionMeMessage() MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatMeMessage) - return nil - } -} - -// MsgOptionUpdate updates a message based on the timestamp. -func MsgOptionUpdate(timestamp string) MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatUpdate) - config.values.Add("ts", timestamp) - return nil - } -} - -// MsgOptionDelete deletes a message based on the timestamp. -func MsgOptionDelete(timestamp string) MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatDelete) - config.values.Add("ts", timestamp) - return nil - } -} - -// MsgOptionUnfurl unfurls a message based on the timestamp. -func MsgOptionUnfurl(timestamp string, unfurls map[string]Attachment) MsgOption { - return func(config *sendConfig) error { - config.endpoint = config.apiurl + string(chatUnfurl) - config.values.Add("ts", timestamp) - unfurlsStr, err := json.Marshal(unfurls) - if err == nil { - config.values.Add("unfurls", string(unfurlsStr)) - } - return err - } -} - -// MsgOptionResponseURL supplies a url to use as the endpoint. -func MsgOptionResponseURL(url string, rt string) MsgOption { - return func(config *sendConfig) error { - config.mode = chatResponse - config.endpoint = url - config.responseType = rt - config.values.Del("ts") - return nil - } -} - -// MsgOptionAsUser whether or not to send the message as the user. -func MsgOptionAsUser(b bool) MsgOption { - return func(config *sendConfig) error { - if b != DEFAULT_MESSAGE_ASUSER { - config.values.Set("as_user", "true") - } - return nil - } -} - -// MsgOptionUser set the user for the message. -func MsgOptionUser(userID string) MsgOption { - return func(config *sendConfig) error { - config.values.Set("user", userID) - return nil - } -} - -// MsgOptionUsername set the username for the message. -func MsgOptionUsername(username string) MsgOption { - return func(config *sendConfig) error { - config.values.Set("username", username) - return nil - } -} - -// MsgOptionText provide the text for the message, optionally escape the provided -// text. -func MsgOptionText(text string, escape bool) MsgOption { - return func(config *sendConfig) error { - if escape { - text = slackutilsx.EscapeMessage(text) - } - config.values.Add("text", text) - return nil - } -} - -// MsgOptionAttachments provide attachments for the message. -func MsgOptionAttachments(attachments ...Attachment) MsgOption { - return func(config *sendConfig) error { - if attachments == nil { - return nil - } - - config.attachments = attachments - - // FIXME: We are setting the attachments on the message twice: above for - // the json version, and below for the html version. The marshalled bytes - // we put into config.values below don't work directly in the Msg version. - - attachmentBytes, err := json.Marshal(attachments) - if err == nil { - config.values.Set("attachments", string(attachmentBytes)) - } - - return err - } -} - -// MsgOptionBlocks sets blocks for the message -func MsgOptionBlocks(blocks ...Block) MsgOption { - return func(config *sendConfig) error { - if blocks == nil { - return nil - } - - config.blocks.BlockSet = append(config.blocks.BlockSet, blocks...) - - blocks, err := json.Marshal(blocks) - if err == nil { - config.values.Set("blocks", string(blocks)) - } - return err - } -} - -// MsgOptionEnableLinkUnfurl enables link unfurling -func MsgOptionEnableLinkUnfurl() MsgOption { - return func(config *sendConfig) error { - config.values.Set("unfurl_links", "true") - return nil - } -} - -// MsgOptionDisableLinkUnfurl disables link unfurling -func MsgOptionDisableLinkUnfurl() MsgOption { - return func(config *sendConfig) error { - config.values.Set("unfurl_links", "false") - return nil - } -} - -// MsgOptionDisableMediaUnfurl disables media unfurling. -func MsgOptionDisableMediaUnfurl() MsgOption { - return func(config *sendConfig) error { - config.values.Set("unfurl_media", "false") - return nil - } -} - -// MsgOptionDisableMarkdown disables markdown. -func MsgOptionDisableMarkdown() MsgOption { - return func(config *sendConfig) error { - config.values.Set("mrkdwn", "false") - return nil - } -} - -// MsgOptionTS sets the thread TS of the message to enable creating or replying to a thread -func MsgOptionTS(ts string) MsgOption { - return func(config *sendConfig) error { - config.values.Set("thread_ts", ts) - return nil - } -} - -// MsgOptionBroadcast sets reply_broadcast to true -func MsgOptionBroadcast() MsgOption { - return func(config *sendConfig) error { - config.values.Set("reply_broadcast", "true") - return nil - } -} - -// MsgOptionCompose combines multiple options into a single option. -func MsgOptionCompose(options ...MsgOption) MsgOption { - return func(c *sendConfig) error { - for _, opt := range options { - if err := opt(c); err != nil { - return err - } - } - return nil - } -} - -// MsgOptionParse set parse option. -func MsgOptionParse(b bool) MsgOption { - return func(c *sendConfig) error { - var v string - if b { - v = "full" - } else { - v = "none" - } - c.values.Set("parse", v) - return nil - } -} - -// MsgOptionIconURL sets an icon URL -func MsgOptionIconURL(iconURL string) MsgOption { - return func(c *sendConfig) error { - c.values.Set("icon_url", iconURL) - return nil - } -} - -// MsgOptionIconEmoji sets an icon emoji -func MsgOptionIconEmoji(iconEmoji string) MsgOption { - return func(c *sendConfig) error { - c.values.Set("icon_emoji", iconEmoji) - return nil - } -} - -// UnsafeMsgOptionEndpoint deliver the message to the specified endpoint. -// NOTE: USE AT YOUR OWN RISK: No issues relating to the use of this Option -// will be supported by the library, it is subject to change without notice that -// may result in compilation errors or runtime behaviour changes. -func UnsafeMsgOptionEndpoint(endpoint string, update func(url.Values)) MsgOption { - return func(config *sendConfig) error { - config.endpoint = endpoint - update(config.values) - return nil - } -} - -// MsgOptionPostMessageParameters maintain backwards compatibility. -func MsgOptionPostMessageParameters(params PostMessageParameters) MsgOption { - return func(config *sendConfig) error { - if params.Username != DEFAULT_MESSAGE_USERNAME { - config.values.Set("username", params.Username) - } - - // chat.postEphemeral support - if params.User != DEFAULT_MESSAGE_USERNAME { - config.values.Set("user", params.User) - } - - // never generates an error. - MsgOptionAsUser(params.AsUser)(config) - - if params.Parse != DEFAULT_MESSAGE_PARSE { - config.values.Set("parse", params.Parse) - } - if params.LinkNames != DEFAULT_MESSAGE_LINK_NAMES { - config.values.Set("link_names", "1") - } - - if params.UnfurlLinks != DEFAULT_MESSAGE_UNFURL_LINKS { - config.values.Set("unfurl_links", "true") - } - - // I want to send a message with explicit `as_user` `true` and `unfurl_links` `false` in request. - // Because setting `as_user` to `true` will change the default value for `unfurl_links` to `true` on Slack API side. - if params.AsUser != DEFAULT_MESSAGE_ASUSER && params.UnfurlLinks == DEFAULT_MESSAGE_UNFURL_LINKS { - config.values.Set("unfurl_links", "false") - } - if params.UnfurlMedia != DEFAULT_MESSAGE_UNFURL_MEDIA { - config.values.Set("unfurl_media", "false") - } - if params.IconURL != DEFAULT_MESSAGE_ICON_URL { - config.values.Set("icon_url", params.IconURL) - } - if params.IconEmoji != DEFAULT_MESSAGE_ICON_EMOJI { - config.values.Set("icon_emoji", params.IconEmoji) - } - if params.Markdown != DEFAULT_MESSAGE_MARKDOWN { - config.values.Set("mrkdwn", "false") - } - - if params.ThreadTimestamp != DEFAULT_MESSAGE_THREAD_TIMESTAMP { - config.values.Set("thread_ts", params.ThreadTimestamp) - } - if params.ReplyBroadcast != DEFAULT_MESSAGE_REPLY_BROADCAST { - config.values.Set("reply_broadcast", "true") - } - - return nil - } -} - -// PermalinkParameters are the parameters required to get a permalink to a -// message. Slack documentation can be found here: -// https://api.slack.com/methods/chat.getPermalink -type PermalinkParameters struct { - Channel string - Ts string -} - -// GetPermalink returns the permalink for a message. It takes -// PermalinkParameters and returns a string containing the permalink. It -// returns an error if unable to retrieve the permalink. -func (api *Client) GetPermalink(params *PermalinkParameters) (string, error) { - return api.GetPermalinkContext(context.Background(), params) -} - -// GetPermalinkContext returns the permalink for a message using a custom context. -func (api *Client) GetPermalinkContext(ctx context.Context, params *PermalinkParameters) (string, error) { - values := url.Values{ - "token": {api.token}, - "channel": {params.Channel}, - "message_ts": {params.Ts}, - } - - response := struct { - Channel string `json:"channel"` - Permalink string `json:"permalink"` - SlackResponse - }{} - err := api.getMethod(ctx, "chat.getPermalink", values, &response) - if err != nil { - return "", err - } - return response.Permalink, response.Err() -} |