Files
ttw_fmx_v10/Services/uTTWEventSub.pas
T
2025-09-11 08:37:27 +03:00

683 lines
23 KiB
ObjectPascal

unit uTTWEventSub;
interface
uses
System.SysUtils, System.JSON, System.Types, System.UITypes, System.Classes,
Winapi.WinInet, System.Win.ComObj, IdException,
ipwcore, ipwtypes, ipwwsclient, ipwping, idhttp, IdSSLOpenSSL, uRecords,
fmx.Types, System.Net.HttpClient, System.Net.HttpClientComponent;
type
TNotifyEvent = procedure(s: string) of object;
TGetCustomRewardEvent = procedure(s: TCustomRewardEvent) of object;
TGetFollowEvent = procedure(s: TFollowEvent) of object;
TGetGiftEvent = procedure(s: TGiftEvent) of object;
TGetSubEvent = procedure(s: TSubEvent) of object;
TGetRaidEvent = procedure(s: TRaidEvent) of object;
TOnLog = procedure(aModul: string; aMethod: string; aMessage: string;
aLevel: integer) of object;
TOnStatus = procedure(Sender: TObject; const ConnectionEvent: String;
StatusCode: integer; const Description: String) of Object;
type
TTTW_ES = class(TObject)
FTimer: ttimer;
wss: TipwWSClient;
private
BroadcasterID: string;
FAccessToken: string;
FClientID: string;
FOnError: TNotifyEvent;
FOnMessage: TNotifyEvent;
FOnSubOk: TNotifyEvent;
FOnRAW: TNotifyEvent;
FOnGetCustomReward: TGetCustomRewardEvent;
FOnFollow: TGetFollowEvent;
FOnGift: TGetGiftEvent;
FOnSub: TGetSubEvent;
FOnLog: TOnLog;
FOnRaid: TGetRaidEvent;
FOnStatus: TOnStatus;
SW: TWelcomMessage;
procedure HandleTimer(Sender: TObject);
procedure ipwWSClient1DataIn(Sender: TObject; DataFormat: integer;
const Text: string; const TextB: TBytes; EOM, EOL: Boolean);
procedure ipwWSPing(Sender: TObject; const Payload: String;
const PayloadB: TBytes; Response: Boolean);
procedure ipwWSClient1ConnectionStatus(Sender: TObject;
const ConnectionEvent: String; StatusCode: integer;
const Description: String);
procedure ipwWSClientError(Sender: TObject; ErrorCode: integer;
const Description: string);
procedure ipwWSClientDisconnected(Sender: TObject; StatusCode: integer;
const Description: String);
procedure ipwWSClientHeader(Sender: TObject; const Field: String;
const Value: String);
procedure ipwWSClientLog(Sender: TObject; LogLevel: integer;
const aMessage, aLog: string);
function subscribeTo(const EventType, Version: string;
const Condition: string): Boolean;
procedure subscribe();
// function ParseRewardRedeemed(const AJsonString: string): TRewardRedeemed;
procedure EventMSG(const AText: string);
function ParseWelcomMessage(const JSONString: string): TWelcomMessage;
function ParseCustomRewardEvent(const JSONString: string)
: TCustomRewardEvent;
function ParseFollowEvent(const JSONString: string): TFollowEvent;
function ParseSubEvent(const JSONString: string): TSubEvent;
function ParseGiftEvent(const JSONString: string): TGiftEvent;
function ParseRaidEvent(const JSONString: string): TRaidEvent;
procedure toLog(aLevel: integer; aMethod: string; aMessage: string);
function ParseMetadata(const JSONString: string): TMetadata;
public
constructor Create(Sender: TObject;
aTokenWS, aClientID, aBroadcasterID: string);
destructor Destroy; override;
procedure Connect();
procedure Disconnect;
property OnMessage: TNotifyEvent read FOnMessage write FOnMessage;
property OnError: TNotifyEvent read FOnError write FOnError;
property OnSubOk: TNotifyEvent read FOnSubOk write FOnSubOk;
property OnRAW: TNotifyEvent read FOnRAW write FOnRAW;
property OnGetCustomReward: TGetCustomRewardEvent read FOnGetCustomReward
write FOnGetCustomReward;
property OnStatus: TOnStatus read FOnStatus write FOnStatus;
property OnFollow: TGetFollowEvent read FOnFollow write FOnFollow;
property OnSub: TGetSubEvent read FOnSub write FOnSub;
property OnGift: TGetGiftEvent read FOnGift write FOnGift;
property OnRaid: TGetRaidEvent read FOnRaid write FOnRaid;
property OnLog: TOnLog read FOnLog write FOnLog;
end;
implementation
uses ugeneral;
function SafeGetObj(Parent: TJSONObject; const Name: string): TJSONObject;
begin
Result := Parent.GetValue<TJSONObject>(Name);
if not Assigned(Result) then
raise Exception.CreateFmt('JSON object "%s" not found', [Name]);
end;
function GetStrDef(Obj: TJSONObject; const Name: string;
Default: string = ''): string;
begin
if not Obj.TryGetValue(Name, Result) then
Result := Default;
end;
function SafeGetInt(Parent: TJSONObject; const Name: string): integer;
var
V: TJSONValue;
begin
V := Parent.GetValue(Name);
if Assigned(V) then
Result := StrToIntDef(V.Value, 0)
else
Result := 0;
end;
function SafeGetBool(Parent: TJSONObject; const Name: string): Boolean;
var
V: TJSONValue;
begin
V := Parent.GetValue(Name);
if Assigned(V) then
Result := SameText(V.Value, 'true')
else
Result := False;
end;
procedure TTTW_ES.toLog(aLevel: integer; aMethod: string; aMessage: string);
begin
if Assigned(FOnLog) then
FOnLog('uTTWEvenSub', aMethod, aMessage, aLevel);
end;
procedure TTTW_ES.Connect;
begin
if wss.Connected then
wss.Disconnect;
try
wss.ConnectTo
('wss://eventsub.wss.twitch.tv/ws?keepalive_timeout_seconds=60');
toLog(0, 'Connect', 'Ïîäêëþ÷åíèå ê WebSocket âûïîëíåíî');
FTimer.Enabled := True;
except
on E: Exception do
toLog(2, 'Connect', E.Message);
end;
end;
constructor TTTW_ES.Create(Sender: TObject;
aTokenWS, aClientID, aBroadcasterID: string);
begin
FAccessToken := aTokenWS;
FClientID := aClientID;
BroadcasterID := aBroadcasterID;
wss := TipwWSClient.Create(nil);
wss.Timeout := 30;
wss.OnPing := ipwWSPing;
wss.OnDataIn := ipwWSClient1DataIn;
wss.OnConnectionStatus := ipwWSClient1ConnectionStatus;
wss.OnError := ipwWSClientError;
wss.OnLog := ipwWSClientLog;
wss.OnDisconnected := ipwWSClientDisconnected;
wss.OnHeader := ipwWSClientHeader;
FTimer := ttimer.Create(nil);
FTimer.Interval := 9000;
FTimer.OnTimer := HandleTimer;
FTimer.Enabled := False;
toLog(0, 'Create', 'Èíèöèàëèçàöèÿ EventSub');
end;
destructor TTTW_ES.Destroy;
begin
toLog(0, 'Destroy', 'Çàâåðøåíèå ðàáîòû EventSub');
try
if Assigned(FTimer) then
FreeAndNil(FTimer);
if Assigned(wss) then
begin
if wss.Connected then
Disconnect;
FreeAndNil(wss);
end;
finally
inherited Destroy;
end;
end;
procedure TTTW_ES.Disconnect;
begin
toLog(1, 'Disconnect', 'Îòêëþ÷åíèå îò WebSocket');
try
if wss.Connected then
wss.Disconnect;
FTimer.Enabled := False;
except
on E: Exception do
toLog(2, 'Disconnect', E.ClassName + ': ' + E.Message);
end;
end;
procedure TTTW_ES.EventMSG(const AText: string);
var
md: TMetadata;
begin
TThread.Queue(nil,
procedure
begin
if Assigned(FOnRAW) then
FOnRAW(AText);
md := ParseMetadata(AText);
toLog(0, 'EventMSG', 'Òèï ñîîáùåíèÿ: ' + md.message_type +
', Òèï ïîäïèñêè: ' + md.subscription_type);
if md.message_type = 'session_welcome' then
begin
toLog(0, 'EventMSG', 'Ïîëó÷åí session_welcome');
SW := ParseWelcomMessage(AText);
if Assigned(FOnMessage) then
FOnMessage('Welcome message');
subscribe;
end
else if md.message_type = 'notification' then
begin
if Assigned(FOnGetCustomReward) and
(md.subscription_type = 'channel.channel_points_custom_reward_redemption.add')
then
FOnGetCustomReward(ParseCustomRewardEvent(AText));
if Assigned(FOnFollow) and (md.subscription_type = 'channel.follow')
then
FOnFollow(ParseFollowEvent(AText));
if Assigned(FOnSub) and (md.subscription_type = 'channel.subscribe')
then
FOnSub(ParseSubEvent(AText));
if Assigned(FOnGift) and
(md.subscription_type = 'channel.subscription.gift') then
FOnGift(ParseGiftEvent(AText));
if Assigned(FOnRaid) and (md.subscription_type = 'channel.raid') then
FOnRaid(ParseRaidEvent(AText));
end
else if md.message_type = 'session_keepalive' then
toLog(3, 'EventMSG', 'Ïîëó÷åí keepalive');
end);
end;
procedure TTTW_ES.HandleTimer(Sender: TObject);
begin
if wss.Connected then
begin
toLog(3, 'HandleTimer', 'Îòïðàâêà ping');
wss.Ping;
end;
end;
procedure TTTW_ES.ipwWSClient1ConnectionStatus(Sender: TObject;
const ConnectionEvent: String; StatusCode: integer; const Description: String);
begin
toLog(0, 'ConnectionStatus', Format('%s | %d | %s', [ConnectionEvent,
StatusCode, Description]));
if Assigned(FOnStatus) then
FOnStatus(Sender, ConnectionEvent, StatusCode, Description);
end;
procedure TTTW_ES.ipwWSClient1DataIn(Sender: TObject; DataFormat: integer;
const Text: string; const TextB: TBytes; EOM, EOL: Boolean);
begin
toLog(3, 'ipwWSClient1DataIn', Text);
EventMSG(Text);
end;
procedure TTTW_ES.ipwWSClientDisconnected(Sender: TObject; StatusCode: integer;
const Description: String);
begin
toLog(1, 'ipwWSClientDisconnected', Description);
end;
procedure TTTW_ES.ipwWSClientError(Sender: TObject; ErrorCode: integer;
const Description: string);
begin
toLog(2, 'ipwWSClientError', Format('Êîä: %d | %s',
[ErrorCode, Description]));
if Assigned(FOnError) then
FOnError(Description);
end;
procedure TTTW_ES.ipwWSClientHeader(Sender: TObject;
const Field, Value: String);
begin
// toLog(3, 'ipwWSClientHeader',
// 'Field: ' + Field + ' | Value: ' + Value);
end;
procedure TTTW_ES.ipwWSClientLog(Sender: TObject; LogLevel: integer;
const aMessage, aLog: string);
begin
// toLog(3, 'ipwWSClientLog', 'Level: ' + IntToStr(LogLevel)
// + ' | ' + aMessage + ' | ' + aLog);
// form1.log(1, 'ipwWSClientLog', 'Level: ' + inttostr(LogLevel) + ' Message: ' +
// aMessage + ' Log: ' + aLog);
end;
procedure TTTW_ES.ipwWSPing(Sender: TObject; const Payload: String;
const PayloadB: TBytes; Response: Boolean);
begin
toLog(3, 'ipwWSPing', 'PING ' + Payload);
end;
function TTTW_ES.ParseMetadata(const JSONString: string): TMetadata;
var
Root, Metadata: TJSONObject;
begin
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Metadata := SafeGetObj(Root, 'metadata');
Result.message_id := GetStrDef(Metadata, 'message_id');
Result.message_type := GetStrDef(Metadata, 'message_type');
Result.message_timestamp := GetStrDef(Metadata, 'message_timestamp');
Result.subscription_type := GetStrDef(Metadata, 'subscription_type');
finally
Root.Free;
end;
end;
function TTTW_ES.ParseWelcomMessage(const JSONString: string): TWelcomMessage;
var
Root, Payload, Session: TJSONObject;
begin
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Session := SafeGetObj(Payload, 'session');
Result.Payload.Session.id := GetStrDef(Session, 'id');
Result.Payload.Session.status := GetStrDef(Session, 'status');
Result.Payload.Session.connected_at := GetStrDef(Session, 'connected_at');
Result.Payload.Session.keepalive_timeout_seconds :=
SafeGetInt(Session, 'keepalive_timeout_seconds');
Result.Payload.Session.reconnect_url := GetStrDef(Session, 'reconnect_url');
finally
Root.Free;
end;
end;
function TTTW_ES.ParseCustomRewardEvent(const JSONString: string)
: TCustomRewardEvent;
var
Root, Payload, Subscription, mCondition, mTransport, Event,
mReward: TJSONObject;
begin
toLog(3, 'ParseCustomRewardEvent', 'Íà÷àëî ïàðñèíãà íàãðàäû');
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Subscription := SafeGetObj(Payload, 'subscription');
with Result.Subscription do
begin
id := GetStrDef(Subscription, 'id');
subscription_type := GetStrDef(Subscription, 'type');
Version := GetStrDef(Subscription, 'version');
status := GetStrDef(Subscription, 'status');
cost := SafeGetInt(Subscription, 'cost');
created_at := GetStrDef(Subscription, 'created_at');
mCondition := SafeGetObj(Subscription, 'condition');
Condition.broadcaster_user_id :=
GetStrDef(mCondition, 'broadcaster_user_id');
Condition.reward_id := GetStrDef(mCondition, 'reward_id');
mTransport := SafeGetObj(Subscription, 'transport');
transport.method := GetStrDef(mTransport, 'method');
end;
Event := SafeGetObj(Payload, 'event');
with Result.Event do
begin
id := GetStrDef(Event, 'id');
broadcaster_user_id := GetStrDef(Event, 'broadcaster_user_id');
broadcaster_user_login := GetStrDef(Event, 'broadcaster_user_login');
broadcaster_user_name := GetStrDef(Event, 'broadcaster_user_name');
user_id := GetStrDef(Event, 'user_id');
user_login := GetStrDef(Event, 'user_login');
user_name := GetStrDef(Event, 'user_name');
user_input := GetStrDef(Event, 'user_input');
mReward := SafeGetObj(Event, 'reward');
revard.id := GetStrDef(mReward, 'id');
revard.title := GetStrDef(mReward, 'title');
revard.cost := SafeGetInt(mReward, 'cost');
revard.prompt := GetStrDef(mReward, 'prompt');
end;
finally
Root.Free;
end;
end;
function TTTW_ES.ParseFollowEvent(const JSONString: string): TFollowEvent;
var
Root, Payload, Subscription, mCondition, mTransport, Event: TJSONObject;
begin
toLog(3, 'ParseFollowEvent', 'Ïàðñèíã ïîäïèñêè');
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Subscription := SafeGetObj(Payload, 'subscription');
with Result.Subscription do
begin
id := GetStrDef(Subscription, 'id');
subscription_type := GetStrDef(Subscription, 'type');
Version := GetStrDef(Subscription, 'version');
status := GetStrDef(Subscription, 'status');
cost := SafeGetInt(Subscription, 'cost');
created_at := GetStrDef(Subscription, 'created_at');
mCondition := SafeGetObj(Subscription, 'condition');
Condition.broadcaster_user_id :=
GetStrDef(mCondition, 'broadcaster_user_id');
mTransport := SafeGetObj(Subscription, 'transport');
transport.method := GetStrDef(mTransport, 'method');
end;
Event := SafeGetObj(Payload, 'event');
with Result.Event do
begin
broadcaster_user_id := GetStrDef(Event, 'broadcaster_user_id');
broadcaster_user_login := GetStrDef(Event, 'broadcaster_user_login');
broadcaster_user_name := GetStrDef(Event, 'broadcaster_user_name');
user_id := GetStrDef(Event, 'user_id');
user_login := GetStrDef(Event, 'user_login');
user_name := GetStrDef(Event, 'user_name');
followed_at := GetStrDef(Event, 'followed_at');
end;
finally
Root.Free;
end;
end;
function TTTW_ES.ParseGiftEvent(const JSONString: string): TGiftEvent;
var
Root, Payload, Subscription, mCondition, mTransport, Event: TJSONObject;
begin
toLog(3, 'ParseGiftEvent', 'Ïàðñèíã ïîäàðî÷íîé ïîäïèñêè');
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Subscription := SafeGetObj(Payload, 'subscription');
with Result.Subscription do
begin
id := GetStrDef(Subscription, 'id');
subscription_type := GetStrDef(Subscription, 'type');
Version := GetStrDef(Subscription, 'version');
status := GetStrDef(Subscription, 'status');
cost := SafeGetInt(Subscription, 'cost');
created_at := GetStrDef(Subscription, 'created_at');
mCondition := SafeGetObj(Subscription, 'condition');
Condition.broadcaster_user_id :=
GetStrDef(mCondition, 'broadcaster_user_id');
mTransport := SafeGetObj(Subscription, 'transport');
transport.method := GetStrDef(mTransport, 'method');
end;
Event := SafeGetObj(Payload, 'event');
with Result.Event do
begin
broadcaster_user_id := GetStrDef(Event, 'broadcaster_user_id');
broadcaster_user_login := GetStrDef(Event, 'broadcaster_user_login');
broadcaster_user_name := GetStrDef(Event, 'broadcaster_user_name');
user_id := GetStrDef(Event, 'user_id');
user_login := GetStrDef(Event, 'user_login');
user_name := GetStrDef(Event, 'user_name');
total := SafeGetInt(Event, 'total');
tier := GetStrDef(Event, 'tier');
cumulative_total := SafeGetInt(Event, 'cumulative_total');
is_anonymous := SafeGetBool(Event, 'anonymous');
end;
finally
Root.Free;
end;
end;
function TTTW_ES.ParseRaidEvent(const JSONString: string): TRaidEvent;
var
Root, Payload, Subscription, mCondition, mTransport, Event: TJSONObject;
begin
toLog(3, 'ParseRaidEvent', 'Ïàðñèíã ðåéäà');
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Subscription := SafeGetObj(Payload, 'subscription');
with Result.Subscription do
begin
id := GetStrDef(Subscription, 'id');
subscription_type := GetStrDef(Subscription, 'type');
Version := GetStrDef(Subscription, 'version');
status := GetStrDef(Subscription, 'status');
cost := SafeGetInt(Subscription, 'cost');
created_at := GetStrDef(Subscription, 'created_at');
mCondition := SafeGetObj(Subscription, 'condition');
Condition.broadcaster_user_id :=
GetStrDef(mCondition, 'to_broadcaster_user_id');
mTransport := SafeGetObj(Subscription, 'transport');
transport.method := GetStrDef(mTransport, 'method');
end;
Event := SafeGetObj(Payload, 'event');
with Result.Event do
begin
from_broadcaster_user_id := GetStrDef(Event, 'from_broadcaster_user_id');
from_broadcaster_user_login :=
GetStrDef(Event, 'from_broadcaster_user_login');
from_broadcaster_user_name :=
GetStrDef(Event, 'from_broadcaster_user_name');
to_broadcaster_user_id := GetStrDef(Event, 'to_broadcaster_user_id');
to_broadcaster_user_login :=
GetStrDef(Event, 'to_broadcaster_user_login');
to_broadcaster_user_name := GetStrDef(Event, 'to_broadcaster_user_name');
viewers := SafeGetInt(Event, 'viewers');
end;
finally
Root.Free;
end;
end;
function TTTW_ES.ParseSubEvent(const JSONString: string): TSubEvent;
var
Root, Payload, Subscription, mCondition, mTransport, Event: TJSONObject;
begin
toLog(3, 'ParseSubEvent', 'Ïàðñèíã ïîäïèñêè');
Root := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(Root) then
raise Exception.Create('Invalid JSON');
try
Payload := SafeGetObj(Root, 'payload');
Subscription := SafeGetObj(Payload, 'subscription');
with Result.Subscription do
begin
id := GetStrDef(Subscription, 'id');
subscription_type := GetStrDef(Subscription, 'type');
Version := GetStrDef(Subscription, 'version');
status := GetStrDef(Subscription, 'status');
cost := SafeGetInt(Subscription, 'cost');
created_at := GetStrDef(Subscription, 'created_at');
mCondition := SafeGetObj(Subscription, 'condition');
Condition.broadcaster_user_id :=
GetStrDef(mCondition, 'broadcaster_user_id');
mTransport := SafeGetObj(Subscription, 'transport');
transport.method := GetStrDef(mTransport, 'method');
end;
Event := SafeGetObj(Payload, 'event');
with Result.Event do
begin
broadcaster_user_id := GetStrDef(Event, 'broadcaster_user_id');
broadcaster_user_login := GetStrDef(Event, 'broadcaster_user_login');
broadcaster_user_name := GetStrDef(Event, 'broadcaster_user_name');
user_id := GetStrDef(Event, 'user_id');
user_login := GetStrDef(Event, 'user_login');
user_name := GetStrDef(Event, 'user_name');
tier := GetStrDef(Event, 'tier');
is_gift := SafeGetBool(Event, 'is_gift');
end;
finally
Root.Free;
end;
end;
function TTTW_ES.subscribeTo(const EventType, Version: string;
const Condition: string): Boolean;
var
JSON: TStringStream;
Resp: string;
HTTP: TNetHTTPClient;
begin
Result := False;
toLog(0, 'subscribeTo', 'Ïîäïèñêà íà ' + EventType);
try
HTTP := TNetHTTPClient.Create(nil);
try
HTTP.ContentType := 'application/json';
HTTP.CustomHeaders['Authorization'] := 'Bearer ' + FAccessToken;
HTTP.CustomHeaders['Client-Id'] := FClientID;
JSON := TStringStream.Create(TJSONObject.Create.AddPair('type', EventType)
.AddPair('version', Version).AddPair('condition',
TJSONObject.ParseJSONValue(Condition) as TJSONObject)
.AddPair('transport', TJSONObject.Create.AddPair('method', 'websocket')
.AddPair('session_id', SW.Payload.Session.id)).ToJSON, TEncoding.UTF8);
try
Resp := HTTP.Post('https://api.twitch.tv/helix/eventsub/subscriptions',
JSON).ContentAsString();
toLog(3, 'subscribeTo', 'Îòâåò Twitch: ' + Resp);
if Pos('"status":"enabled"', Resp) > 0 then
begin
toLog(0, 'subscribeTo', 'Ïîäïèñêà óñïåøíà');
Result := True;
end
else
toLog(1, 'subscribeTo', 'Ïîäïèñêà íå ïîäòâåðæäåíà: ' + Resp);
finally
JSON.Free;
end;
finally
HTTP.Free;
end;
except
on E: Exception do
toLog(2, 'subscribeTo', 'Îøèáêà ïîäïèñêè: ' + E.Message);
end;
end;
procedure TTTW_ES.subscribe;
begin
// channel.channel_points_custom_reward.add (1)
// channel.follow (2) moderator:read:followers
// channel.subscribe (1) channel:read:subscriptions
// channel.subscription.gift (1) channel:read:subscriptions
// channel.raid (1)
if subscribeTo('channel.channel_points_custom_reward_redemption.add', '1',
'{"broadcaster_user_id":"' + BroadcasterID + '"}') then
toLog(0, 'subscribe',
'channel.channel_points_custom_reward_redemption.add OK')
else
toLog(2, 'subscribe',
'channel.channel_points_custom_reward_redemption.add');
if subscribeTo('channel.raid', '1', '{"to_broadcaster_user_id":"' +
BroadcasterID + '"}') then
toLog(0, 'subscribe', 'channel.raid OK')
else
toLog(2, 'subscribe', 'channel.raid');
if subscribeTo('channel.follow', '2', '{"broadcaster_user_id":"' +
BroadcasterID + '","moderator_user_id":"' + BroadcasterID + '"}') then
toLog(0, 'subscribe', 'channel.follow OK')
else
toLog(2, 'subscribe', 'channel.follow');
if subscribeTo('channel.subscribe', '1', '{"broadcaster_user_id":"' +
BroadcasterID + '"}') then
toLog(0, 'subscribe', 'channel.subscribe OK')
else
toLog(2, 'subscribe', 'channel.subscribe');
if subscribeTo('channel.subscription.gift', '1', '{"broadcaster_user_id":"' +
BroadcasterID + '"}') then
toLog(0, 'subscribe', 'channel.subscription.gift OK')
else
toLog(2, 'subscribe', 'channel.subscription.gift');
end;
end.