summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/nlopes/slack/chat.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/nlopes/slack/chat.go')
-rw-r--r--vendor/github.com/nlopes/slack/chat.go301
1 files changed, 225 insertions, 76 deletions
diff --git a/vendor/github.com/nlopes/slack/chat.go b/vendor/github.com/nlopes/slack/chat.go
index fc909a86..9a2c4453 100644
--- a/vendor/github.com/nlopes/slack/chat.go
+++ b/vendor/github.com/nlopes/slack/chat.go
@@ -1,6 +1,7 @@
package slack
import (
+ "context"
"encoding/json"
"errors"
"net/url"
@@ -62,30 +63,92 @@ func NewPostMessageParameters() PostMessageParameters {
}
}
-func chatRequest(path string, values url.Values, debug bool) (*chatResponseFull, error) {
- response := &chatResponseFull{}
- err := post(path, values, response, debug)
+// 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(channel, text string, params PostMessageParameters) (string, string, error) {
+ respChannel, respTimestamp, _, err := api.SendMessageContext(
+ context.Background(),
+ channel,
+ MsgOptionText(text, params.EscapeText),
+ MsgOptionAttachments(params.Attachments...),
+ MsgOptionPostMessageParameters(params),
+ )
+ 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, channel, text string, params PostMessageParameters) (string, string, error) {
+ respChannel, respTimestamp, _, err := api.SendMessageContext(
+ ctx,
+ channel,
+ MsgOptionText(text, params.EscapeText),
+ MsgOptionAttachments(params.Attachments...),
+ MsgOptionPostMessageParameters(params),
+ )
+ return respChannel, respTimestamp, err
+}
+
+// UpdateMessage updates a message in a channel
+func (api *Client) UpdateMessage(channel, timestamp, text string) (string, string, string, error) {
+ return api.UpdateMessageContext(context.Background(), channel, timestamp, text)
+}
+
+// UpdateMessage updates a message in a channel
+func (api *Client) UpdateMessageContext(ctx context.Context, channel, timestamp, text string) (string, string, string, error) {
+ return api.SendMessageContext(ctx, channel, MsgOptionUpdate(timestamp), MsgOptionText(text, true))
+}
+
+// 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, channel string, options ...MsgOption) (string, string, string, error) {
+ channel, values, err := ApplyMsgOptions(api.config.token, channel, options...)
if err != nil {
- return nil, err
+ return "", "", "", err
}
- if !response.Ok {
- return nil, errors.New(response.Error)
+
+ response, err := chatRequest(ctx, channel, values, api.debug)
+ if err != nil {
+ return "", "", "", err
}
- return response, nil
+
+ return response.Channel, response.Timestamp, response.Text, nil
}
-// DeleteMessage deletes a message in a channel
-func (api *Client) DeleteMessage(channel, messageTimestamp string) (string, string, error) {
- values := url.Values{
- "token": {api.config.token},
- "channel": {channel},
- "ts": {messageTimestamp},
+// ApplyMsgOptions utility function for debugging/testing chat requests.
+func ApplyMsgOptions(token, channel string, options ...MsgOption) (string, url.Values, error) {
+ config := sendConfig{
+ mode: chatPostMessage,
+ values: url.Values{
+ "token": {token},
+ "channel": {channel},
+ },
}
- response, err := chatRequest("chat.delete", values, api.debug)
- if err != nil {
- return "", "", err
+
+ for _, opt := range options {
+ if err := opt(&config); err != nil {
+ return string(config.mode), config.values, err
+ }
}
- return response.Channel, response.Timestamp, nil
+
+ return string(config.mode), config.values, nil
}
func escapeMessage(message string) string {
@@ -93,79 +156,165 @@ func escapeMessage(message string) string {
return replacer.Replace(message)
}
-// 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(channel, text string, params PostMessageParameters) (string, string, error) {
- if params.EscapeText {
- text = escapeMessage(text)
- }
- values := url.Values{
- "token": {api.config.token},
- "channel": {channel},
- "text": {text},
+func chatRequest(ctx context.Context, path string, values url.Values, debug bool) (*chatResponseFull, error) {
+ response := &chatResponseFull{}
+ err := post(ctx, path, values, response, debug)
+ if err != nil {
+ return nil, err
}
- if params.Username != DEFAULT_MESSAGE_USERNAME {
- values.Set("username", string(params.Username))
+ if !response.Ok {
+ return nil, errors.New(response.Error)
}
- if params.AsUser != DEFAULT_MESSAGE_ASUSER {
- values.Set("as_user", "true")
+ return response, nil
+}
+
+type sendMode string
+
+const (
+ chatUpdate sendMode = "chat.update"
+ chatPostMessage sendMode = "chat.postMessage"
+ chatDelete sendMode = "chat.delete"
+)
+
+type sendConfig struct {
+ mode sendMode
+ values url.Values
+}
+
+// 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.mode = chatPostMessage
+ config.values.Del("ts")
+ return nil
}
- if params.Parse != DEFAULT_MESSAGE_PARSE {
- values.Set("parse", string(params.Parse))
+}
+
+// MsgOptionUpdate updates a message based on the timestamp.
+func MsgOptionUpdate(timestamp string) MsgOption {
+ return func(config *sendConfig) error {
+ config.mode = chatUpdate
+ config.values.Add("ts", timestamp)
+ return nil
}
- if params.LinkNames != DEFAULT_MESSAGE_LINK_NAMES {
- values.Set("link_names", "1")
+}
+
+// MsgOptionDelete deletes a message based on the timestamp.
+func MsgOptionDelete(timestamp string) MsgOption {
+ return func(config *sendConfig) error {
+ config.mode = chatDelete
+ config.values.Add("ts", timestamp)
+ return nil
}
- if params.Attachments != nil {
- attachments, err := json.Marshal(params.Attachments)
- if err != nil {
- return "", "", err
+}
+
+// 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")
}
- values.Set("attachments", string(attachments))
+ return nil
}
- if params.UnfurlLinks != DEFAULT_MESSAGE_UNFURL_LINKS {
- 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 {
- values.Set("unfurl_links", "false")
- }
- if params.UnfurlMedia != DEFAULT_MESSAGE_UNFURL_MEDIA {
- values.Set("unfurl_media", "false")
- }
- if params.IconURL != DEFAULT_MESSAGE_ICON_URL {
- values.Set("icon_url", params.IconURL)
- }
- if params.IconEmoji != DEFAULT_MESSAGE_ICON_EMOJI {
- values.Set("icon_emoji", params.IconEmoji)
+}
+
+// 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 = escapeMessage(text)
+ }
+ config.values.Add("text", text)
+ return nil
}
- if params.Markdown != DEFAULT_MESSAGE_MARKDOWN {
- values.Set("mrkdwn", "false")
+}
+
+// MsgOptionAttachments provide attachments for the message.
+func MsgOptionAttachments(attachments ...Attachment) MsgOption {
+ return func(config *sendConfig) error {
+ if attachments == nil {
+ return nil
+ }
+
+ attachments, err := json.Marshal(attachments)
+ if err == nil {
+ config.values.Set("attachments", string(attachments))
+ }
+ return err
}
- if params.ThreadTimestamp != DEFAULT_MESSAGE_THREAD_TIMESTAMP {
- values.Set("thread_ts", params.ThreadTimestamp)
+}
+
+// MsgOptionEnableLinkUnfurl enables link unfurling
+func MsgOptionEnableLinkUnfurl() MsgOption {
+ return func(config *sendConfig) error {
+ config.values.Set("unfurl_links", "true")
+ return nil
}
+}
- response, err := chatRequest("chat.postMessage", values, api.debug)
- if err != nil {
- return "", "", err
+// MsgOptionDisableMediaUnfurl disables media unfurling.
+func MsgOptionDisableMediaUnfurl() MsgOption {
+ return func(config *sendConfig) error {
+ config.values.Set("unfurl_media", "false")
+ return nil
}
- return response.Channel, response.Timestamp, nil
}
-// UpdateMessage updates a message in a channel
-func (api *Client) UpdateMessage(channel, timestamp, text string) (string, string, string, error) {
- values := url.Values{
- "token": {api.config.token},
- "channel": {channel},
- "text": {escapeMessage(text)},
- "ts": {timestamp},
+// MsgOptionDisableMarkdown disables markdown.
+func MsgOptionDisableMarkdown() MsgOption {
+ return func(config *sendConfig) error {
+ config.values.Set("mrkdwn", "false")
+ return nil
}
- response, err := chatRequest("chat.update", values, api.debug)
- if err != nil {
- return "", "", "", err
+}
+
+// MsgOptionPostMessageParameters maintain backwards compatibility.
+func MsgOptionPostMessageParameters(params PostMessageParameters) MsgOption {
+ return func(config *sendConfig) error {
+ if params.Username != DEFAULT_MESSAGE_USERNAME {
+ config.values.Set("username", string(params.Username))
+ }
+
+ // never generates an error.
+ MsgOptionAsUser(params.AsUser)(config)
+
+ if params.Parse != DEFAULT_MESSAGE_PARSE {
+ config.values.Set("parse", string(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)
+ }
+
+ return nil
}
- return response.Channel, response.Timestamp, response.Text, nil
}