Chatterino
Helix.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "common/Aliases.hpp"
6 #include "util/QStringHash.hpp"
7 
8 #include <QJsonArray>
9 #include <QString>
10 #include <QStringList>
11 #include <QUrl>
12 #include <QUrlQuery>
13 #include <boost/optional.hpp>
14 
15 #include <functional>
16 #include <unordered_set>
17 #include <vector>
18 
19 namespace chatterino {
20 
21 using HelixFailureCallback = std::function<void()>;
22 template <typename... T>
23 using ResultCallback = std::function<void(T...)>;
24 
25 struct HelixUser {
26  QString id;
27  QString login;
28  QString displayName;
29  QString createdAt;
30  QString description;
31  QString profileImageUrl;
32 
33  explicit HelixUser(QJsonObject jsonObject)
34  : id(jsonObject.value("id").toString())
35  , login(jsonObject.value("login").toString())
36  , displayName(jsonObject.value("display_name").toString())
37  , createdAt(jsonObject.value("created_at").toString())
38  , description(jsonObject.value("description").toString())
39  , profileImageUrl(jsonObject.value("profile_image_url").toString())
40  {
41  }
42 };
43 
45  QString fromId;
46  QString fromName;
47  QString toId;
48  QString toName;
49  QString followedAt; // date time object
50 
52  : fromId("")
53  , fromName("")
54  , toId("")
55  , toName("")
56  , followedAt("")
57  {
58  }
59 
60  explicit HelixUsersFollowsRecord(QJsonObject jsonObject)
61  : fromId(jsonObject.value("from_id").toString())
62  , fromName(jsonObject.value("from_name").toString())
63  , toId(jsonObject.value("to_id").toString())
64  , toName(jsonObject.value("to_name").toString())
65  , followedAt(jsonObject.value("followed_at").toString())
66  {
67  }
68 };
69 
71  int total;
72  std::vector<HelixUsersFollowsRecord> data;
73  explicit HelixUsersFollowsResponse(QJsonObject jsonObject)
74  : total(jsonObject.value("total").toInt())
75  {
76  const auto &jsonData = jsonObject.value("data").toArray();
77  std::transform(jsonData.begin(), jsonData.end(),
78  std::back_inserter(this->data),
79  [](const QJsonValue &record) {
80  return HelixUsersFollowsRecord(record.toObject());
81  });
82  }
83 };
84 
85 struct HelixStream {
86  QString id; // stream id
87  QString userId;
88  QString userLogin;
89  QString userName;
90  QString gameId;
91  QString gameName;
92  QString type;
93  QString title;
95  QString startedAt;
96  QString language;
97  QString thumbnailUrl;
98 
100  : id("")
101  , userId("")
102  , userLogin("")
103  , userName("")
104  , gameId("")
105  , gameName("")
106  , type("")
107  , title("")
108  , viewerCount()
109  , startedAt("")
110  , language("")
111  , thumbnailUrl("")
112  {
113  }
114 
115  explicit HelixStream(QJsonObject jsonObject)
116  : id(jsonObject.value("id").toString())
117  , userId(jsonObject.value("user_id").toString())
118  , userLogin(jsonObject.value("user_login").toString())
119  , userName(jsonObject.value("user_name").toString())
120  , gameId(jsonObject.value("game_id").toString())
121  , gameName(jsonObject.value("game_name").toString())
122  , type(jsonObject.value("type").toString())
123  , title(jsonObject.value("title").toString())
124  , viewerCount(jsonObject.value("viewer_count").toInt())
125  , startedAt(jsonObject.value("started_at").toString())
126  , language(jsonObject.value("language").toString())
127  , thumbnailUrl(jsonObject.value("thumbnail_url").toString())
128  {
129  }
130 };
131 
132 struct HelixGame {
133  QString id; // stream id
134  QString name;
135  QString boxArtUrl;
136 
137  explicit HelixGame(QJsonObject jsonObject)
138  : id(jsonObject.value("id").toString())
139  , name(jsonObject.value("name").toString())
140  , boxArtUrl(jsonObject.value("box_art_url").toString())
141  {
142  }
143 };
144 
145 struct HelixClip {
146  QString id; // clip slug
147  QString editUrl;
148 
149  explicit HelixClip(QJsonObject jsonObject)
150  : id(jsonObject.value("id").toString())
151  , editUrl(jsonObject.value("edit_url").toString())
152  {
153  }
154 };
155 
156 struct HelixChannel {
157  QString userId;
158  QString name;
159  QString language;
160  QString gameId;
161  QString gameName;
162  QString title;
163 
164  explicit HelixChannel(QJsonObject jsonObject)
165  : userId(jsonObject.value("broadcaster_id").toString())
166  , name(jsonObject.value("broadcaster_name").toString())
167  , language(jsonObject.value("broadcaster_language").toString())
168  , gameId(jsonObject.value("game_id").toString())
169  , gameName(jsonObject.value("game_name").toString())
170  , title(jsonObject.value("title").toString())
171  {
172  }
173 };
174 
176  QString createdAt;
177  QString description;
178  QString id;
180 
181  explicit HelixStreamMarker(QJsonObject jsonObject)
182  : createdAt(jsonObject.value("created_at").toString())
183  , description(jsonObject.value("description").toString())
184  , id(jsonObject.value("id").toString())
185  , positionSeconds(jsonObject.value("position_seconds").toInt())
186  {
187  }
188 };
189 
190 struct HelixBlock {
191  QString userId;
192  QString userName;
193  QString displayName;
194 
195  explicit HelixBlock(QJsonObject jsonObject)
196  : userId(jsonObject.value("user_id").toString())
197  , userName(jsonObject.value("user_login").toString())
198  , displayName(jsonObject.value("display_name").toString())
199  {
200  }
201 };
202 
207 
208  explicit HelixCheermoteImage(QJsonObject jsonObject)
209  : imageURL1x(Url{jsonObject.value("1").toString()})
210  , imageURL2x(Url{jsonObject.value("2").toString()})
211  , imageURL4x(Url{jsonObject.value("4").toString()})
212  {
213  }
214 };
215 
217  QString id;
218  QString color;
219  int minBits;
224 
225  explicit HelixCheermoteTier(QJsonObject jsonObject)
226  : id(jsonObject.value("id").toString())
227  , color(jsonObject.value("color").toString())
228  , minBits(jsonObject.value("min_bits").toInt())
229  , darkAnimated(jsonObject.value("images")
230  .toObject()
231  .value("dark")
232  .toObject()
233  .value("animated")
234  .toObject())
235  , darkStatic(jsonObject.value("images")
236  .toObject()
237  .value("dark")
238  .toObject()
239  .value("static")
240  .toObject())
241  , lightAnimated(jsonObject.value("images")
242  .toObject()
243  .value("light")
244  .toObject()
245  .value("animated")
246  .toObject())
247  , lightStatic(jsonObject.value("images")
248  .toObject()
249  .value("light")
250  .toObject()
251  .value("static")
252  .toObject())
253  {
254  }
255 };
256 
258  QString prefix;
259  QString type;
260  std::vector<HelixCheermoteTier> tiers;
261 
262  explicit HelixCheermoteSet(QJsonObject jsonObject)
263  : prefix(jsonObject.value("prefix").toString())
264  , type(jsonObject.value("type").toString())
265  {
266  for (const auto &tier : jsonObject.value("tiers").toArray())
267  {
268  this->tiers.emplace_back(tier.toObject());
269  }
270  }
271 };
272 
274  QString setId;
275  QString ownerId;
276  QString emoteType;
277 
278  explicit HelixEmoteSetData(QJsonObject jsonObject)
279  : setId(jsonObject.value("emote_set_id").toString())
280  , ownerId(jsonObject.value("owner_id").toString())
281  , emoteType(jsonObject.value("emote_type").toString())
282  {
283  }
284 };
285 
287  const QString emoteId;
288  const QString name;
289  const QString type;
290  const QString setId;
291  const QString url;
292 
293  explicit HelixChannelEmote(QJsonObject jsonObject)
294  : emoteId(jsonObject.value("id").toString())
295  , name(jsonObject.value("name").toString())
296  , type(jsonObject.value("emote_type").toString())
297  , setId(jsonObject.value("emote_set_id").toString())
298  , url(QString(TWITCH_EMOTE_TEMPLATE)
299  .replace("{id}", this->emoteId)
300  .replace("{scale}", "3.0"))
301  {
302  }
303 };
304 
306  const QString broadcasterId;
307  const bool emoteMode;
308  // boost::none if disabled
309  const boost::optional<int> followerModeDuration; // time in minutes
310  const boost::optional<int>
311  nonModeratorChatDelayDuration; // time in seconds
312  const boost::optional<int> slowModeWaitTime; // time in seconds
313  const bool subscriberMode;
314  const bool uniqueChatMode;
315 
316  explicit HelixChatSettings(QJsonObject jsonObject)
317  : broadcasterId(jsonObject.value("broadcaster_id").toString())
318  , emoteMode(jsonObject.value("emote_mode").toBool())
319  , followerModeDuration(boost::make_optional(
320  jsonObject.value("follower_mode").toBool(),
321  jsonObject.value("follower_mode_duration").toInt()))
322  , nonModeratorChatDelayDuration(boost::make_optional(
323  jsonObject.value("non_moderator_chat_delay").toBool(),
324  jsonObject.value("non_moderator_chat_delay_duration").toInt()))
325  , slowModeWaitTime(boost::make_optional(
326  jsonObject.value("slow_mode").toBool(),
327  jsonObject.value("slow_mode_wait_time").toInt()))
328  , subscriberMode(jsonObject.value("subscriber_mode").toBool())
329  , uniqueChatMode(jsonObject.value("unique_chat_mode").toBool())
330  {
331  }
332 };
333 
334 struct HelixVip {
335  // Twitch ID of the user
336  QString userId;
337 
338  // Display name of the user
339  QString userName;
340 
341  // Login name of the user
342  QString userLogin;
343 
344  explicit HelixVip(const QJsonObject &jsonObject)
345  : userId(jsonObject.value("user_id").toString())
346  , userName(jsonObject.value("user_name").toString())
347  , userLogin(jsonObject.value("user_login").toString())
348  {
349  }
350 };
351 
353  std::unordered_set<QString> chatters;
354  int total;
355  QString cursor;
356 
357  HelixChatters() = default;
358 
359  explicit HelixChatters(const QJsonObject &jsonObject)
360  : total(jsonObject.value("total").toInt())
361  , cursor(jsonObject.value("pagination")
362  .toObject()
363  .value("cursor")
364  .toString())
365  {
366  const auto &data = jsonObject.value("data").toArray();
367  for (const auto &chatter : data)
368  {
369  auto userLogin = chatter.toObject().value("user_login").toString();
370  this->chatters.insert(userLogin);
371  }
372  }
373 };
374 
376 
378  std::vector<HelixModerator> moderators;
379  QString cursor;
380 
381  HelixModerators() = default;
382 
383  explicit HelixModerators(const QJsonObject &jsonObject)
384  : cursor(jsonObject.value("pagination")
385  .toObject()
386  .value("cursor")
387  .toString())
388  {
389  const auto &data = jsonObject.value("data").toArray();
390  for (const auto &mod : data)
391  {
392  HelixModerator moderator(mod.toObject());
393 
394  this->moderators.push_back(moderator);
395  }
396  }
397 };
398 
400  Blue,
401  Green,
402  Orange,
403  Purple,
404 
405  // this is the executor's chat color
406  Primary,
407 };
408 
409 enum class HelixClipError {
410  Unknown,
413 };
414 
416  Unknown,
419 };
420 
422  Unknown,
427 };
428 
430  Unknown,
432  InvalidColor,
433 
434  // The error message is forwarded directly from the Twitch API
435  Forwarded,
436 };
437 
439  Unknown,
444 
445  // The error message is forwarded directly from the Twitch API
446  Forwarded,
447 };
448 
450  Unknown,
452 
453  // The error message is forwarded directly from the Twitch API
454  Forwarded,
455 };
456 
458  Unknown,
461  Ratelimited,
463  TargetIsVIP,
464 
465  // The error message is forwarded directly from the Twitch API
466  Forwarded,
467 };
468 
470  Unknown,
474  Ratelimited,
475 
476  // The error message is forwarded directly from the Twitch API
477  Forwarded,
478 };
479 
481  Unknown,
484  Ratelimited,
485 
486  // The error message is forwarded directly from the Twitch API
487  Forwarded,
488 };
489 
491  Unknown,
494  Ratelimited,
495 
496  // The error message is forwarded directly from the Twitch API
497  Forwarded,
498 };
499 
500 // These changes are from the helix-command-migration/unban-untimeout branch
502  Unknown,
505  Ratelimited,
508 
509  // The error message is forwarded directly from the Twitch API
510  Forwarded,
511 }; // These changes are from the helix-command-migration/unban-untimeout branch
512 
513 enum class HelixStartRaidError { // /raid
514  Unknown,
518  Ratelimited,
519 
520  // The error message is forwarded directly from the Twitch API
521  Forwarded,
522 }; // /raid
523 
524 enum class HelixCancelRaidError { // /unraid
525  Unknown,
529  Ratelimited,
530 
531  // The error message is forwarded directly from the Twitch API
532  Forwarded,
533 }; // /unraid
534 
535 enum class HelixUpdateChatSettingsError { // update chat settings
536  Unknown,
539  Ratelimited,
540  Forbidden,
541  OutOfRange,
542 
543  // The error message is forwarded directly from the Twitch API
544  Forwarded,
545 }; // update chat settings
546 
547 enum class HelixBanUserError { // /timeout, /ban
548  Unknown,
551  Ratelimited,
553  TargetBanned,
555 
556  // The error message is forwarded directly from the Twitch API
557  Forwarded,
558 }; // /timeout, /ban
559 
560 enum class HelixWhisperError { // /w
561  Unknown,
564  Ratelimited,
567  WhisperSelf,
568 
569  // The error message is forwarded directly from the Twitch API
570  Forwarded,
571 }; // /w
572 
574  Unknown,
577 
578  // The error message is forwarded directly from the Twitch API
579  Forwarded,
580 };
581 
583  Unknown,
586 
587  // The error message is forwarded directly from the Twitch API
588  Forwarded,
589 };
590 
591 enum class HelixListVIPsError { // /vips
592  Unknown,
596  Ratelimited,
597 
598  // The error message is forwarded directly from the Twitch API
599  Forwarded,
600 }; // /vips
601 
603  // Length of the triggered commercial
604  int length;
605  // Provides contextual information on why the request failed
606  QString message;
607  // Seconds until the next commercial can be served on this channel
609 
610  explicit HelixStartCommercialResponse(const QJsonObject &jsonObject)
611  {
612  auto jsonData = jsonObject.value("data").toArray().at(0).toObject();
613  this->length = jsonData.value("length").toInt();
614  this->message = jsonData.value("message").toString();
615  this->retryAfter = jsonData.value("retry_after").toInt();
616  }
617 };
618 
620  Unknown,
625  Ratelimited,
626 
627  // The error message is forwarded directly from the Twitch API
628  Forwarded,
629 };
630 
631 class IHelix
632 {
633 public:
634  template <typename... T>
635  using FailureCallback = std::function<void(T...)>;
636 
637  // https://dev.twitch.tv/docs/api/reference#get-users
638  virtual void fetchUsers(
639  QStringList userIds, QStringList userLogins,
640  ResultCallback<std::vector<HelixUser>> successCallback,
641  HelixFailureCallback failureCallback) = 0;
642  virtual void getUserByName(QString userName,
643  ResultCallback<HelixUser> successCallback,
644  HelixFailureCallback failureCallback) = 0;
645  virtual void getUserById(QString userId,
646  ResultCallback<HelixUser> successCallback,
647  HelixFailureCallback failureCallback) = 0;
648 
649  // https://dev.twitch.tv/docs/api/reference#get-users-follows
650  virtual void fetchUsersFollows(
651  QString fromId, QString toId,
653  HelixFailureCallback failureCallback) = 0;
654 
655  virtual void getUserFollowers(
656  QString userId,
658  HelixFailureCallback failureCallback) = 0;
659 
660  // https://dev.twitch.tv/docs/api/reference#get-streams
661  virtual void fetchStreams(
662  QStringList userIds, QStringList userLogins,
663  ResultCallback<std::vector<HelixStream>> successCallback,
664  HelixFailureCallback failureCallback,
665  std::function<void()> finallyCallback) = 0;
666 
667  virtual void getStreamById(
668  QString userId, ResultCallback<bool, HelixStream> successCallback,
669  HelixFailureCallback failureCallback,
670  std::function<void()> finallyCallback) = 0;
671 
672  virtual void getStreamByName(
673  QString userName, ResultCallback<bool, HelixStream> successCallback,
674  HelixFailureCallback failureCallback,
675  std::function<void()> finallyCallback) = 0;
676 
677  // https://dev.twitch.tv/docs/api/reference#get-games
678  virtual void fetchGames(
679  QStringList gameIds, QStringList gameNames,
680  ResultCallback<std::vector<HelixGame>> successCallback,
681  HelixFailureCallback failureCallback) = 0;
682 
683  // https://dev.twitch.tv/docs/api/reference#search-categories
684  virtual void searchGames(
685  QString gameName,
686  ResultCallback<std::vector<HelixGame>> successCallback,
687  HelixFailureCallback failureCallback) = 0;
688 
689  virtual void getGameById(QString gameId,
690  ResultCallback<HelixGame> successCallback,
691  HelixFailureCallback failureCallback) = 0;
692 
693  // https://dev.twitch.tv/docs/api/reference#create-clip
694  virtual void createClip(QString channelId,
695  ResultCallback<HelixClip> successCallback,
696  std::function<void(HelixClipError)> failureCallback,
697  std::function<void()> finallyCallback) = 0;
698 
699  // https://dev.twitch.tv/docs/api/reference#get-channel-information
700  virtual void getChannel(QString broadcasterId,
701  ResultCallback<HelixChannel> successCallback,
702  HelixFailureCallback failureCallback) = 0;
703 
704  // https://dev.twitch.tv/docs/api/reference/#create-stream-marker
705  virtual void createStreamMarker(
706  QString broadcasterId, QString description,
707  ResultCallback<HelixStreamMarker> successCallback,
708  std::function<void(HelixStreamMarkerError)> failureCallback) = 0;
709 
710  // https://dev.twitch.tv/docs/api/reference#get-user-block-list
711  virtual void loadBlocks(
712  QString userId, ResultCallback<std::vector<HelixBlock>> successCallback,
713  HelixFailureCallback failureCallback) = 0;
714 
715  // https://dev.twitch.tv/docs/api/reference#block-user
716  virtual void blockUser(QString targetUserId,
717  std::function<void()> successCallback,
718  HelixFailureCallback failureCallback) = 0;
719 
720  // https://dev.twitch.tv/docs/api/reference#unblock-user
721  virtual void unblockUser(QString targetUserId,
722  std::function<void()> successCallback,
723  HelixFailureCallback failureCallback) = 0;
724 
725  // https://dev.twitch.tv/docs/api/reference#modify-channel-information
726  virtual void updateChannel(
727  QString broadcasterId, QString gameId, QString language, QString title,
728  std::function<void(NetworkResult)> successCallback,
729  HelixFailureCallback failureCallback) = 0;
730 
731  // https://dev.twitch.tv/docs/api/reference#manage-held-automod-messages
732  virtual void manageAutoModMessages(
733  QString userID, QString msgID, QString action,
734  std::function<void()> successCallback,
735  std::function<void(HelixAutoModMessageError)> failureCallback) = 0;
736 
737  // https://dev.twitch.tv/docs/api/reference/#get-cheermotes
738  virtual void getCheermotes(
739  QString broadcasterId,
740  ResultCallback<std::vector<HelixCheermoteSet>> successCallback,
741  HelixFailureCallback failureCallback) = 0;
742 
743  // https://dev.twitch.tv/docs/api/reference#get-emote-sets
744  virtual void getEmoteSetData(
745  QString emoteSetId, ResultCallback<HelixEmoteSetData> successCallback,
746  HelixFailureCallback failureCallback) = 0;
747 
748  // https://dev.twitch.tv/docs/api/reference#get-channel-emotes
749  virtual void getChannelEmotes(
750  QString broadcasterId,
751  ResultCallback<std::vector<HelixChannelEmote>> successCallback,
752  HelixFailureCallback failureCallback) = 0;
753 
754  // https://dev.twitch.tv/docs/api/reference#update-user-chat-color
755  virtual void updateUserChatColor(
756  QString userID, QString color, ResultCallback<> successCallback,
758  failureCallback) = 0;
759 
760  // https://dev.twitch.tv/docs/api/reference#delete-chat-messages
761  virtual void deleteChatMessages(
762  QString broadcasterID, QString moderatorID, QString messageID,
763  ResultCallback<> successCallback,
765  failureCallback) = 0;
766 
767  // https://dev.twitch.tv/docs/api/reference#add-channel-moderator
768  virtual void addChannelModerator(
769  QString broadcasterID, QString userID, ResultCallback<> successCallback,
771  failureCallback) = 0;
772 
773  // https://dev.twitch.tv/docs/api/reference#remove-channel-moderator
774  virtual void removeChannelModerator(
775  QString broadcasterID, QString userID, ResultCallback<> successCallback,
777  failureCallback) = 0;
778 
779  // https://dev.twitch.tv/docs/api/reference#send-chat-announcement
780  virtual void sendChatAnnouncement(
781  QString broadcasterID, QString moderatorID, QString message,
782  HelixAnnouncementColor color, ResultCallback<> successCallback,
784  failureCallback) = 0;
785 
786  // https://dev.twitch.tv/docs/api/reference#add-channel-vip
787  virtual void addChannelVIP(
788  QString broadcasterID, QString userID, ResultCallback<> successCallback,
790 
791  // https://dev.twitch.tv/docs/api/reference#remove-channel-vip
792  virtual void removeChannelVIP(
793  QString broadcasterID, QString userID, ResultCallback<> successCallback,
795  failureCallback) = 0;
796 
797  // These changes are from the helix-command-migration/unban-untimeout branch
798  // https://dev.twitch.tv/docs/api/reference#unban-user
799  // These changes are from the helix-command-migration/unban-untimeout branch
800  virtual void unbanUser(
801  QString broadcasterID, QString moderatorID, QString userID,
802  ResultCallback<> successCallback,
804  // These changes are from the helix-command-migration/unban-untimeout branch
805 
806  // https://dev.twitch.tv/docs/api/reference#start-a-raid
807  virtual void startRaid(
808  QString fromBroadcasterID, QString toBroadcasterID,
809  ResultCallback<> successCallback,
811  // https://dev.twitch.tv/docs/api/reference#start-a-raid
812 
813  // https://dev.twitch.tv/docs/api/reference#cancel-a-raid
814  virtual void cancelRaid(
815  QString broadcasterID, ResultCallback<> successCallback,
817  // https://dev.twitch.tv/docs/api/reference#cancel-a-raid
818 
819  // Updates the emote mode using
820  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
821  virtual void updateEmoteMode(
822  QString broadcasterID, QString moderatorID, bool emoteMode,
823  ResultCallback<HelixChatSettings> successCallback,
825  failureCallback) = 0;
826 
827  // Updates the follower mode using
828  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
829  virtual void updateFollowerMode(
830  QString broadcasterID, QString moderatorID,
831  boost::optional<int> followerModeDuration,
832  ResultCallback<HelixChatSettings> successCallback,
834  failureCallback) = 0;
835 
836  // Updates the non-moderator chat delay using
837  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
838  virtual void updateNonModeratorChatDelay(
839  QString broadcasterID, QString moderatorID,
840  boost::optional<int> nonModeratorChatDelayDuration,
841  ResultCallback<HelixChatSettings> successCallback,
843  failureCallback) = 0;
844 
845  // Updates the slow mode using
846  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
847  virtual void updateSlowMode(
848  QString broadcasterID, QString moderatorID,
849  boost::optional<int> slowModeWaitTime,
850  ResultCallback<HelixChatSettings> successCallback,
852  failureCallback) = 0;
853 
854  // Updates the subscriber mode using
855  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
856  virtual void updateSubscriberMode(
857  QString broadcasterID, QString moderatorID, bool subscriberMode,
858  ResultCallback<HelixChatSettings> successCallback,
860  failureCallback) = 0;
861 
862  // Updates the unique chat mode using
863  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
864  virtual void updateUniqueChatMode(
865  QString broadcasterID, QString moderatorID, bool uniqueChatMode,
866  ResultCallback<HelixChatSettings> successCallback,
868  failureCallback) = 0;
869 
870  // Ban/timeout a user
871  // https://dev.twitch.tv/docs/api/reference#ban-user
872  virtual void banUser(
873  QString broadcasterID, QString moderatorID, QString userID,
874  boost::optional<int> duration, QString reason,
875  ResultCallback<> successCallback,
876  FailureCallback<HelixBanUserError, QString> failureCallback) = 0;
877 
878  // Send a whisper
879  // https://dev.twitch.tv/docs/api/reference#send-whisper
880  virtual void sendWhisper(
881  QString fromUserID, QString toUserID, QString message,
882  ResultCallback<> successCallback,
883  FailureCallback<HelixWhisperError, QString> failureCallback) = 0;
884 
885  // Get Chatters from the `broadcasterID` channel
886  // This will follow the returned cursor and return up to `maxChattersToFetch` chatters
887  // https://dev.twitch.tv/docs/api/reference#get-chatters
888  virtual void getChatters(
889  QString broadcasterID, QString moderatorID, int maxChattersToFetch,
890  ResultCallback<HelixChatters> successCallback,
892 
893  // Get moderators from the `broadcasterID` channel
894  // This will follow the returned cursor
895  // https://dev.twitch.tv/docs/api/reference#get-moderators
896  virtual void getModerators(
897  QString broadcasterID, int maxModeratorsToFetch,
898  ResultCallback<std::vector<HelixModerator>> successCallback,
900 
901  // https://dev.twitch.tv/docs/api/reference#get-vips
902  virtual void getChannelVIPs(
903  QString broadcasterID,
904  ResultCallback<std::vector<HelixVip>> successCallback,
906 
907  // https://dev.twitch.tv/docs/api/reference#start-commercial
908  virtual void startCommercial(
909  QString broadcasterID, int length,
912  failureCallback) = 0;
913 
914  virtual void update(QString clientId, QString oauthToken) = 0;
915 
916 protected:
917  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
918  virtual void updateChatSettings(
919  QString broadcasterID, QString moderatorID, QJsonObject json,
920  ResultCallback<HelixChatSettings> successCallback,
922  failureCallback) = 0;
923 };
924 
925 class Helix final : public IHelix
926 {
927 public:
928  // https://dev.twitch.tv/docs/api/reference#get-users
929  void fetchUsers(QStringList userIds, QStringList userLogins,
930  ResultCallback<std::vector<HelixUser>> successCallback,
931  HelixFailureCallback failureCallback) final;
932  void getUserByName(QString userName,
933  ResultCallback<HelixUser> successCallback,
934  HelixFailureCallback failureCallback) final;
935  void getUserById(QString userId, ResultCallback<HelixUser> successCallback,
936  HelixFailureCallback failureCallback) final;
937 
938  // https://dev.twitch.tv/docs/api/reference#get-users-follows
939  void fetchUsersFollows(
940  QString fromId, QString toId,
942  HelixFailureCallback failureCallback) final;
943 
944  void getUserFollowers(
945  QString userId,
947  HelixFailureCallback failureCallback) final;
948 
949  // https://dev.twitch.tv/docs/api/reference#get-streams
950  void fetchStreams(QStringList userIds, QStringList userLogins,
951  ResultCallback<std::vector<HelixStream>> successCallback,
952  HelixFailureCallback failureCallback,
953  std::function<void()> finallyCallback) final;
954 
955  void getStreamById(QString userId,
956  ResultCallback<bool, HelixStream> successCallback,
957  HelixFailureCallback failureCallback,
958  std::function<void()> finallyCallback) final;
959 
960  void getStreamByName(QString userName,
961  ResultCallback<bool, HelixStream> successCallback,
962  HelixFailureCallback failureCallback,
963  std::function<void()> finallyCallback) final;
964 
965  // https://dev.twitch.tv/docs/api/reference#get-games
966  void fetchGames(QStringList gameIds, QStringList gameNames,
967  ResultCallback<std::vector<HelixGame>> successCallback,
968  HelixFailureCallback failureCallback) final;
969 
970  // https://dev.twitch.tv/docs/api/reference#search-categories
971  void searchGames(QString gameName,
972  ResultCallback<std::vector<HelixGame>> successCallback,
973  HelixFailureCallback failureCallback) final;
974 
975  void getGameById(QString gameId, ResultCallback<HelixGame> successCallback,
976  HelixFailureCallback failureCallback) final;
977 
978  // https://dev.twitch.tv/docs/api/reference#create-clip
979  void createClip(QString channelId,
980  ResultCallback<HelixClip> successCallback,
981  std::function<void(HelixClipError)> failureCallback,
982  std::function<void()> finallyCallback) final;
983 
984  // https://dev.twitch.tv/docs/api/reference#get-channel-information
985  void getChannel(QString broadcasterId,
986  ResultCallback<HelixChannel> successCallback,
987  HelixFailureCallback failureCallback) final;
988 
989  // https://dev.twitch.tv/docs/api/reference/#create-stream-marker
990  void createStreamMarker(
991  QString broadcasterId, QString description,
992  ResultCallback<HelixStreamMarker> successCallback,
993  std::function<void(HelixStreamMarkerError)> failureCallback) final;
994 
995  // https://dev.twitch.tv/docs/api/reference#get-user-block-list
996  void loadBlocks(QString userId,
997  ResultCallback<std::vector<HelixBlock>> successCallback,
998  HelixFailureCallback failureCallback) final;
999 
1000  // https://dev.twitch.tv/docs/api/reference#block-user
1001  void blockUser(QString targetUserId, std::function<void()> successCallback,
1002  HelixFailureCallback failureCallback) final;
1003 
1004  // https://dev.twitch.tv/docs/api/reference#unblock-user
1005  void unblockUser(QString targetUserId,
1006  std::function<void()> successCallback,
1007  HelixFailureCallback failureCallback) final;
1008 
1009  // https://dev.twitch.tv/docs/api/reference#modify-channel-information
1010  void updateChannel(QString broadcasterId, QString gameId, QString language,
1011  QString title,
1012  std::function<void(NetworkResult)> successCallback,
1013  HelixFailureCallback failureCallback) final;
1014 
1015  // https://dev.twitch.tv/docs/api/reference#manage-held-automod-messages
1016  void manageAutoModMessages(
1017  QString userID, QString msgID, QString action,
1018  std::function<void()> successCallback,
1019  std::function<void(HelixAutoModMessageError)> failureCallback) final;
1020 
1021  // https://dev.twitch.tv/docs/api/reference/#get-cheermotes
1022  void getCheermotes(
1023  QString broadcasterId,
1024  ResultCallback<std::vector<HelixCheermoteSet>> successCallback,
1025  HelixFailureCallback failureCallback) final;
1026 
1027  // https://dev.twitch.tv/docs/api/reference#get-emote-sets
1028  void getEmoteSetData(QString emoteSetId,
1029  ResultCallback<HelixEmoteSetData> successCallback,
1030  HelixFailureCallback failureCallback) final;
1031 
1032  // https://dev.twitch.tv/docs/api/reference#get-channel-emotes
1033  void getChannelEmotes(
1034  QString broadcasterId,
1035  ResultCallback<std::vector<HelixChannelEmote>> successCallback,
1036  HelixFailureCallback failureCallback) final;
1037 
1038  // https://dev.twitch.tv/docs/api/reference#update-user-chat-color
1039  void updateUserChatColor(
1040  QString userID, QString color, ResultCallback<> successCallback,
1042  final;
1043 
1044  // https://dev.twitch.tv/docs/api/reference#delete-chat-messages
1045  void deleteChatMessages(
1046  QString broadcasterID, QString moderatorID, QString messageID,
1047  ResultCallback<> successCallback,
1049  final;
1050 
1051  // https://dev.twitch.tv/docs/api/reference#add-channel-moderator
1052  void addChannelModerator(
1053  QString broadcasterID, QString userID, ResultCallback<> successCallback,
1055  final;
1056 
1057  // https://dev.twitch.tv/docs/api/reference#remove-channel-moderator
1058  void removeChannelModerator(
1059  QString broadcasterID, QString userID, ResultCallback<> successCallback,
1061  failureCallback) final;
1062 
1063  // https://dev.twitch.tv/docs/api/reference#send-chat-announcement
1064  void sendChatAnnouncement(
1065  QString broadcasterID, QString moderatorID, QString message,
1066  HelixAnnouncementColor color, ResultCallback<> successCallback,
1068  failureCallback) final;
1069 
1070  // https://dev.twitch.tv/docs/api/reference#add-channel-vip
1071  void addChannelVIP(QString broadcasterID, QString userID,
1072  ResultCallback<> successCallback,
1074  failureCallback) final;
1075 
1076  // https://dev.twitch.tv/docs/api/reference#remove-channel-vip
1077  void removeChannelVIP(QString broadcasterID, QString userID,
1078  ResultCallback<> successCallback,
1080  failureCallback) final;
1081 
1082  // These changes are from the helix-command-migration/unban-untimeout branch
1083  // https://dev.twitch.tv/docs/api/reference#unban-user
1084  // These changes are from the helix-command-migration/unban-untimeout branch
1085  void unbanUser(
1086  QString broadcasterID, QString moderatorID, QString userID,
1087  ResultCallback<> successCallback,
1088  FailureCallback<HelixUnbanUserError, QString> failureCallback) final;
1089  // These changes are from the helix-command-migration/unban-untimeout branch
1090 
1091  // https://dev.twitch.tv/docs/api/reference#start-a-raid
1092  void startRaid(
1093  QString fromBroadcasterID, QString toBroadcasterID,
1094  ResultCallback<> successCallback,
1095  FailureCallback<HelixStartRaidError, QString> failureCallback) final;
1096  // https://dev.twitch.tv/docs/api/reference#start-a-raid
1097 
1098  // https://dev.twitch.tv/docs/api/reference#cancel-a-raid
1099  void cancelRaid(
1100  QString broadcasterID, ResultCallback<> successCallback,
1101  FailureCallback<HelixCancelRaidError, QString> failureCallback) final;
1102  // https://dev.twitch.tv/docs/api/reference#cancel-a-raid
1103 
1104  // Updates the emote mode using
1105  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1106  void updateEmoteMode(QString broadcasterID, QString moderatorID,
1107  bool emoteMode,
1108  ResultCallback<HelixChatSettings> successCallback,
1110  failureCallback) final;
1111 
1112  // Updates the follower mode using
1113  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1114  void updateFollowerMode(
1115  QString broadcasterID, QString moderatorID,
1116  boost::optional<int> followerModeDuration,
1117  ResultCallback<HelixChatSettings> successCallback,
1119  final;
1120 
1121  // Updates the non-moderator chat delay using
1122  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1123  void updateNonModeratorChatDelay(
1124  QString broadcasterID, QString moderatorID,
1125  boost::optional<int> nonModeratorChatDelayDuration,
1126  ResultCallback<HelixChatSettings> successCallback,
1128  final;
1129 
1130  // Updates the slow mode using
1131  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1132  void updateSlowMode(QString broadcasterID, QString moderatorID,
1133  boost::optional<int> slowModeWaitTime,
1134  ResultCallback<HelixChatSettings> successCallback,
1136  failureCallback) final;
1137 
1138  // Updates the subscriber mode using
1139  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1140  void updateSubscriberMode(
1141  QString broadcasterID, QString moderatorID, bool subscriberMode,
1142  ResultCallback<HelixChatSettings> successCallback,
1144  final;
1145 
1146  // Updates the unique chat mode using
1147  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1148  void updateUniqueChatMode(
1149  QString broadcasterID, QString moderatorID, bool uniqueChatMode,
1150  ResultCallback<HelixChatSettings> successCallback,
1152  final;
1153 
1154  // Ban/timeout a user
1155  // https://dev.twitch.tv/docs/api/reference#ban-user
1156  void banUser(
1157  QString broadcasterID, QString moderatorID, QString userID,
1158  boost::optional<int> duration, QString reason,
1159  ResultCallback<> successCallback,
1160  FailureCallback<HelixBanUserError, QString> failureCallback) final;
1161 
1162  // Send a whisper
1163  // https://dev.twitch.tv/docs/api/reference#send-whisper
1164  void sendWhisper(
1165  QString fromUserID, QString toUserID, QString message,
1166  ResultCallback<> successCallback,
1167  FailureCallback<HelixWhisperError, QString> failureCallback) final;
1168 
1169  // Get Chatters from the `broadcasterID` channel
1170  // This will follow the returned cursor and return up to `maxChattersToFetch` chatters
1171  // https://dev.twitch.tv/docs/api/reference#get-chatters
1172  void getChatters(
1173  QString broadcasterID, QString moderatorID, int maxChattersToFetch,
1174  ResultCallback<HelixChatters> successCallback,
1175  FailureCallback<HelixGetChattersError, QString> failureCallback) final;
1176 
1177  // Get moderators from the `broadcasterID` channel
1178  // This will follow the returned cursor
1179  // https://dev.twitch.tv/docs/api/reference#get-moderators
1180  void getModerators(
1181  QString broadcasterID, int maxModeratorsToFetch,
1182  ResultCallback<std::vector<HelixModerator>> successCallback,
1184  final;
1185 
1186  // https://dev.twitch.tv/docs/api/reference#get-vips
1187  void getChannelVIPs(
1188  QString broadcasterID,
1189  ResultCallback<std::vector<HelixVip>> successCallback,
1190  FailureCallback<HelixListVIPsError, QString> failureCallback) final;
1191 
1192  // https://dev.twitch.tv/docs/api/reference#start-commercial
1193  void startCommercial(
1194  QString broadcasterID, int length,
1197  final;
1198 
1199  void update(QString clientId, QString oauthToken) final;
1200 
1201  static void initialize();
1202 
1203 protected:
1204  // https://dev.twitch.tv/docs/api/reference#update-chat-settings
1205  void updateChatSettings(
1206  QString broadcasterID, QString moderatorID, QJsonObject json,
1207  ResultCallback<HelixChatSettings> successCallback,
1209  final;
1210 
1211  // Recursive boy
1212  void onFetchChattersSuccess(
1213  std::shared_ptr<HelixChatters> finalChatters, QString broadcasterID,
1214  QString moderatorID, int maxChattersToFetch,
1215  ResultCallback<HelixChatters> successCallback,
1217  HelixChatters chatters);
1218 
1219  // Get chatters list - This method is what actually runs the API request
1220  // https://dev.twitch.tv/docs/api/reference#get-chatters
1221  void fetchChatters(
1222  QString broadcasterID, QString moderatorID, int first, QString after,
1223  ResultCallback<HelixChatters> successCallback,
1225 
1226  // Recursive boy
1227  void onFetchModeratorsSuccess(
1228  std::shared_ptr<std::vector<HelixModerator>> finalModerators,
1229  QString broadcasterID, int maxModeratorsToFetch,
1230  ResultCallback<std::vector<HelixModerator>> successCallback,
1232  HelixModerators moderators);
1233 
1234  // Get moderator list - This method is what actually runs the API request
1235  // https://dev.twitch.tv/docs/api/reference#get-moderators
1236  void fetchModerators(
1237  QString broadcasterID, int first, QString after,
1238  ResultCallback<HelixModerators> successCallback,
1240 
1241 private:
1242  NetworkRequest makeRequest(QString url, QUrlQuery urlQuery);
1243 
1244  QString clientId;
1245  QString oauthToken;
1246 };
1247 
1248 // initializeHelix sets the helix instance to _instance
1249 // from a normal application, this should never be called, and will instead be handled by calling Helix::initialize()
1250 void initializeHelix(IHelix *_instance);
1251 
1252 IHelix *getHelix();
1253 
1254 } // namespace chatterino
QString startedAt
Definition: Helix.hpp:95
QString userId
Definition: Helix.hpp:336
QString cursor
Definition: Helix.hpp:355
HelixAddChannelModeratorError
Definition: Helix.hpp:457
const bool subscriberMode
Definition: Helix.hpp:313
HelixUpdateChatSettingsError
Definition: Helix.hpp:535
HelixRemoveChannelVIPError
Definition: Helix.hpp:490
HelixRemoveChannelModeratorError
Definition: Helix.hpp:469
int minBits
Definition: Helix.hpp:219
QString ownerId
Definition: Helix.hpp:275
Definition: Helix.hpp:175
QString userName
Definition: Helix.hpp:89
HelixChatters(const QJsonObject &jsonObject)
Definition: Helix.hpp:359
int viewerCount
Definition: Helix.hpp:94
Definition: Helix.hpp:132
Definition: NetworkRequest.hpp:13
QString boxArtUrl
Definition: Helix.hpp:135
HelixStartCommercialResponse(const QJsonObject &jsonObject)
Definition: Helix.hpp:610
HelixBlock(QJsonObject jsonObject)
Definition: Helix.hpp:195
const boost::optional< int > nonModeratorChatDelayDuration
Definition: Helix.hpp:311
QString id
Definition: Helix.hpp:26
QString profileImageUrl
Definition: Helix.hpp:31
Definition: Helix.hpp:305
Url imageURL2x
Definition: Helix.hpp:205
HelixWhisperError
Definition: Helix.hpp:560
Definition: Helix.hpp:925
QString type
Definition: Helix.hpp:92
HelixClipError
Definition: Helix.hpp:409
Url imageURL4x
Definition: Helix.hpp:206
HelixCheermoteImage lightStatic
Definition: Helix.hpp:223
Definition: Helix.hpp:216
HelixSendChatAnnouncementError
Definition: Helix.hpp:449
HelixChannel(QJsonObject jsonObject)
Definition: Helix.hpp:164
QString cursor
Definition: Helix.hpp:379
QString description
Definition: Helix.hpp:177
HelixAddChannelVIPError
Definition: Helix.hpp:480
QString description
Definition: Helix.hpp:30
QString fromName
Definition: Helix.hpp:46
HelixUpdateUserChatColorError
Definition: Helix.hpp:429
std::vector< HelixCheermoteTier > tiers
Definition: Helix.hpp:260
HelixModerators(const QJsonObject &jsonObject)
Definition: Helix.hpp:383
const bool uniqueChatMode
Definition: Helix.hpp:314
const bool emoteMode
Definition: Helix.hpp:307
Definition: Helix.hpp:203
Definition: Application.cpp:48
QString userLogin
Definition: Helix.hpp:342
QString title
Definition: Helix.hpp:93
Definition: Helix.hpp:156
QString id
Definition: Helix.hpp:217
std::function< void(T...)> FailureCallback
Definition: Helix.hpp:635
HelixClip(QJsonObject jsonObject)
Definition: Helix.hpp:149
HelixUsersFollowsRecord()
Definition: Helix.hpp:51
Definition: Helix.hpp:44
QString toName
Definition: Helix.hpp:48
HelixBanUserError
Definition: Helix.hpp:547
QString setId
Definition: Helix.hpp:274
std::function< void()> HelixFailureCallback
Definition: Helix.hpp:21
HelixCheermoteImage darkAnimated
Definition: Helix.hpp:220
QString id
Definition: Helix.hpp:178
QString userId
Definition: Helix.hpp:191
Definition: Helix.hpp:257
HelixUser(QJsonObject jsonObject)
Definition: Helix.hpp:33
Definition: Helix.hpp:631
HelixGame(QJsonObject jsonObject)
Definition: Helix.hpp:137
QString id
Definition: Helix.hpp:133
void initializeHelix(IHelix *_instance)
Definition: Helix.cpp:2500
HelixUsersFollowsResponse(QJsonObject jsonObject)
Definition: Helix.hpp:73
QString createdAt
Definition: Helix.hpp:176
QString editUrl
Definition: Helix.hpp:147
std::function< void(T...)> ResultCallback
Definition: IvrApi.hpp:15
HelixEmoteSetData(QJsonObject jsonObject)
Definition: Helix.hpp:278
QString thumbnailUrl
Definition: Helix.hpp:97
HelixStreamMarkerError
Definition: Helix.hpp:415
int positionSeconds
Definition: Helix.hpp:179
Definition: NetworkResult.hpp:9
const boost::optional< int > slowModeWaitTime
Definition: Helix.hpp:312
QString userName
Definition: Helix.hpp:192
QString userLogin
Definition: Helix.hpp:88
HelixCheermoteImage(QJsonObject jsonObject)
Definition: Helix.hpp:208
HelixCheermoteTier(QJsonObject jsonObject)
Definition: Helix.hpp:225
HelixStreamMarker(QJsonObject jsonObject)
Definition: Helix.hpp:181
QString title
Definition: Helix.hpp:162
QString name
Definition: Helix.hpp:158
QString toId
Definition: Helix.hpp:47
std::vector< HelixUsersFollowsRecord > data
Definition: Helix.hpp:72
Definition: Helix.hpp:286
std::unordered_set< QString > chatters
Definition: Helix.hpp:353
int retryAfter
Definition: Helix.hpp:608
QString id
Definition: Helix.hpp:86
int total
Definition: Helix.hpp:354
HelixUsersFollowsRecord(QJsonObject jsonObject)
Definition: Helix.hpp:60
Definition: Helix.hpp:25
const QString url
Definition: Helix.hpp:291
HelixListVIPsError
Definition: Helix.hpp:591
HelixCheermoteImage darkStatic
Definition: Helix.hpp:221
Url imageURL1x
Definition: Helix.hpp:204
QString userName
Definition: Helix.hpp:339
HelixChatSettings(QJsonObject jsonObject)
Definition: Helix.hpp:316
const QString type
Definition: Helix.hpp:289
const QString broadcasterId
Definition: Helix.hpp:306
HelixChannelEmote(QJsonObject jsonObject)
Definition: Helix.hpp:293
#define TWITCH_EMOTE_TEMPLATE
Definition: TwitchEmotes.hpp:15
QString prefix
Definition: Helix.hpp:258
HelixCheermoteSet(QJsonObject jsonObject)
Definition: Helix.hpp:262
Definition: Helix.hpp:85
int length
Definition: Helix.hpp:604
HelixVip(const QJsonObject &jsonObject)
Definition: Helix.hpp:344
HelixStartRaidError
Definition: Helix.hpp:513
QString displayName
Definition: Helix.hpp:193
QString userId
Definition: Helix.hpp:157
QString gameName
Definition: Helix.hpp:91
std::vector< HelixModerator > moderators
Definition: Helix.hpp:378
Definition: Helix.hpp:377
QString gameName
Definition: Helix.hpp:161
HelixUnbanUserError
Definition: Helix.hpp:501
QString userId
Definition: Helix.hpp:87
const QString setId
Definition: Helix.hpp:290
Definition: Helix.hpp:145
QString emoteType
Definition: Helix.hpp:276
HelixStream()
Definition: Helix.hpp:99
QString id
Definition: Helix.hpp:146
Definition: Helix.hpp:190
const QString emoteId
Definition: Helix.hpp:287
HelixStream(QJsonObject jsonObject)
Definition: Helix.hpp:115
Definition: Helix.hpp:334
HelixAutoModMessageError
Definition: Helix.hpp:421
HelixCancelRaidError
Definition: Helix.hpp:524
QString gameId
Definition: Helix.hpp:90
const boost::optional< int > followerModeDuration
Definition: Helix.hpp:309
QString login
Definition: Helix.hpp:27
HelixGetChattersError
Definition: Helix.hpp:573
QString createdAt
Definition: Helix.hpp:29
int total
Definition: Helix.hpp:71
QString gameId
Definition: Helix.hpp:160
QString color
Definition: Helix.hpp:218
QString displayName
Definition: Helix.hpp:28
HelixAnnouncementColor
Definition: Helix.hpp:399
QString language
Definition: Helix.hpp:159
HelixCheermoteImage lightAnimated
Definition: Helix.hpp:222
QString fromId
Definition: Helix.hpp:45
QString followedAt
Definition: Helix.hpp:49
HelixDeleteChatMessagesError
Definition: Helix.hpp:438
const QString name
Definition: Helix.hpp:288
QString message
Definition: Helix.hpp:606
QString type
Definition: Helix.hpp:259
QString name
Definition: Helix.hpp:134
IHelix * getHelix()
Definition: Helix.cpp:2507
QString language
Definition: Helix.hpp:96
Definition: Helix.hpp:352
HelixGetModeratorsError
Definition: Helix.hpp:582
Definition: Helix.hpp:273
HelixStartCommercialError
Definition: Helix.hpp:619