forked from slack-go/slack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chat.go
171 lines (160 loc) · 5.47 KB
/
chat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package slack
import (
"encoding/json"
"errors"
"net/url"
"strings"
)
const (
DEFAULT_MESSAGE_USERNAME = ""
DEFAULT_MESSAGE_THREAD_TIMESTAMP = ""
DEFAULT_MESSAGE_ASUSER = false
DEFAULT_MESSAGE_PARSE = ""
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"`
Text string `json:"text"`
SlackResponse
}
// PostMessageParameters contains all the parameters necessary (including the optional ones) for a PostMessage() request
type PostMessageParameters struct {
Text string `json:"text"`
Username string `json:"user_name"`
AsUser bool `json:"as_user"`
Parse string `json:"parse"`
ThreadTimestamp string `json:"thread_ts"`
LinkNames int `json:"link_names"`
Attachments []Attachment `json:"attachments"`
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"`
}
// NewPostMessageParameters provides an instance of PostMessageParameters with all the sane default values set
func NewPostMessageParameters() PostMessageParameters {
return PostMessageParameters{
Username: DEFAULT_MESSAGE_USERNAME,
AsUser: DEFAULT_MESSAGE_ASUSER,
Parse: DEFAULT_MESSAGE_PARSE,
LinkNames: DEFAULT_MESSAGE_LINK_NAMES,
Attachments: nil,
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,
}
}
func chatRequest(path string, values url.Values, debug bool) (*chatResponseFull, error) {
response := &chatResponseFull{}
err := post(path, values, response, debug)
if err != nil {
return nil, err
}
if !response.Ok {
return nil, errors.New(response.Error)
}
return response, 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},
}
response, err := chatRequest("chat.delete", values, api.debug)
if err != nil {
return "", "", err
}
return response.Channel, response.Timestamp, nil
}
func escapeMessage(message string) string {
replacer := strings.NewReplacer("&", "&", "<", "<", ">", ">")
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},
}
if params.Username != DEFAULT_MESSAGE_USERNAME {
values.Set("username", string(params.Username))
}
if params.AsUser != DEFAULT_MESSAGE_ASUSER {
values.Set("as_user", "true")
}
if params.Parse != DEFAULT_MESSAGE_PARSE {
values.Set("parse", string(params.Parse))
}
if params.LinkNames != DEFAULT_MESSAGE_LINK_NAMES {
values.Set("link_names", "1")
}
if params.Attachments != nil {
attachments, err := json.Marshal(params.Attachments)
if err != nil {
return "", "", err
}
values.Set("attachments", string(attachments))
}
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)
}
if params.Markdown != DEFAULT_MESSAGE_MARKDOWN {
values.Set("mrkdwn", "false")
}
if params.ThreadTimestamp != DEFAULT_MESSAGE_THREAD_TIMESTAMP {
values.Set("thread_ts", params.ThreadTimestamp)
}
response, err := chatRequest("chat.postMessage", values, api.debug)
if err != nil {
return "", "", err
}
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},
}
response, err := chatRequest("chat.update", values, api.debug)
if err != nil {
return "", "", "", err
}
return response.Channel, response.Timestamp, response.Text, nil
}