-
Notifications
You must be signed in to change notification settings - Fork 31
/
event.go
183 lines (148 loc) · 6.04 KB
/
event.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
package stream_chat // nolint: golint
import (
"encoding/json"
"errors"
"net/http"
"net/url"
"path"
"time"
)
// EventType marks which of the various sub-types of a webhook event you are
// receiving or sending.
type EventType string
const (
// EventMessageNew is fired when a new message is added.
EventMessageNew EventType = "message.new"
// EventMessageUpdated is fired when a message is updated.
EventMessageUpdated EventType = "message.updated"
// EventMessageDeleted is fired when a message is deleted.
EventMessageDeleted EventType = "message.deleted"
// EventMessageRead is fired when a user calls mark as read.
EventMessageRead EventType = "message.read"
// EventReactionNew is fired when a message reaction is added.
EventReactionNew EventType = "reaction.new"
// EventReactionDeleted is fired when a message reaction deleted.
EventReactionDeleted EventType = "reaction.deleted"
// EventMemberAdded is fired when a member is added to a channel.
EventMemberAdded EventType = "member.added"
// EventMemberUpdated is fired when a member is updated.
EventMemberUpdated EventType = "member.updated"
// EventMemberRemoved is fired when a member is removed from a channel.
EventMemberRemoved EventType = "member.removed"
// EventChannelCreated is fired when a channel is created.
EventChannelCreated EventType = "channel.created"
// EventChannelUpdated is fired when a channel is updated.
EventChannelUpdated EventType = "channel.updated"
// EventChannelDeleted is fired when a channel is deleted.
EventChannelDeleted EventType = "channel.deleted"
// EventChannelTruncated is fired when a channel is truncated.
EventChannelTruncated EventType = "channel.truncated"
// EventHealthCheck is fired when a user is updated.
EventHealthCheck EventType = "health.check"
// EventNotificationNewMessage and family are fired when a notification is
// created, marked read, invited to a channel, and so on.
EventNotificationNewMessage EventType = "notification.message_new"
EventNotificationMarkRead EventType = "notification.mark_read"
EventNotificationInvited EventType = "notification.invited"
EventNotificationInviteAccepted EventType = "notification.invite_accepted"
EventNotificationAddedToChannel EventType = "notification.added_to_channel"
EventNotificationRemovedFromChannel EventType = "notification.removed_from_channel"
EventNotificationMutesUpdated EventType = "notification.mutes_updated"
// EventTypingStart and EventTypingStop are fired when a user starts or stops typing.
EventTypingStart EventType = "typing.start"
EventTypingStop EventType = "typing.stop"
// EventUserMuted is fired when a user is muted.
EventUserMuted EventType = "user.muted"
// EventUserUnmuted is fired when a user is unmuted.
EventUserUnmuted EventType = "user.unmuted"
EventUserPresenceChanged EventType = "user.presence.changed"
EventUserWatchingStart EventType = "user.watching.start"
EventUserWatchingStop EventType = "user.watching.stop"
EventUserUpdated EventType = "user.updated"
)
// Event is received from a webhook, or sent with the SendEvent function.
type Event struct {
CID string `json:"cid,omitempty"` // Channel ID
Type EventType `json:"type"` // Event type, one of Event* constants
Message *Message `json:"message,omitempty"`
Reaction *Reaction `json:"reaction,omitempty"`
Channel *Channel `json:"channel,omitempty"`
Member *ChannelMember `json:"member,omitempty"`
Members []*ChannelMember `json:"members,omitempty"`
User *User `json:"user,omitempty"`
UserID string `json:"user_id,omitempty"`
OwnUser *User `json:"me,omitempty"`
WatcherCount int `json:"watcher_count,omitempty"`
ExtraData map[string]interface{} `json:"-"`
CreatedAt time.Time `json:"created_at,omitempty"`
}
type eventForJSON Event
func (e *Event) UnmarshalJSON(data []byte) error {
var e2 eventForJSON
if err := json.Unmarshal(data, &e2); err != nil {
return err
}
*e = Event(e2)
if err := json.Unmarshal(data, &e.ExtraData); err != nil {
return err
}
removeFromMap(e.ExtraData, *e)
return nil
}
func (e Event) MarshalJSON() ([]byte, error) {
return addToMapAndMarshal(e.ExtraData, eventForJSON(e))
}
// SendEvent sends an event on this channel.
func (ch *Channel) SendEvent(event *Event, userID string) error {
if event == nil {
return errors.New("event is nil")
}
event.User = &User{ID: userID}
req := struct {
Event *Event `json:"event"`
}{
Event: event,
}
p := path.Join("channels", url.PathEscape(ch.Type), url.PathEscape(ch.ID), "event")
return ch.client.makeRequest(http.MethodPost, p, nil, req, nil)
}
// UserCustomEvent is a custom event sent to a particular user.
type UserCustomEvent struct {
// Type should be a custom type. Using a built-in event is not supported here.
Type string `json:"type"`
ExtraData map[string]interface{} `json:"-"`
CreatedAt time.Time `json:"created_at,omitempty"`
}
type userCustomEventForJSON UserCustomEvent
func (e *UserCustomEvent) UnmarshalJSON(data []byte) error {
// TODO: merge this method with Event.UnmarshalJSON
var e2 userCustomEventForJSON
if err := json.Unmarshal(data, &e2); err != nil {
return err
}
*e = UserCustomEvent(e2)
if err := json.Unmarshal(data, &e.ExtraData); err != nil {
return err
}
removeFromMap(e.ExtraData, *e)
return nil
}
func (e UserCustomEvent) MarshalJSON() ([]byte, error) {
return addToMapAndMarshal(e.ExtraData, userCustomEventForJSON(e))
}
// SendUserCustomEvent sends a custom event to all connected clients for the target user id.
func (c *Client) SendUserCustomEvent(targetUserID string, event *UserCustomEvent) error {
if event == nil {
return errors.New("event is nil")
}
if targetUserID == "" {
return errors.New("targetUserID should not be empty")
}
req := struct {
Event *UserCustomEvent `json:"event"`
}{
Event: event,
}
p := path.Join("users", url.PathEscape(targetUserID), "event")
return c.makeRequest(http.MethodPost, p, nil, req, nil)
}