-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlast_week_data.go
220 lines (207 loc) · 6.19 KB
/
last_week_data.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package main
import (
"errors"
"fmt"
"math"
"sort"
"strconv"
"strings"
"time"
"github.com/ryho/slack-emoji-bot/util"
"github.com/slack-go/slack"
)
func dealWithLastWeekMessages() error {
if overRideLastNewEmoji != "" {
// If overriding the last new emoji, assume that we are also not
// able to get last week's votes.
lastNewEmoji = overRideLastNewEmoji
previousLastNewEmoji = overRideLastNewEmoji
return nil
}
// Get the emojis channel
emojiChannelId, err := getChannel(emojiChannel)
if err != nil {
return err
}
// Get the two messages that we need
message, lastEmojiMessage, previousLastEmojiMessage, err := findLastWeekMessages(emojiChannelId)
reactionMessage = message
if err != nil {
return err
}
// Find the last emoji that was posted last week.
parts := strings.Split(lastEmojiMessage.Text, ":")
if len(parts) < 2 {
return fmt.Errorf("Unable to get last emoji from message %v", lastEmojiMessage)
}
lastNewEmoji = parts[len(parts)-2]
parts = strings.Split(previousLastEmojiMessage.Text, ":")
if len(parts) < 2 {
return fmt.Errorf("Unable to get last emoji from message %v", lastEmojiMessage)
}
previousLastNewEmoji = parts[len(parts)-2]
return nil
}
func findLastWeekMessages(emojiChannelId string) (*slack.Message, *slack.Message, *slack.Message, error) {
conversationParams := &slack.GetConversationHistoryParameters{
ChannelID: emojiChannelId,
}
var reactionMessage, lastEmojiMessage, previousWeekLastEmojiMessage slack.Message
var foundOne, foundTwo, foundThree, foundFour bool
for true {
messages, err := GetConversationHistoryWithBackoff(conversationParams)
if err != nil {
return nil, nil, nil, err
}
if foundOne && !foundTwo {
if len(messages.Messages) == 0 {
return nil, nil, nil, errors.New("Unable to find message " + emojiChannel)
}
lastEmojiMessage = messages.Messages[0]
foundTwo = true
}
if foundThree && !foundFour {
if len(messages.Messages) == 0 {
return nil, nil, nil, errors.New("Unable to find message " + emojiChannel)
}
lastEmojiMessage = messages.Messages[0]
foundTwo = true
}
for i, message := range messages.Messages {
if message.Text == votePrompt || message.Text == votePromptPrevious {
if !foundOne {
reactionMessage = message
foundOne = true
if len(messages.Messages) >= i {
lastEmojiMessage = messages.Messages[i+1]
foundTwo = true
}
} else {
previousWeekLastEmojiMessage = message
foundThree = true
if len(messages.Messages) >= i {
previousWeekLastEmojiMessage = messages.Messages[i+1]
foundFour = true
break
}
}
}
}
if foundFour {
break
}
if len(messages.ResponseMetaData.NextCursor) == 0 {
return nil, nil, nil, errors.New("Unable to find message in channel " + emojiChannel)
}
// Check if we have looked through 15 days
lastMessageTime, err := timeFromMessage(&messages.Messages[len(messages.Messages)-1])
if err != nil {
return nil, nil, nil, err
}
if time.Since(lastMessageTime) > time.Hour*24*16 {
return nil, nil, nil, errors.New("Unable to find message in channel " + emojiChannel + " in the last 15 days")
}
conversationParams.Cursor = messages.ResponseMetaData.NextCursor
}
return &reactionMessage, &lastEmojiMessage, &previousWeekLastEmojiMessage, nil
}
func timeFromMessage(message *slack.Message) (time.Time, error) {
seconds, err := strconv.ParseFloat(message.Timestamp, 64)
if err != nil {
return time.Time{}, err
}
return time.Unix(0, int64(float64(time.Second)*seconds)), nil
}
func getChannel(channelName string) (string, error) {
if len(channelName) == 0 {
return "", errors.New("No channel name provided")
}
if cachedChannelID != "" {
return cachedChannelID, nil
}
if channelName[0] == '#' {
channelName = channelName[1:]
}
channelsParams := &slack.GetConversationsParameters{
ExcludeArchived: true,
Limit: 1000,
}
var emojiChannelData slack.Channel
for true {
channels, cursor, err := GetConversationsWithBackoff(channelsParams)
if err != nil {
return "", err
}
var found bool
for _, channel := range channels {
if channel.IsChannel && channel.Name == channelName {
found = true
emojiChannelData = channel
break
}
}
if found {
break
}
if cursor == "" {
return "", errors.New("Unable to find channel " + emojiChannel)
}
channelsParams.Cursor = cursor
}
fmt.Printf("Found Channel ID: %v. You can set this in cachedChannelID in config.go for faster run times.\n", emojiChannelData.ID)
return emojiChannelData.ID, nil
}
func printTopEmojisByReactionVote(allEmojis *SlackEmojiResponseMessage, doEmojisWrapped bool, maxPrintCount int, messages ...*slack.Message) error {
var emojis []*stringCount
uniqueUsers := util.StringSet{}
for _, message := range messages {
for _, reaction := range message.Reactions {
emojis = append(emojis, &stringCount{name: reaction.Name, count: reaction.Count})
for _, user := range reaction.Users {
uniqueUsers[user] = util.SetEntry{}
}
}
}
sort.Sort(ByCount(emojis))
printedCount := 0
previousCount := math.MaxInt64
minReaction := 3
var creators []string
var counts []int
var printedEmojis []string
for _, emoji := range emojis {
// Stop if we have printed enough emojis, however, always print all emojis with the same reaction
// count even if we go over the limit.
if emoji.count != previousCount && printedCount >= maxPrintCount {
break
}
// Stop if the reaction count is too low, even if we have not hit the limit.
if emoji.count < minReaction {
break
}
emojisObj := allEmojis.emojiMap[emoji.name]
creators = append(creators, emojisObj.UserId)
counts = append(counts, emoji.count)
var name string
if aprilFoolsMode {
name = aprilFoolsEmoji
} else {
name = emoji.name
}
printedEmojis = append(printedEmojis, name)
previousCount = emoji.count
printedCount++
}
peopleToPrint := TopPeopleToPrint
message := fmt.Sprintf(lastWeek, len(uniqueUsers))
if doEmojisWrapped {
peopleToPrint = 20
rightNow := time.Now()
year := rightNow.Year()
if rightNow.Month() == time.January {
year--
}
message = fmt.Sprintf(lastYear, year, len(uniqueUsers))
}
return printTopCreators(message, peopleToPrint, creators, counts, printedEmojis)
}