-
Notifications
You must be signed in to change notification settings - Fork 0
/
slack.go
127 lines (105 loc) · 2.9 KB
/
slack.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
package slack
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
)
const slackApiUrl = "https://slack.com/api/"
// VerifySignature will verify request comes from slack.
// See also https://api.slack.com/authentication/verifying-requests-from-slack
func VerifySignature(headers http.Header, body []byte, signingSecret string) bool {
versionNumber := "v0"
timestamp := headers.Get("X-Slack-Request-Timestamp")
expectedSignature := headers.Get("X-Slack-Signature")
textToEncrypt := fmt.Sprintf(
"%s:%s:%s",
versionNumber,
timestamp,
string(body),
)
hash := hmac.New(sha256.New, []byte(signingSecret))
hash.Write([]byte(textToEncrypt))
encryptedResult := hex.EncodeToString(hash.Sum(nil))
encryptedResultWithVersionNumber := "v0=" + encryptedResult
return hmac.Equal(
[]byte(expectedSignature),
[]byte(encryptedResultWithVersionNumber),
)
}
type MessageTs string
func SendMessage(
message string,
channel string,
threadTs string,
slackBotToken string,
) MessageTs {
slackUrl := slackApiUrl + "chat.postMessage"
payload := createChatMessagePayload(message, channel, threadTs)
return sendMessage(slackUrl, payload, slackBotToken)
}
func UpdateMessage(
message string,
channel string,
ts MessageTs,
slackBotToken string,
) MessageTs {
slackUrl := slackApiUrl + "chat.update"
payload := createChatUpdatePayload(message, channel, ts)
return sendMessage(slackUrl, payload, slackBotToken)
}
func createChatMessagePayload(message string, channel string, ts string) string {
payload := map[string]interface{}{
"channel": channel,
"text": message,
"thread_ts": ts,
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
log.Printf("Error marshaling JSON: %v", err)
return ""
}
return string(jsonPayload)
}
func createChatUpdatePayload(message string, channel string, ts MessageTs) string {
payload := map[string]interface{}{
"channel": channel,
"text": message,
"ts": ts,
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
log.Printf("Error marshaling JSON: %v", err)
return ""
}
return string(jsonPayload)
}
func sendMessage(slackUrl string, payload string, slackBotToken string) MessageTs {
req, err := http.NewRequest("POST", slackUrl, strings.NewReader(payload))
if err != nil {
log.Printf("Error creating request: %v", err)
return ""
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+slackBotToken)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Printf("Error sending message: %v", err)
return ""
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
log.Printf("Slack API response: %s", string(body))
var response map[string]interface{}
if err := json.Unmarshal(body, &response); err != nil {
log.Printf("Error parsing JSON: %v", err)
return ""
}
return MessageTs(response["ts"].(string))
}