-
Notifications
You must be signed in to change notification settings - Fork 0
/
slack_interactive.go
132 lines (110 loc) · 3.78 KB
/
slack_interactive.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
package main
import (
"encoding/json"
"gorm.io/gorm"
"net/http"
"net/url"
"strings"
)
type SlackInteractiveHandler struct {
DB *gorm.DB
Slack *Slack
}
func (params SlackInteractiveHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
requestBody, err := verifyRequest(r)
if err != nil {
panic(err)
}
payload, err := url.QueryUnescape(string(requestBody))
if err != nil {
panic(err)
}
payload = strings.TrimPrefix(payload, "payload=")
var jsonBody map[string]interface{}
err = json.Unmarshal([]byte(payload), &jsonBody)
if err != nil {
panic(err)
}
var ok bool
var opaqueActions []interface{}
if opaqueActions, ok = jsonBody["actions"].([]interface{}); !ok {
log.Warning("unable to extract actions", jsonBody)
return
}
for _, opaqueAction := range opaqueActions {
var action map[string]interface{}
if action, ok = opaqueAction.(map[string]interface{}); !ok {
log.Warning("unable to convert action to json dict: ", jsonBody)
continue
}
var actionId string
if actionId, ok = action["action_id"].(string); !ok {
log.Warning("unable to convert actionId to string: ", jsonBody)
continue
}
if strings.HasPrefix(actionId, "feedback_msg:") {
if err = params.handleFeedbackMsg(jsonBody, actionId); err != nil {
panic(err)
}
} else {
log.Warning("unknown actionId: " + actionId)
continue
}
}
}
func (params SlackInteractiveHandler) handleFeedbackMsg(reqBody map[string]interface{}, actionId string) error {
var bagel Bagel
var feedbackMsg FeedbackMsg
var incomplete, planned, completed bool
if params.DB.Where("incomplete_action_id = ?", actionId).Find(&feedbackMsg); feedbackMsg.ID != 0 {
if err := params.DB.Model(&feedbackMsg).Association("bagels").Find(&bagel); err != nil {
return err
}
incomplete = true
} else if params.DB.Where("planned_action_id = ?", actionId).Find(&feedbackMsg); feedbackMsg.ID != 0 {
if err := params.DB.Model(&feedbackMsg).Association("bagels").Find(&bagel); err != nil {
return err
}
planned = true
} else if params.DB.Where("completed_action_id = ?", actionId).Find(&feedbackMsg); feedbackMsg.ID != 0 {
if err := params.DB.Model(&feedbackMsg).Association("bagels").Find(&bagel); err != nil {
return err
}
completed = true
} else {
log.Warning("unable to find feedback msg with actionId ", actionId)
}
if bagel.ID == 0 {
log.Warning("unable to find bagel from feedback msg")
return nil
}
log.Infof("updating status for bagel %d: IsPlanned(%t) IsCompleted(%t)", bagel.ID, planned, completed)
bagel.IsPlanned = planned
bagel.IsCompleted = completed
params.DB.Save(&bagel)
var blocks []interface{}
if incomplete {
blocks = SlackBlocks_FeedbackMsg(feedbackMsg, "😥 I'm sad that you've decided not to meet up. If you change your mind, you can always push the buttons below to let me know.")
} else if planned {
blocks = SlackBlocks_FeedbackMsg(feedbackMsg, "😀 Great! I'm exited that you've planned to chat. Once you do meet up, go ahead and push the button below to let me know you've 🥯'd. And don't forget about posting a selfie to the #bagel-chats channel.")
} else if completed {
blocks = SlackBlocks_FeedbackMsg(feedbackMsg, "😁 Perfect! Thank you for contributing to AppDev's social culture.")
}
var ok bool
var container map[string]interface{}
if container, ok = reqBody["container"].(map[string]interface{}); !ok {
log.Warning("unable to extract container", reqBody)
return nil
}
var ts string
if ts, ok = container["message_ts"].(string); !ok {
log.Warning("unable to extract timestamp", reqBody)
return nil
}
var channelID string
if channelID, ok = container["channel_id"].(string); !ok {
log.Warning("unable to extract channel id", reqBody)
return nil
}
return params.Slack.ChatUpdate(channelID, ts, "Someone responded to bagel feedback", blocks)
}