Codebase list golang-github-nlopes-slack / 45fb4cb
working reactions.list Ryan Carver 8 years ago
2 changed file(s) with 208 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
55 "net/url"
66 )
77
8 // Reaction is the act of reacting to an item.
9 type Reaction struct {
10 Name string `json:"name"`
11 ItemRef
12 }
13
148 // ItemReaction is the reactions that have happened on an item.
159 type ItemReaction struct {
1610 Name string `json:"name"`
1812 Users []string `json:"users"`
1913 }
2014
21 // ReactedToItem is an item that was reacted to, and the details of the
22 // reaction.
23 type ReactedToItem struct {
24 Item
25 ItemReaction
15 // ReactedItem is an item that was reacted to, and the details of the
16 // reactions.
17 type ReactedItem struct {
18 Type string
19 Message *Message
20 File *File
21 Comment *Comment
22 Reactions []ItemReaction
2623 }
2724
2825 // AddReactionParameters is the inputs to create a new reaction.
2926 type AddReactionParameters struct {
27 Name string
3028 ItemRef
31 Name string
3229 }
3330
3431 // NewAddReactionParameters initialies the inputs to react to an item.
3633 return AddReactionParameters{Name: name, ItemRef: ref}
3734 }
3835
39 // GetReactionParameters is the inputs to get reactions on an item.
36 // GetReactionParameters is the inputs to get reactions to an item.
4037 type GetReactionParameters struct {
38 Full bool
4139 ItemRef
42 Full bool
43 }
44
45 // NewGetReactionParameters initializes the inputs to get reactions on an item.
40 }
41
42 // NewGetReactionParameters initializes the inputs to get reactions to an item.
4643 func NewGetReactionParameters(ref ItemRef) GetReactionParameters {
4744 return GetReactionParameters{ItemRef: ref}
4845 }
4946
5047 type getReactionsResponseFull struct {
51 Message struct {
52 Type string
53 Message struct {
54 Reactions []ItemReaction
55 }
56 File struct {
57 Reactions []ItemReaction
58 }
59 FileComment struct {
48 M struct {
49 Type string
50 M struct {
51 Reactions []ItemReaction
52 } `json:"message"`
53 F struct {
54 Reactions []ItemReaction
55 } `json:"file"`
56 FC struct {
6057 Comment struct {
6158 Reactions []ItemReaction
6259 }
6360 } `json:"file_comment"`
64 }
61 } `json:"message"`
6562 SlackResponse
6663 }
6764
68 func (res getReactionsResponseFull) FindReactions() []ItemReaction {
69 switch res.Message.Type {
65 func (res getReactionsResponseFull) extractReactions() []ItemReaction {
66 switch res.M.Type {
7067 case "message":
71 return res.Message.Message.Reactions
68 return res.M.M.Reactions
7269 case "file":
73 return res.Message.File.Reactions
70 return res.M.F.Reactions
7471 case "file_comment":
75 return res.Message.FileComment.Comment.Reactions
72 return res.M.FC.Comment.Reactions
7673 }
7774 return []ItemReaction{}
7875 }
9289 Full bool
9390 }
9491
95 // NewListReactionsParameters initializes the inputs to find all reactions by a user.
92 // NewListReactionsParameters initializes the inputs to find all reactions
93 // performed by a user.
9694 func NewListReactionsParameters(userID string) ListReactionsParameters {
9795 return ListReactionsParameters{
9896 User: userID,
104102
105103 type listReactionsResponseFull struct {
106104 Items []struct {
107 Message struct {
108 Reactions []ItemReaction
105 Type string
106 M struct {
107 *Message
108 Reactions []ItemReaction
109 } `json:"message"`
110 F struct {
111 *File
112 Reactions []ItemReaction
113 } `json:"file"`
114 FC struct {
115 C struct {
116 *Comment
117 Reactions []ItemReaction
118 } `json:"comment"`
119 } `json:"file_comment"`
120 }
121 Paging `json:"paging"`
122 SlackResponse
123 }
124
125 func (res listReactionsResponseFull) extractReactedItems() []ReactedItem {
126 items := make([]ReactedItem, len(res.Items))
127 for i, input := range res.Items {
128 item := ReactedItem{
129 Type: input.Type,
109130 }
110 }
111 SlackResponse
131 switch input.Type {
132 case "message":
133 item.Message = input.M.Message
134 item.Reactions = input.M.Reactions
135 case "file":
136 item.File = input.F.File
137 item.Reactions = input.F.Reactions
138 case "file_comment":
139 item.Comment = input.FC.C.Comment
140 item.Reactions = input.FC.C.Reactions
141 }
142 items[i] = item
143 }
144 return items
112145 }
113146
114147 // AddReaction adds a reaction emoji to a message, file or file comment.
168201 if !response.Ok {
169202 return nil, errors.New(response.Error)
170203 }
171 return response.FindReactions(), nil
204 return response.extractReactions(), nil
172205 }
173206
174207 // ListReactions returns information about the items a user reacted to.
175 func (api *Slack) ListReactions(params ListReactionsParameters) ([]ReactedToItem, Paging, error) {
208 func (api *Slack) ListReactions(params ListReactionsParameters) ([]ReactedItem, Paging, error) {
176209 values := url.Values{
177210 "token": {api.config.token},
178211 }
180213 values.Add("user", params.User)
181214 }
182215 if params.Count != DEFAULT_REACTIONS_COUNT {
183 values.Add("count", string(params.Count))
216 values.Add("count", fmt.Sprintf("%d", params.Count))
184217 }
185218 if params.Page != DEFAULT_REACTIONS_PAGE {
186 values.Add("count", string(params.Page))
219 values.Add("page", fmt.Sprintf("%d", params.Page))
187220 }
188221 if params.Full != DEFAULT_REACTIONS_FULL {
189 values.Add("count", fmt.Sprintf("%t", params.Full))
222 values.Add("full", fmt.Sprintf("%t", params.Full))
190223 }
191224 response := &listReactionsResponseFull{}
192225 err := parseResponse("reactions.list", values, response, api.debug)
196229 if !response.Ok {
197230 return nil, Paging{}, errors.New(response.Error)
198231 }
199 return nil, Paging{}, nil
200 }
232 return response.extractReactedItems(), response.Paging, nil
233 }
00 package slack
11
22 import (
3 "fmt"
34 "net/http"
45 "reflect"
56 "testing"
89 func init() {
910 http.HandleFunc("/reactions.add", addReactionHandler)
1011 http.HandleFunc("/reactions.get", getReactionHandler)
12 http.HandleFunc("/reactions.list", listReactionHandler)
1113 }
1214
1315 var (
14 gotParams map[string]string
15 addedReaction Reaction
16 getReactionRes string
17 gottenReactionRef ItemRef
16 gotParams map[string]string
17 getReactionRes string
18 listReactionRes string
1819 )
1920
2021 func accumulateFormValue(k string, r *http.Request) {
4142 accumulateFormValue("full", r)
4243 w.Header().Set("Content-Type", "application/json")
4344 w.Write([]byte(getReactionRes))
45 }
46
47 func listReactionHandler(w http.ResponseWriter, r *http.Request) {
48 accumulateFormValue("user", r)
49 accumulateFormValue("count", r)
50 accumulateFormValue("full", r)
51 accumulateFormValue("page", r)
52 w.Header().Set("Content-Type", "application/json")
53 w.Write([]byte(listReactionRes))
4454 }
4555
4656 func TestSlack_AddReaction_ToMessage(t *testing.T) {
234244 t.Errorf("Got params %#v, want %#v", gotParams, wantParams)
235245 }
236246 }
247
248 func TestSlack_ListReactions(t *testing.T) {
249 once.Do(startServer)
250 SLACK_API = "http://" + serverAddr + "/"
251 api := New("testing-token")
252 listReactionRes = `{"ok": true,
253 "items": [
254 {
255 "type": "message",
256 "message": {
257 "text": "hello",
258 "reactions": [
259 {
260 "name": "astonished",
261 "count": 3,
262 "users": [ "U1", "U2", "U3" ]
263 },
264 {
265 "name": "clock1",
266 "count": 3,
267 "users": [ "U1", "U2" ]
268 }
269 ]
270 }
271 },
272 {
273 "type": "file",
274 "file": {
275 "name": "toy",
276 "reactions": [
277 {
278 "name": "clock1",
279 "count": 3,
280 "users": [ "U1", "U2" ]
281 }
282 ]
283 }
284 },
285 {
286 "type": "file_comment",
287 "file_comment": {
288 "file": {},
289 "comment": {
290 "comment": "cool toy",
291 "reactions": [
292 {
293 "name": "astonished",
294 "count": 3,
295 "users": [ "U1", "U2", "U3" ]
296 }
297 ]
298 }
299 }
300 }
301 ],
302 "paging": {
303 "count": 100,
304 "total": 4,
305 "page": 1,
306 "pages": 1
307 }}`
308 want := []ReactedItem{
309 ReactedItem{
310 Type: "message",
311 Message: &Message{Msg: Msg{Text: "hello"}},
312 Reactions: []ItemReaction{
313 ItemReaction{Name: "astonished", Count: 3, Users: []string{"U1", "U2", "U3"}},
314 ItemReaction{Name: "clock1", Count: 3, Users: []string{"U1", "U2"}},
315 },
316 },
317 ReactedItem{
318 Type: "file",
319 File: &File{Name: "toy"},
320 Reactions: []ItemReaction{
321 ItemReaction{Name: "clock1", Count: 3, Users: []string{"U1", "U2"}},
322 },
323 },
324 ReactedItem{
325 Type: "file_comment",
326 Comment: &Comment{Comment: "cool toy"},
327 Reactions: []ItemReaction{
328 ItemReaction{Name: "astonished", Count: 3, Users: []string{"U1", "U2", "U3"}},
329 },
330 },
331 }
332 wantParams := map[string]string{
333 "user": "UserID",
334 "count": "200",
335 "page": "2",
336 "full": "true",
337 }
338 gotParams = map[string]string{}
339 params := NewListReactionsParameters("UserID")
340 params.Count = 200
341 params.Page = 2
342 params.Full = true
343 got, paging, err := api.ListReactions(params)
344 if err != nil {
345 t.Fatalf("Unexpected error: %s", err)
346 }
347 if !reflect.DeepEqual(got, want) {
348 t.Errorf("Got reaction %#v, want %#v", got, want)
349 for i, item := range got {
350 fmt.Printf("Item %d, Type: %s\n", i, item.Type)
351 fmt.Printf("Message %#v\n", item.Message)
352 fmt.Printf("File %#v\n", item.File)
353 fmt.Printf("Comment %#v\n", item.Comment)
354 fmt.Printf("Reactions %#v\n", item.Reactions)
355 }
356 }
357 if !reflect.DeepEqual(gotParams, wantParams) {
358 t.Errorf("Got params %#v, want %#v", gotParams, wantParams)
359 }
360 if reflect.DeepEqual(paging, Paging{}) {
361 t.Errorf("Want paging data, got empty struct")
362 }
363 }