-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathmessage.go
More file actions
386 lines (326 loc) · 11.6 KB
/
message.go
File metadata and controls
386 lines (326 loc) · 11.6 KB
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
package message
import (
"strings"
stream "github.com/GetStream/stream-chat-go/v5"
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
chatUtils "github.com/GetStream/stream-cli/pkg/cmd/chat/utils"
"github.com/GetStream/stream-cli/pkg/config"
"github.com/GetStream/stream-cli/pkg/utils"
)
func NewCmds() []*cobra.Command {
return []*cobra.Command{
sendCmd(),
getCmd(),
getMultipleCmd(),
partialUpdateCmd(),
deleteCmd(),
flagCmd(),
translateCmd(),
updateMessageCmd(),
}
}
func sendCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send-message --channel-type [channel-type] --channel-id [channel-id] --text [text] --user [user-id]",
Short: "Send a message to a channel",
Example: heredoc.Doc(`
# Sends a message to 'redteam' channel of 'messaging' channel type
$ stream-cli chat send-message --channel-type messaging --channel-id redteam --text "Hello World!" --user "user-1"
# Sends a message to 'redteam' channel of 'livestream' channel type with an URL attachment
$ stream-cli chat send-message --channel-type livestream --channel-id redteam --attachment "https://example.com/image.png" --text "Hello World!" --user "user-1"
# You can also send a message with a local file attachment
# In this scenario, we'll upload the file first then send the message
$ stream-cli chat send-message --channel-type livestream --channel-id redteam --attachment "./image.png" --text "Hello World!" --user "user-1"
`),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
chType, _ := cmd.Flags().GetString("channel-type")
chID, _ := cmd.Flags().GetString("channel-id")
user, _ := cmd.Flags().GetString("user")
text, _ := cmd.Flags().GetString("text")
attachment, _ := cmd.Flags().GetString("attachment")
m := &stream.Message{Text: text}
if attachment != "" {
if strings.HasPrefix(attachment, "http") {
m.Attachments = []*stream.Attachment{{AssetURL: attachment}}
} else {
uri, err := chatUtils.UploadFile(c, cmd, chType, chID, user, attachment)
if err != nil {
return err
}
m.Attachments = []*stream.Attachment{{AssetURL: uri}}
}
}
msg, err := c.Channel(chType, chID).SendMessage(cmd.Context(), m, user)
if err != nil {
return err
}
cmd.Printf("Message successfully sent. Message id: [%s]\n", msg.Message.ID)
return nil
},
}
fl := cmd.Flags()
fl.StringP("channel-type", "t", "", "[required] Channel type such as 'messaging' or 'livestream'")
fl.StringP("channel-id", "i", "", "[required] Channel id")
fl.StringP("user", "u", "", "[required] User id")
fl.String("text", "", "[required] Text of the message")
fl.StringP("attachment", "a", "", "[optional] URL of the an attachment")
_ = cmd.MarkFlagRequired("channel-type")
_ = cmd.MarkFlagRequired("channel-id")
_ = cmd.MarkFlagRequired("user")
_ = cmd.MarkFlagRequired("text")
return cmd
}
func getCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "get-message [message-id] --output-format [json|tree]",
Short: "Return a single message",
Example: heredoc.Doc(`
# Returns a message with id 'msgid-1'
$ stream-cli chat get-message msgid-1
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
msg, err := c.GetMessage(cmd.Context(), args[0])
if err != nil {
return err
}
return utils.PrintObject(cmd, msg)
},
}
fl := cmd.Flags()
fl.StringP("output-format", "o", "json", "[optional] Output format. Can be json or tree")
return cmd
}
func getMultipleCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "get-messages --channel-type [channel-type] --channel-id [channel-id] --output-format [json|tree] [message-id-1] [message-id-2] [message-id ...]",
Short: "Return multiple messages",
Example: heredoc.Doc(`
# Returns 3 messages of 'redteam' channel of 'messaging' channel type
$ stream-cli chat get-messages --channel-type messaging --channel-id redteam msgid-1 msgid-2 msgid-3
`),
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
chType, _ := cmd.Flags().GetString("channel-type")
chID, _ := cmd.Flags().GetString("channel-id")
messages, err := c.Channel(chType, chID).GetMessages(cmd.Context(), args)
if err != nil {
return err
}
return utils.PrintObject(cmd, messages)
},
}
fl := cmd.Flags()
fl.StringP("channel-type", "t", "", "[required] Channel type such as 'messaging' or 'livestream'")
fl.StringP("channel-id", "i", "", "[required] Channel id")
fl.StringP("output-format", "o", "json", "[optional] Output format. Can be json or tree")
_ = cmd.MarkFlagRequired("channel-type")
_ = cmd.MarkFlagRequired("channel-id")
return cmd
}
func deleteCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "delete-message [message-id]",
Short: "Delete a message",
Long: heredoc.Doc(`
You can delete a message by calling DeleteMessage and including a message
with an ID. Messages can be soft deleted or hard deleted. Unless specified
via the hard parameter, messages are soft deleted. Be aware that deleting
a message doesn't delete its attachments.
`),
Example: heredoc.Doc(`
# Soft deletes a message with id 'msgid-1'
$ stream-cli chat delete-message msgid-1
# Hard deletes a message with id 'msgid-2'
$ stream-cli chat delete-message msgid-2 --hard
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
hard, _ := cmd.Flags().GetBool("hard")
if hard {
_, err = c.HardDeleteMessage(cmd.Context(), args[0])
} else {
_, err = c.DeleteMessage(cmd.Context(), args[0])
}
if err != nil {
return err
}
cmd.Printf("Message successfully deleted.\n")
return nil
},
}
fl := cmd.Flags()
fl.BoolP("hard", "H", false, "[optional] Hard delete message. Default is false")
return cmd
}
func partialUpdateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-message-partial --message-id [message-id] --user [user-id] --set [raw-json] --unset [property-names]",
Short: "Partially update a message",
Long: heredoc.Doc(`
A partial update can be used to set and unset specific fields when it
is necessary to retain additional data fields on the object. AKA a patch style update.
`),
Example: heredoc.Doc(`
# Partially updates a message with id 'msgid-1'. Updates a custom field and removes the silent flag.
$ stream-cli chat update-message-partial -message-id msgid-1 --set '{"importance": "low"}' --unset silent
`),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
msgId, _ := cmd.Flags().GetString("message-id")
user, _ := cmd.Flags().GetString("user")
update, err := utils.GetPartialUpdateParam(cmd.Flags())
if err != nil {
return err
}
_, err = c.PartialUpdateMessage(cmd.Context(), msgId, &stream.MessagePartialUpdateRequest{
UserID: user,
PartialUpdate: update,
})
if err != nil {
return err
}
cmd.Println("Successfully updated message.")
return nil
},
}
fl := cmd.Flags()
fl.StringP("message-id", "m", "", "[required] Message id")
fl.StringP("user", "u", "", "[required] User id")
fl.StringP("set", "s", "", "[optional] Raw JSON of key-value pairs to set")
fl.String("unset", "", "[optional] Comma separated list of properties to unset")
_ = cmd.MarkFlagRequired("message-id")
return cmd
}
func flagCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "flag-message --message-id [message-id] --user-id [user-id]",
Short: "Flag a message",
Long: heredoc.Doc(`
Any user is allowed to flag a message. This triggers the message.flagged webhook event
and adds the message to the inbox of your Stream Dashboard Chat Moderation view.
`),
Example: heredoc.Doc(`
# Flags a message with id 'msgid-1' by 'userid-1'
$ stream-cli chat flag-message --message-id msgid-1 --user-id userid-1
`),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
msgID, _ := cmd.Flags().GetString("message-id")
userID, _ := cmd.Flags().GetString("user-id")
_, err = c.FlagMessage(cmd.Context(), msgID, userID)
if err != nil {
return err
}
cmd.Println("Successfully flagged message.")
return nil
},
}
fl := cmd.Flags()
fl.StringP("message-id", "m", "", "[required] Message id to flag")
fl.StringP("user-id", "u", "", "[required] ID of the user who flagged the message")
_ = cmd.MarkFlagRequired("message-id")
_ = cmd.MarkFlagRequired("user-id")
return cmd
}
func translateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "translate-message --message-id [message-id] --language [language] --output-format [json|tree]",
Short: "Translate a message",
Long: heredoc.Doc(`
Chat messages can be translated on-demand or automatically, this
allows users speaking different languages on the same channel.
The translate endpoint returns the translated message, updates
it and sends a message.updated event to all users on the channel.
`),
Example: heredoc.Doc(`
# Translates a message with id 'msgid-1' to English
$ stream-cli chat translate-message --message-id msgid-1 --language en
`),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
msgID, _ := cmd.Flags().GetString("message-id")
lang, _ := cmd.Flags().GetString("language")
resp, err := c.TranslateMessage(cmd.Context(), msgID, lang)
if err != nil {
return err
}
return utils.PrintObject(cmd, resp.Message.I18n)
},
}
fl := cmd.Flags()
fl.StringP("message-id", "m", "", "[required] Message id to translate")
fl.StringP("language", "l", "", "[required] Language to translate to")
fl.StringP("output-format", "o", "json", "[optional] Output format. Can be json or tree")
_ = cmd.MarkFlagRequired("message-id")
_ = cmd.MarkFlagRequired("language")
return cmd
}
func updateMessageCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-message --message-id [id] --user [user-id] --text [text]",
Short: "Update an existing message",
Long: heredoc.Doc(`
Update a message by providing the message ID, user ID, and new message text.
This fully overwrites the message content while preserving metadata.
`),
Example: heredoc.Doc(`
# Update a message by ID
$ stream-cli chat update-message --message-id msgid-123 --user user123 --text "Updated message text"
`),
RunE: func(cmd *cobra.Command, args []string) error {
c, err := config.GetConfig(cmd).GetClient(cmd)
if err != nil {
return err
}
msgID, _ := cmd.Flags().GetString("message-id")
userID, _ := cmd.Flags().GetString("user")
text, _ := cmd.Flags().GetString("text")
updatedMsg := &stream.Message{
ID: msgID,
Text: text,
User: &stream.User{ID: userID},
}
_, err = c.UpdateMessage(cmd.Context(), updatedMsg, msgID)
if err != nil {
return err
}
cmd.Println("Successfully updated message.")
return nil
},
}
fl := cmd.Flags()
fl.String("message-id", "", "[required] ID of the message to update")
fl.String("user", "", "[required] User ID performing the update")
fl.String("text", "", "[required] New message text")
_ = cmd.MarkFlagRequired("message-id")
_ = cmd.MarkFlagRequired("user")
_ = cmd.MarkFlagRequired("text")
return cmd
}