-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathChat.cs
452 lines (380 loc) · 23.6 KB
/
Chat.cs
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
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using TwitchLib.Api.Core;
using TwitchLib.Api.Core.Enums;
using TwitchLib.Api.Core.Exceptions;
using TwitchLib.Api.Core.Interfaces;
using TwitchLib.Api.Helix.Models.Channels.SendChatMessage;
using TwitchLib.Api.Helix.Models.Chat;
using TwitchLib.Api.Helix.Models.Chat.Badges.GetChannelChatBadges;
using TwitchLib.Api.Helix.Models.Chat.Badges.GetGlobalChatBadges;
using TwitchLib.Api.Helix.Models.Chat.ChatSettings;
using TwitchLib.Api.Helix.Models.Chat.Emotes.GetChannelEmotes;
using TwitchLib.Api.Helix.Models.Chat.Emotes.GetEmoteSets;
using TwitchLib.Api.Helix.Models.Chat.Emotes.GetGlobalEmotes;
using TwitchLib.Api.Helix.Models.Chat.Emotes.GetUserEmotes;
using TwitchLib.Api.Helix.Models.Chat.GetChatters;
using TwitchLib.Api.Helix.Models.Chat.GetUserChatColor;
namespace TwitchLib.Api.Helix
{
/// <summary>
/// Chat related APIs
/// </summary>
public class Chat : ApiBase
{
public Chat(IApiSettings settings, IRateLimiter rateLimiter, IHttpCallHandler http) : base(settings, rateLimiter, http)
{ }
#region Badges
/// <summary>
/// Gets a list of custom chat badges that can be used in chat for the specified channel. This includes subscriber badges and Bit badges.
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster whose chat badges you want to get.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetChannelChatBadgesResponse"></returns>
public Task<GetChannelChatBadgesResponse> GetChannelChatBadgesAsync(string broadcasterId, string accessToken = null)
{
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId)
};
return TwitchGetGenericAsync<GetChannelChatBadgesResponse>("/chat/badges", ApiVersion.Helix, getParams, accessToken);
}
/// <summary>
/// Gets a list of chat badges that can be used in chat for any channel.
/// </summary>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetGlobalChatBadgesResponse"></returns>
public Task<GetGlobalChatBadgesResponse> GetGlobalChatBadgesAsync(string accessToken = null)
{
return TwitchGetGenericAsync<GetGlobalChatBadgesResponse>("/chat/badges/global", ApiVersion.Helix, accessToken: accessToken);
}
#endregion
#region Chatters
/// <summary>
/// Gets the list of users that are connected to the specified broadcaster’s chat session.
/// <para>Note that there is a delay between when users join and leave a chat and when the list is updated accordingly.</para>
/// <para>Requires a user access token that includes the moderator:read:chatters scope.</para>
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster whose list of chatters you want to get.</param>
/// <param name="moderatorId">
/// The ID of the moderator or the specified broadcaster that’s requesting the list of chatters.
/// <para>This ID must match the user ID associated with the user access token.</para>
/// </param>
/// <param name="first">
/// The maximum number of items to return per page in the response.
/// <para>The minimum page size is 1 item per page and the maximum is 1,000. The default is 100.</para>
/// </param>
/// <param name="after">The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value. </param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetChattersResponse"></returns>
/// <exception cref="BadParameterException"></exception>
public Task<GetChattersResponse> GetChattersAsync(string broadcasterId, string moderatorId, int first = 100, string after = null, string accessToken = null)
{
if (string.IsNullOrWhiteSpace(broadcasterId))
throw new BadParameterException("broadcasterId cannot be null/empty/whitespace");
if (string.IsNullOrWhiteSpace(moderatorId))
throw new BadParameterException("moderatorId cannot be null/empty/whitespace");
if (first < 1 || first > 1000)
throw new BadParameterException("first cannot be less than 1 or greater than 1000");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId),
new KeyValuePair<string, string>("moderator_id", moderatorId),
new KeyValuePair<string, string>("first", first.ToString()),
};
if (!string.IsNullOrWhiteSpace(after))
getParams.Add(new KeyValuePair<string, string>("after", after));
return TwitchGetGenericAsync<GetChattersResponse>("/chat/chatters", ApiVersion.Helix, getParams, accessToken: accessToken);
}
#endregion
#region Emotes
/// <summary>
/// Gets all emotes that the specified Twitch channel created.
/// </summary>
/// <param name="broadcasterId">ID of the broadcaster to get the emotes from.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetChannelEmotesResponse"></returns>
public Task<GetChannelEmotesResponse> GetChannelEmotesAsync(string broadcasterId, string accessToken = null)
{
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId)
};
return TwitchGetGenericAsync<GetChannelEmotesResponse>("/chat/emotes", ApiVersion.Helix, getParams, accessToken);
}
/// <summary>
/// Gets emotes for one or more specified emote sets.
/// <para>An emote set groups emotes that have a similar context.</para>
/// <para>For example, Twitch places all the subscriber emotes that a broadcaster uploads for their channel in the same emote set.</para>
/// </summary>
/// <param name="emoteSetIds">
/// An ID that identifies the emote set
/// <para>You may specify a maximum of 25 IDs.</para>
/// </param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetEmoteSetsResponse"></returns>
public Task<GetEmoteSetsResponse> GetEmoteSetsAsync(List<string> emoteSetIds, string accessToken = null)
{
var getParams = new List<KeyValuePair<string, string>>();
getParams.AddRange(emoteSetIds.Select(emoteSetId => new KeyValuePair<string, string>("emote_set_id", emoteSetId)));
return TwitchGetGenericAsync<GetEmoteSetsResponse>("/chat/emotes/set", ApiVersion.Helix, getParams, accessToken);
}
/// <summary>
/// Gets all global emotes. Global emotes are Twitch-created emoticons that users can use in any Twitch chat.
/// </summary>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetGlobalEmotesResponse"></returns>
public Task<GetGlobalEmotesResponse> GetGlobalEmotesAsync(string accessToken = null)
{
return TwitchGetGenericAsync<GetGlobalEmotesResponse>("/chat/emotes/global", ApiVersion.Helix, accessToken: accessToken);
}
/// <summary>
/// Retrieves emotes available to the user across all channels.
/// </summary>
/// <param name="userId">The ID of the user. This ID must match the user ID in the user access token.</param>
/// <param name="after">The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value.</param>
/// <param name="broadcasterId">The User ID of a broadcaster you wish to get follower emotes of. Using this query parameter will guarantee inclusion of the broadcaster’s follower emotes in the response body.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetUserEmotesResponse"></returns>
public Task<GetUserEmotesResponse> GetUserEmotesAsync(string userId, string after = null,
string broadcasterId = null, string accessToken = null)
{
if (string.IsNullOrEmpty(userId))
throw new BadParameterException("userId must be set");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("user_id", userId)
};
if (!string.IsNullOrEmpty(after))
getParams.Add(new KeyValuePair<string, string>("after", after));
if (!string.IsNullOrEmpty(broadcasterId))
getParams.Add(new KeyValuePair<string, string>("broadcaster_id", broadcasterId));
return TwitchGetGenericAsync<GetUserEmotesResponse>("/chat/emotes/user", ApiVersion.Helix, getParams,
accessToken);
}
#endregion
#region GetChatSettings
/// <summary>
/// Gets the broadcaster’s chat settings.
/// <para>To include the non_moderator_chat_delay or non_moderator_chat_delay_duration settings in the response, you must specify a User access token with scope set to moderator:read:chat_settings.</para>
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster whose chat settings you want to get.</param>
/// <param name="moderatorId">
/// Required only to access the non_moderator_chat_delay or non_moderator_chat_delay_duration settings.
/// <para>The ID of a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID associated with the user OAuth token.</para>
/// <para>If the broadcaster wants to get their own settings (instead of having the moderator do it), set this parameter to the broadcaster’s ID, too.</para>
/// </param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetChatSettingsResponse"></returns>
/// <exception cref="BadParameterException"></exception>
public Task<GetChatSettingsResponse> GetChatSettingsAsync(string broadcasterId, string moderatorId, string accessToken = null)
{
if (string.IsNullOrEmpty(broadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(moderatorId))
throw new BadParameterException("moderatorId must be set");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId),
new KeyValuePair<string, string>("moderator_id", moderatorId)
};
return TwitchGetGenericAsync<GetChatSettingsResponse>("/chat/settings", ApiVersion.Helix, getParams, accessToken);
}
#endregion
#region UpdateChatSettings
/// <summary>
/// Updates the broadcaster’s chat settings.
/// <para>Requires a User access token with scope set to moderator:manage:chat_settings.</para>
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster whose chat settings you want to update.</param>
/// <param name="moderatorId">
/// The ID of a user that has permission to moderate the broadcaster’s chat room.
/// <para>This ID must match the user ID associated with the user OAuth token.</para>
/// <para>If the broadcaster is making the update, also set this parameter to the broadcaster’s ID.</para>
/// </param>
/// <param name="settings" cref="ChatSettings"></param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="UpdateChatSettingsResponse"></returns>
/// <exception cref="BadParameterException"></exception>
public Task<UpdateChatSettingsResponse> UpdateChatSettingsAsync(string broadcasterId, string moderatorId, ChatSettings settings, string accessToken = null)
{
if (string.IsNullOrEmpty(broadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(moderatorId))
throw new BadParameterException("moderatorId must be set");
if (settings == null)
throw new BadParameterException("settings must be set");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId),
new KeyValuePair<string, string>("moderator_id", moderatorId)
};
return TwitchPatchGenericAsync<UpdateChatSettingsResponse>("/chat/settings", ApiVersion.Helix, JsonConvert.SerializeObject(settings), getParams, accessToken);
}
#endregion
#region Announcements
/// <summary>
/// Sends an announcement to the broadcaster’s chat room.
/// Requires a user access token that includes the moderator:manage:announcements scope.
/// The ID in the moderator_id query parameter must match the user ID in the access token.
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster that owns the chat room to send the announcement to.</param>
/// <param name="moderatorId">The ID of a user who has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the OAuth token, which can be a moderator or the broadcaster.</param>
/// <param name="message">The announcement to make in the broadcaster’s chat room.</param>
/// <param name="color">The color used to highlight the announcement. Possible case-sensitive values are: blue/green/orange/purple/primary(default)</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
public Task SendChatAnnouncementAsync(string broadcasterId, string moderatorId, string message, AnnouncementColors color = null, string accessToken = null)
{
if (string.IsNullOrEmpty(broadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(moderatorId))
throw new BadParameterException("moderatorId must be set");
if (message == null)
throw new BadParameterException("message must be set");
if (message.Length > 500)
throw new BadParameterException("message length must be less than or equal to 500 characters");
if (color == null)
color = AnnouncementColors.Primary;
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("broadcaster_id", broadcasterId),
new KeyValuePair<string, string>("moderator_id", moderatorId),
};
// This should be updated to have a Request Class in the future.
var json = new JObject
{
["message"] = message,
["color"] = color.Value
};
return TwitchPostAsync("/chat/announcements", ApiVersion.Helix, json.ToString(), getParams, accessToken);
}
#endregion
#region Shoutouts
/// <summary>
/// Sends a Shoutout to the specified broadcaster.
/// </summary>
/// <param name="fromBroadcasterId">The ID of the broadcaster that’s sending the Shoutout.</param>
/// <param name="toBroadcasterId"> The ID of the broadcaster that’s receiving the Shoutout.</param>
/// <param name="moderatorId">The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.</param>
/// <param name="accessToken"></param>
/// <exception cref="BadParameterException"></exception>
public Task SendShoutoutAsync(string fromBroadcasterId, string toBroadcasterId, string moderatorId, string accessToken = null)
{
if (string.IsNullOrEmpty(fromBroadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(toBroadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(moderatorId))
throw new BadParameterException("moderatorId must be set");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("from_broadcaster_id", fromBroadcasterId),
new KeyValuePair<string, string>("to_broadcaster_id", toBroadcasterId),
new KeyValuePair<string, string>("moderator_id", moderatorId),
};
return TwitchPostAsync("/chat/shoutouts", ApiVersion.Helix, null, getParams, accessToken);
}
/// <summary>
/// Sends a message to a chat
/// </summary>
/// <param name="broadcasterId">The ID of the broadcaster whose chat room the message will be sent to.</param>
/// <param name="senderId"> The ID of the user sending the message. This ID must match the user ID in the user access token.</param>
/// <param name="message"> The message to send. The message is limited to a maximum of 500 characters. Chat messages can also include emoticons. To include emoticons, use the name of the emote. The names are case sensitive. Don’t include colons around the name (e.g., :bleedPurple:). If Twitch recognizes the name, Twitch converts the name to the emote before writing the chat message to the chat room</param>
/// <param name="replyParentMessageId">The ID of the chat message being replied to. If omitted, the message is not a reply</param>
/// <param name="accessToken"></param>
/// <returns></returns>
/// <exception cref="BadParameterException"></exception>
public Task<SendChatMessageResponse> SendChatMessage(string broadcasterId, string senderId, string message, string replyParentMessageId = null, string accessToken = null)
{
if (string.IsNullOrEmpty(broadcasterId))
throw new BadParameterException("broadcasterId must be set");
if (string.IsNullOrEmpty(senderId))
throw new BadParameterException("senderId must be set");
if (string.IsNullOrEmpty(message))
throw new BadParameterException("message must be set");
var json = new JObject
{
["broadcaster_id"] = broadcasterId,
["sender_id"] = senderId,
["message"] = message
};
if (replyParentMessageId != null)
{
json.Add("reply_parent_message_id", replyParentMessageId);
}
return TwitchPostGenericAsync<SendChatMessageResponse>("/chat/messages", ApiVersion.Helix, json.ToString(), null, accessToken);
}
#endregion
#region Update User Chat Color
/// <summary>
/// Updates the color used for the user’s name in chat from a selection of available colors.
/// </summary>
/// <param name="userId">The ID of the user whose chat color you want to update.</param>
/// <param name="color">The color to use for the user’s name in chat from UserColors selection.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
public Task UpdateUserChatColorAsync(string userId, UserColors color, string accessToken = null)
{
if (string.IsNullOrEmpty(userId))
throw new BadParameterException("userId must be set");
if (string.IsNullOrEmpty(color.Value))
throw new BadParameterException("color must be set");
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("user_id", userId),
new KeyValuePair<string, string>("color", color.Value),
};
return TwitchPutAsync("/chat/color", ApiVersion.Helix, null, getParams, accessToken);
}
/// <summary>
/// Updates the color used for the user’s name in chat from a HEX Code.
/// <para>Turbo or Prime Required</para>
/// </summary>
/// <param name="userId">The ID of the user whose chat color you want to update.</param>
/// <param name="colorHex">The color to use for the user’s name in chat in hex format.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
public Task UpdateUserChatColorAsync(string userId, string colorHex, string accessToken = null)
{
if (string.IsNullOrEmpty(userId))
throw new BadParameterException("userId must be set");
if (string.IsNullOrEmpty(colorHex))
throw new BadParameterException("colorHex must be set");
if (colorHex.Length != 6)
throw new BadParameterException("colorHex length must be equal to 6 characters \"######\"");
var colorEncoded = HttpUtility.UrlEncode("#" + colorHex);
var getParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("user_id", userId),
new KeyValuePair<string, string>("color", colorEncoded),
};
return TwitchPutAsync("/chat/color", ApiVersion.Helix, null, getParams, accessToken);
}
#endregion
#region Get User Chat Color
/// <summary>
/// Gets the color used for the user(s)’s name in chat.
/// </summary>
/// <param name="userIds">The ID of the users whose color you want to get.</param>
/// <param name="accessToken">optional access token to override the use of the stored one in the TwitchAPI instance</param>
/// <returns cref="GetUserChatColorResponse"></returns>
public Task<GetUserChatColorResponse> GetUserChatColorAsync(List<string> userIds, string accessToken = null)
{
if (userIds.Count == 0)
throw new BadParameterException("userIds must contain at least 1 userId");
var getParams = new List<KeyValuePair<string, string>>();
foreach (var userId in userIds)
{
if (string.IsNullOrEmpty(userId))
{
throw new BadParameterException("userId must be set");
}
getParams.Add(new KeyValuePair<string, string>("user_id", userId));
}
return TwitchGetGenericAsync<GetUserChatColorResponse>("/chat/color", ApiVersion.Helix, getParams, accessToken);
}
#endregion
}
}