Files
ttw_fmx_v10/Services/uTTWAPI.pas
T

1097 lines
30 KiB
ObjectPascal

unit uTTWAPI;
interface
uses
System.Classes, System.SysUtils, IdHTTP, IdSSLOpenSSL, System.JSON, FMX.Forms,
IdMultipartFormData, DateUtils, uDataBase, System.Generics.Collections,
uRecords;
type
TOnLog = procedure(aModul: string; aMethod: string; aMessage: string; aLevel: integer) of object;
type
TTTW_API = class(TObject)
private
Token_api: string;
Token_api_streamer: string;
ClientID: string;
channel_name_api: string;
BotName_api: string;
FChatBadges: TList<TChatBadge>;
FOnLog: TOnLog;
function GetFollowedAtFromJson(jsonString: string): string;
function getTTW(method: string; ClientID: string;
isStreamer: boolean = false): string;
function DelTTW(method: string; ClientID: string;
isStreamer: boolean = false): string;
function postTTW(method: string; ClientID: string;
params: TIdMultipartFormDataStream; isStreamer: boolean = false)
: string; overload;
function postTTW(method: string; ClientID: string; params: TStringStream;
isStreamer: boolean = false): string; overload;
function patchTTW(method: string; ClientID: string; params: TStringStream;
isStreamer: boolean = false): string; overload;
procedure toLog(alevel: integer; amethod: string; amessage: string);
public
constructor Create(Sender: TObject);
destructor Destroy; override;
procedure Init(myClient, myToken, streamerToken, Channel,
myBotName: string);
procedure getTTWStat(Channel: string; var avg_viewers: integer;
var max_viewers: integer; var hours_watched: integer;
var followers: integer; var followers_total: integer);
procedure shoutouts(id: string);
procedure SendNotify(text: string);
procedure banUser(id: string);
procedure banUserTime(id: string; aTime: integer);
procedure unBanUser(id: string);
procedure warnUser(id: string);
procedure raid(id: string);
procedure unRaid();
procedure setModerator(id: string);
procedure delModerator(id: string);
procedure setVIP(id: string);
procedure delVIP(id: string);
procedure getCustomReward(var acr: TList<TCustomRevards>);
function createCustomReward(title: string; cost: string;
promt: string = ''; isUserInput: boolean = false): TCustomRevards;
procedure UpdateCustomReward(ahr: TCustomRevards);
procedure UpdateRedemptionStatus(ahr: TCustomRewardEvent);
procedure deleteCustomReward(id: string);
function getRoomAndBot(): string;
function getUserbyLogin(login: string): TUser;
function getFollow(id: string): TDateTime;
function GetRoomID: string;
procedure getGlobalChatBadges(var gcb: TList<TChatBadge>);
procedure getCustomChatBadges(var ccb: TList<TChatBadge>);
procedure GetChannelEmotes(var ce: TList<TEmotes>);
procedure GetGlobalEmotes(var ge: TList<TEmotes>);
function ValidateTwitchToken(const TokenName, TokenValue: string; var DayOfLive: integer): Boolean;
property OnLog: TOnLog read FOnLog write FOnLog;
end;
var
room_id: string = '';
bot_id: string = '';
implementation
uses uGeneral;
constructor TTTW_API.Create(Sender: TObject);
begin
FChatBadges := TList<TChatBadge>.Create;
end;
function TTTW_API.createCustomReward(title: string; cost: string;
promt: string = ''; isUserInput: boolean = false): TCustomRevards;
var
RequestData: TStringStream;
s, s1, json: string;
i: integer;
cr: TCustomRevards;
JSONData: TJSONObject;
JSONArray: TJSONArray;
begin
Result := Default(TCustomRevards);
try
if room_id = '' then
room_id := GetRoomID;
s := '';
s1 := '';
if isUserInput then
s := ' "is_user_input_required":true,';
if promt <> '' then
s1 := ' "prompt":"' + promt + '",';
RequestData := TStringStream.Create('{ "title":"' + title + '", ' + s + s1
+ ' "cost":' + cost + ' }', TEncoding.UTF8);
try
json := postTTW('channel_points/custom_rewards?broadcaster_id=' + room_id, ClientID,
RequestData, true);
if json = '' then
begin
toLog(1, 'createCustomReward', 'Íàãðàäà íå ñîçäàëàñü, çàïðîñ âåðíóë ïóñòîé îòâåò');
Exit;
end;
JSONData := TJSONObject.ParseJSONValue(json) as TJSONObject;
if not Assigned(JSONData) then
begin
toLog(2, 'createCustomReward', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
JSONArray := JSONData.GetValue<TJSONArray>('data');
if JSONArray.Count > 0 then
begin
cr.id := JSONArray.Items[0].GetValue<string>('id');
cr.title := JSONArray.Items[0].GetValue<string>('title');
cr.promt := JSONArray.Items[0].GetValue<string>('prompt');
cr.cost := JSONArray.Items[0].GetValue<integer>('cost');
cr.is_user_input_required := JSONArray.Items[0].GetValue<boolean>
('is_user_input_required');
Result := cr;
end;
finally
JSONData.Free;
end;
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'createCustomReward', E.Message);
end;
end;
destructor TTTW_API.Destroy;
begin
FChatBadges.Free;
inherited;
end;
procedure TTTW_API.Init(myClient, myToken, streamerToken, Channel,
myBotName: string);
begin
ClientID := myClient;
Token_api := myToken;
Token_api_streamer := streamerToken;
channel_name_api := Channel;
BotName_api := myBotName;
end;
procedure TTTW_API.banUser(id: string);
var
RequestData: TStringStream;
begin
try
if bot_id = '' then
bot_id := getRoomAndBot;
if (bot_id = '') or (room_id = '') then
Exit;
RequestData := TStringStream.Create('{"data": {"user_id":"' + id +
'","reason":"no reason"}}', TEncoding.UTF8);
try
postTTW('moderation/bans?broadcaster_id=' + room_id + '&moderator_id=' +
bot_id, ClientID, RequestData);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'banUser', E.Message);
end;
end;
procedure TTTW_API.banUserTime(id: string; aTime: integer);
var
RequestData: TStringStream;
begin
try
if bot_id = '' then
bot_id := getRoomAndBot;
if (bot_id = '') or (room_id = '') then
Exit;
RequestData := TStringStream.Create('{"data": {"user_id":"' + id +
'","duration":' + IntToStr(aTime) + '}}', TEncoding.UTF8);
try
postTTW('moderation/bans?broadcaster_id=' + room_id + '&moderator_id=' +
bot_id, ClientID, RequestData);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'banUserTime', E.Message);
end;
end;
procedure TTTW_API.deleteCustomReward(id: string);
begin
try
if Token_api_streamer = '' then
Exit;
if room_id = '' then
Exit;
DelTTW('channel_points/custom_rewards?broadcaster_id=' + room_id + '&id=' +
id, ClientID, true);
except
on E: Exception do
toLog(2, 'deleteCustomReward', E.Message);
end;
end;
procedure TTTW_API.delModerator(id: string);
begin
try
if Token_api_streamer = '' then
Exit;
if room_id = '' then
Exit;
DelTTW('moderation/moderators?broadcaster_id=' + room_id + '&user_id=' + id,
ClientID, true);
except
on E: Exception do
toLog(2, 'delModerator', E.Message);
end;
end;
function TTTW_API.DelTTW(method, ClientID: string; isStreamer: boolean): string;
var
url: string;
response1, Token: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
if isStreamer then
Token := Token_api_streamer
else
Token := Token_api;
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
http.Request.CustomHeaders.AddValue('Client-ID', ClientID);
http.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Token);
http.Request.ContentType := 'application/json';
url := 'https://api.twitch.tv/helix/' + method;
response1 := http.Delete(url);
Result := response1;
except
on E: Exception do
toLog(2, 'DelTTW', E.Message + ' [' + method + ']');
end;
finally
http.Free;
ssl.Free;
end;
end;
procedure TTTW_API.delVIP(id: string);
begin
try
if Token_api_streamer = '' then
Exit;
if room_id = '' then
Exit;
DelTTW('channels/vips?broadcaster_id=' + room_id + '&user_id=' + id,
ClientID, true);
except
on E: Exception do
toLog(2, 'delVIP', E.Message);
end;
end;
procedure TTTW_API.getCustomReward(var acr: TList<TCustomRevards>);
var
JSON: string;
sl: TCustomRevards;
JSONData: TJSONObject;
JSONArray: TJSONArray;
i: integer;
begin
try
if Token_api_streamer = '' then
begin
toLog(1, 'getCustomReward', 'Token_api_streamer ïóñò');
Exit;
end;
if room_id = '' then
Exit;
JSON := getTTW('channel_points/custom_rewards?broadcaster_id=' + room_id +
'&only_manageable_rewards=true', ClientID, true);
if JSON = '' then
begin
toLog(1, 'getCustomReward', 'Ïóñòîé îòâåò îò API');
Exit;
end;
JSONData := TJSONObject.ParseJSONValue(JSON) as TJSONObject;
if not Assigned(JSONData) then
begin
toLog(2, 'getCustomReward', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
JSONArray := JSONData.GetValue<TJSONArray>('data');
for i := 0 to JSONArray.Count - 1 do
begin
sl.id := JSONArray.Items[i].GetValue<string>('id');
sl.title := JSONArray.Items[i].GetValue<string>('title');
sl.promt := JSONArray.Items[i].GetValue<string>('prompt');
sl.cost := JSONArray.Items[i].GetValue<integer>('cost');
sl.is_user_input_required := JSONArray.Items[i].GetValue<boolean>
('is_user_input_required');
acr.Add(sl);
end;
finally
JSONData.Free;
end;
except
on E: Exception do
toLog(2, 'getCustomReward', E.Message);
end;
end;
function TTTW_API.getFollow(id: string): TDateTime;
var
s: string;
followedAt: string;
begin
Result := 0;
s := getTTW('channels/followers?user_id=' + id + '&broadcaster_id=' + room_id,
ClientID);
followedAt := GetFollowedAtFromJson(s);
if followedAt <> '' then
Result := StrToDate(followedAt);
end;
function TTTW_API.GetFollowedAtFromJson(jsonString: string): string;
var
JSON: TJSONObject;
dataArray: TJSONArray;
begin
Result := '';
if jsonString = '' then Exit;
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
if not Assigned(JSON) then Exit;
try
dataArray := JSON.GetValue('data') as TJSONArray;
if Assigned(dataArray) and (dataArray.Count > 0) then
Result := DateToStr(ISO8601ToDate(dataArray.Items[0].GetValue<string>('followed_at')));
finally
JSON.Free;
end;
end;
function TTTW_API.getTTW(method, ClientID: string; isStreamer: boolean): string;
var
url: string;
response1, Token: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
if isStreamer then
Token := Token_api_streamer
else
Token := Token_api;
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
http.Request.CustomHeaders.AddValue('Client-ID', ClientID);
http.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Token);
url := 'https://api.twitch.tv/helix/' + method;
response1 := http.Get(url);
Result := response1;
except
on E: Exception do
toLog(2, 'getTTW', E.Message + ' [' + method + ']');
end;
finally
http.Free;
ssl.Free;
end;
end;
procedure TTTW_API.getTTWStat(Channel: string; var avg_viewers, max_viewers,
hours_watched, followers, followers_total: integer);
var
jsonObject: TJSONObject;
url: string;
response1: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
url := 'https://twitchtracker.com/api/channels/summary/' + Channel;
response1 := http.Get(url);
jsonObject := TJSONObject.ParseJSONValue(response1) as TJSONObject;
if not Assigned(jsonObject) then
begin
toLog(2, 'getTTWStat', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
avg_viewers := jsonObject.GetValue<integer>('avg_viewers');
max_viewers := jsonObject.GetValue<integer>('max_viewers');
hours_watched := jsonObject.GetValue<integer>('hours_watched');
followers := jsonObject.GetValue<integer>('followers');
followers_total := jsonObject.GetValue<integer>('followers_total');
finally
jsonObject.Free;
end;
except
on E: Exception do
toLog(2, 'getTTWStat', E.Message);
end;
finally
http.Free;
ssl.Free;
end;
end;
function ParseBadgeVersion(VersionObj: TJSONObject): TBadgeVersion;
begin
Result.Id := VersionObj.GetValue('id').Value;
Result.ImageUrl1x := VersionObj.GetValue('image_url_1x').Value;
Result.ImageUrl2x := VersionObj.GetValue('image_url_2x').Value;
Result.ImageUrl4x := VersionObj.GetValue('image_url_4x').Value;
Result.Title := VersionObj.GetValue('title').Value;
Result.Description := VersionObj.GetValue('description').Value;
Result.ClickAction := VersionObj.GetValue('click_action').Value;
Result.ClickUrl := VersionObj.GetValue('click_url').Value;
end;
function ParseChatBadge(BadgeObj: TJSONObject): TChatBadge;
var
VersionsArray: TJSONArray;
I: Integer;
begin
Result.SetId := BadgeObj.GetValue('set_id').Value;
VersionsArray := BadgeObj.GetValue('versions') as TJSONArray;
SetLength(Result.Versions, VersionsArray.Count);
for I := 0 to VersionsArray.Count - 1 do
Result.Versions[I] := ParseBadgeVersion(VersionsArray.Items[I] as TJSONObject);
end;
procedure ParseBadgesFromApi(const JSONResponse: string; Badges: TList<TChatBadge>);
var
RootObj: TJSONObject;
DataArray: TJSONArray;
I: Integer;
begin
if JSONResponse = '' then Exit;
RootObj := TJSONObject.ParseJSONValue(JSONResponse) as TJSONObject;
if not Assigned(RootObj) then Exit;
try
DataArray := RootObj.GetValue('data') as TJSONArray;
for I := 0 to DataArray.Count - 1 do
Badges.Add(ParseChatBadge(DataArray.Items[I] as TJSONObject));
finally
RootObj.Free;
end;
end;
procedure TTTW_API.getGlobalChatBadges(var gcb: TList<TChatBadge>);
var
jsonString: string;
begin
jsonString := getTTW('chat/badges/global', ClientID, false);
ParseBadgesFromApi(jsonString, gcb);
end;
procedure TTTW_API.getCustomChatBadges(var ccb: TList<TChatBadge>);
var
jsonString: string;
begin
if room_id = '' then Exit;
jsonString := getTTW('chat/badges?broadcaster_id=' + room_id, ClientID, false);
ParseBadgesFromApi(jsonString, ccb);
end;
function TTTW_API.getRoomAndBot(): string;
var
jsonString: string;
JSON: TJSONObject;
dataArray: TJSONArray;
begin
try
jsonString := getTTW('users?login=' + LowerCase(BotName_api), ClientID);
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
if not Assigned(JSON) then
begin
toLog(2, 'getRoomAndBot.GetBotID', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
dataArray := JSON.GetValue('data') as TJSONArray;
if Assigned(dataArray) and (dataArray.Count > 0) then
bot_id := dataArray.Items[0].GetValue<string>('id');
finally
JSON.Free;
end;
except
on E: Exception do
toLog(2, 'getRoomAndBot.GetBotID', E.Message);
end;
try
jsonString := getTTW('users?login=' + LowerCase(channel_name_api), ClientID);
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
if not Assigned(JSON) then
begin
toLog(2, 'getRoomAndBot.GetRoomID', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
dataArray := JSON.GetValue('data') as TJSONArray;
if Assigned(dataArray) and (dataArray.Count > 0) then
room_id := dataArray.Items[0].GetValue<string>('id');
finally
JSON.Free;
end;
except
on E: Exception do
toLog(2, 'getRoomAndBot.GetRoomID', E.Message);
end;
Result := room_id;
end;
function TTTW_API.GetRoomID: string;
begin
Result := room_id;
end;
function TTTW_API.getUserbyLogin(login: string): TUser;
var
u: TUser;
JSON: TJSONObject;
dataArray: TJSONArray;
jsonString: string;
begin
Result := Default(TUser);
jsonString := getTTW('users?login=' + LowerCase(login), ClientID);
if jsonString = '' then Exit;
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
if not Assigned(JSON) then Exit;
try
dataArray := JSON.GetValue('data') as TJSONArray;
if Assigned(dataArray) and (dataArray.Count > 0) then
begin
u.id := dataArray.Items[0].GetValue<string>('id');
u.login := dataArray.Items[0].GetValue<string>('login');
u.DisplayName := dataArray.Items[0].GetValue<string>('display_name');
u.created_at := ISO8601ToDate(dataArray.Items[0].GetValue<string>('created_at'));
Result := u;
end;
finally
JSON.Free;
end;
end;
function TTTW_API.postTTW(method, ClientID: string;
params: TIdMultipartFormDataStream; isStreamer: boolean): string;
var
url: string;
response1, Token: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
if isStreamer then
Token := Token_api_streamer
else
Token := Token_api;
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
http.Request.CustomHeaders.AddValue('Client-ID', ClientID);
http.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Token);
http.Request.ContentType := 'application/json';
url := 'https://api.twitch.tv/helix/' + method;
response1 := http.Post(url, params);
Result := response1;
except
on E: Exception do
toLog(2, 'postTTW', E.Message + ' [' + method + ']');
end;
finally
http.Free;
ssl.Free;
end;
end;
function TTTW_API.patchTTW(method, ClientID: string; params: TStringStream;
isStreamer: boolean): string;
var
url: string;
response1, Token: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
if isStreamer then
Token := Token_api_streamer
else
Token := Token_api;
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
http.Request.CustomHeaders.AddValue('Client-ID', ClientID);
http.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Token);
http.Request.ContentType := 'application/json';
url := 'https://api.twitch.tv/helix/' + method;
response1 := http.Patch(url, params);
Result := response1;
except
on E: Exception do
toLog(2, 'patchTTW', E.Message + ' [' + method + ']');
end;
finally
http.Free;
ssl.Free;
end;
end;
function TTTW_API.postTTW(method, ClientID: string; params: TStringStream;
isStreamer: boolean): string;
var
url: string;
response1, Token: string;
http: TIdHTTP;
ssl: TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';
http := TIdHTTP.Create(nil);
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
if isStreamer then
Token := Token_api_streamer
else
Token := Token_api;
http.IOHandler := ssl;
ssl.SSLOptions.method := sslvSSLv23;
http.Request.UserAgent :=
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
http.Request.CustomHeaders.AddValue('Client-ID', ClientID);
http.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + Token);
http.Request.ContentType := 'application/json';
url := 'https://api.twitch.tv/helix/' + method;
response1 := http.Post(url, params);
Result := response1;
except
on E: Exception do
toLog(2, 'postTTW', E.Message + ' [' + method + ']');
end;
finally
http.Free;
ssl.Free;
end;
end;
procedure TTTW_API.raid(id: string);
var
p: TIdMultipartFormDataStream;
begin
try
if room_id = '' then
Exit;
p := TIdMultipartFormDataStream.Create;
try
postTTW('raids?from_broadcaster_id=' + room_id + '&to_broadcaster_id=' + id, ClientID, p, true);
finally
p.Free;
end;
except
on E: Exception do
toLog(2, 'raid', E.Message);
end;
end;
procedure TTTW_API.SendNotify(text: string);
var
p: TStringStream;
begin
try
if bot_id = '' then
begin
toLog(1, 'SendNotify', 'bot_id ïóñò. Èñïðàâëÿþ');
getRoomAndBot;
if bot_id = '' then
begin
toLog(2, 'SendNotify', 'bot_id âñå ðàâíî ïóñò');
Exit;
end;
end;
if room_id = '' then
begin
toLog(2, 'SendNotify', 'room_id ïóñò');
Exit;
end;
p := TStringStream.Create('{"message":"' + text + '","color":"primary"}', TEncoding.UTF8);
try
postTTW('chat/announcements?broadcaster_id=' + room_id + '&moderator_id=' + bot_id, ClientID, p);
finally
p.Free;
end;
except
on E: Exception do
toLog(2, 'SendNotify', E.Message);
end;
end;
procedure TTTW_API.setModerator(id: string);
var
RequestData: TStringStream;
begin
try
if Token_api_streamer = '' then Exit;
if room_id = '' then Exit;
RequestData := TStringStream.Create('', TEncoding.UTF8);
try
postTTW('moderation/moderators?broadcaster_id=' + room_id + '&user_id=' + id, ClientID, RequestData, true);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'setModerator', E.Message);
end;
end;
procedure TTTW_API.setVIP(id: string);
var
RequestData: TStringStream;
begin
try
if Token_api_streamer = '' then Exit;
if room_id = '' then Exit;
RequestData := TStringStream.Create('', TEncoding.UTF8);
try
postTTW('channels/vips?broadcaster_id=' + room_id + '&user_id=' + id, ClientID, RequestData, true);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'setVIP', E.Message);
end;
end;
procedure TTTW_API.shoutouts(id: string);
var
p: TIdMultipartFormDataStream;
begin
try
if (bot_id = '') or (room_id = '') then
Exit;
p := TIdMultipartFormDataStream.Create;
try
postTTW('chat/shoutouts?from_broadcaster_id=' + room_id + '&to_broadcaster_id=' + id + '&moderator_id=' + bot_id, ClientID, p);
finally
p.Free;
end;
except
on E: Exception do
toLog(2, 'shoutouts', E.Message);
end;
end;
procedure TTTW_API.toLog(alevel: integer; amethod, amessage: string);
begin
if Assigned(FOnLog) then
FOnLog('uTTWAPI', amethod, amessage, alevel);
end;
procedure TTTW_API.unBanUser(id: string);
begin
try
if bot_id = '' then bot_id := getRoomAndBot;
if (bot_id = '') or (room_id = '') then Exit;
DelTTW('moderation/bans?broadcaster_id=' + room_id + '&moderator_id=' + bot_id + '&user_id=' + id, ClientID);
except
on E: Exception do
toLog(2, 'unBanUser', E.Message);
end;
end;
procedure TTTW_API.unRaid;
begin
try
if room_id = '' then Exit;
DelTTW('raids?broadcaster_id=' + room_id, ClientID);
except
on E: Exception do
toLog(2, 'unRaid', E.Message);
end;
end;
procedure TTTW_API.UpdateCustomReward(ahr: TCustomRevards);
var
RequestData: TStringStream;
qid: string;
begin
try
if room_id = '' then Exit;
qid := ahr.id;
RequestData := TStringStream.Create('{"cost": ' + IntToStr(ahr.cost) + '}', TEncoding.UTF8);
try
patchTTW('channel_points/custom_rewards?broadcaster_id=' + room_id + '&id=' + qid, ClientID, RequestData, true);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'UpdateCustomReward', E.Message);
end;
end;
procedure TTTW_API.UpdateRedemptionStatus(ahr: TCustomRewardEvent);
var
qbid, qrid, qid: string;
RequestData: TStringStream;
begin
try
if (bot_id = '') or (room_id = '') then
Exit;
qbid := ahr.event.broadcaster_user_id;
qrid := ahr.event.revard.id;
qid := ahr.event.id;
toLog(0, 'UpdateRedemptionStatus', 'ChannelId: ' + qbid + '; Reward.id: ' + qrid + '; Redemption.id: ' + qid);
RequestData := TStringStream.Create('{"status":"CANCELED"}', TEncoding.UTF8);
try
patchTTW('channel_points/custom_rewards/redemptions?broadcaster_id=' + qbid + '&reward_id=' + qrid + '&id=' + qid, ClientID, RequestData, true);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'UpdateRedemptionStatus', E.Message);
end;
end;
function TTTW_API.ValidateTwitchToken(const TokenName, TokenValue: string; var DayOfLive: integer): Boolean;
var
HTTP: TIdHTTP;
SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
ResponseStream: TStringStream;
ResponseJSON: TJSONObject;
StatusCode: Integer;
ResponseText: string;
begin
Result := False;
DayOfLive := 0;
if Trim(TokenValue) = '' then
begin
toLog(1, 'ValidateTwitchToken', 'Ïóñòîé òîêåí');
Exit;
end;
HTTP := TIdHTTP.Create(nil);
SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
ResponseStream := TStringStream.Create;
try
HTTP.IOHandler := SSLHandler;
HTTP.Request.CustomHeaders.Values['Authorization'] := 'OAuth ' + TokenValue;
HTTP.Request.UserAgent := 'YourApp/1.0';
HTTP.Request.Accept := 'application/json';
HTTP.HTTPOptions := [hoKeepOrigProtocol];
try
HTTP.Get('https://id.twitch.tv/oauth2/validate', ResponseStream);
StatusCode := HTTP.ResponseCode;
ResponseText := ResponseStream.DataString;
except
on E: EIdHTTPProtocolException do
begin
StatusCode := E.ErrorCode;
ResponseText := E.ErrorMessage;
end;
on E: Exception do
begin
toLog(2, 'ValidateTwitchToken', E.Message);
Exit;
end;
end;
if StatusCode = 200 then
begin
try
ResponseJSON := TJSONObject.ParseJSONValue(ResponseText) as TJSONObject;
if not Assigned(ResponseJSON) then
begin
toLog(2, 'ValidateTwitchToken', 'Îøèáêà ïàðñèíãà JSON');
Exit;
end;
try
if ResponseJSON.GetValue('expires_in') <> nil then
begin
DayOfLive := Round(ResponseJSON.GetValue('expires_in').Value.ToInteger / 86400);
toLog(0, 'ValidateTwitchToken', Format('Òîêåí äåéñòâèòåëåí. Îñòàëîñü: %d äíåé', [DayOfLive]));
end;
Result := True;
finally
ResponseJSON.Free;
end;
except
on E: Exception do
toLog(2, 'ValidateTwitchToken', E.Message);
end;
end
else if StatusCode = 401 then
begin
toLog(2, 'ValidateTwitchToken', 'Invalid token');
end
else
begin
toLog(2, 'ValidateTwitchToken', Format('HTTP %d: %s', [StatusCode, ResponseText]));
end;
finally
ResponseStream.Free;
SSLHandler.Free;
HTTP.Free;
end;
end;
procedure TTTW_API.warnUser(id: string);
var
RequestData: TStringStream;
begin
try
if bot_id = '' then bot_id := getRoomAndBot;
if (bot_id = '') or (room_id = '') then Exit;
RequestData := TStringStream.Create('{"data": {"user_id":"' + id + '","reason":"Âàì âûíåñåíî ïðåäóïðåæäåíèå!"}}', TEncoding.UTF8);
try
postTTW('moderation/warnings?broadcaster_id=' + room_id + '&moderator_id=' + bot_id, ClientID, RequestData);
finally
RequestData.Free;
end;
except
on E: Exception do
toLog(2, 'warnUser', E.Message);
end;
end;
function GetStringValue(JSONObj: TJSONObject; const Name: string): string;
var
Val: TJSONValue;
begin
Val := JSONObj.GetValue(Name);
if Assigned(Val) then
Result := Val.Value
else
Result := '';
end;
function GetStringArray(JSONObj: TJSONObject; const Name: string): TArray<string>;
var
Arr: TJSONArray;
I: Integer;
begin
SetLength(Result, 0);
if not JSONObj.TryGetValue<TJSONArray>(Name, Arr) then Exit;
SetLength(Result, Arr.Count);
for I := 0 to Arr.Count - 1 do
Result[I] := Arr.Items[I].Value;
end;
procedure ParseEmotes(const JSONString: string; EmotesList: TList<TEmotes>);
var
RootObj: TJSONObject;
DataArr: TJSONArray;
EmoteObj: TJSONObject;
ImagesObj: TJSONObject;
Emote: TEmotes;
I: Integer;
begin
if JSONString = '' then Exit;
RootObj := TJSONObject.ParseJSONValue(JSONString) as TJSONObject;
if not Assigned(RootObj) then Exit;
try
if not RootObj.TryGetValue<TJSONArray>('data', DataArr) then Exit;
for I := 0 to DataArr.Count - 1 do
begin
EmoteObj := DataArr.Items[I] as TJSONObject;
Emote.id := GetStringValue(EmoteObj, 'id');
Emote.name := GetStringValue(EmoteObj, 'name');
Emote.tier := GetStringValue(EmoteObj, 'tier');
Emote.emote_type := GetStringValue(EmoteObj, 'emote_type');
Emote.emote_set_id := GetStringValue(EmoteObj, 'emote_set_id');
if EmoteObj.TryGetValue<TJSONObject>('images', ImagesObj) then
begin
Emote.images.Url1x := GetStringValue(ImagesObj, 'url_1x');
Emote.images.Url2x := GetStringValue(ImagesObj, 'url_2x');
Emote.images.Url4x := GetStringValue(ImagesObj, 'url_4x');
end;
Emote.format := GetStringArray(EmoteObj, 'format');
Emote.scale := GetStringArray(EmoteObj, 'scale');
Emote.theme_mode := GetStringArray(EmoteObj, 'theme_mode');
EmotesList.Add(Emote);
end;
finally
RootObj.Free;
end;
end;
procedure TTTW_API.GetChannelEmotes(var ce: TList<TEmotes>);
var
jsonres: string;
begin
if room_id = '' then Exit;
jsonres := getTTW('chat/emotes?broadcaster_id=' + room_id, ClientID, false);
ParseEmotes(jsonres, ce);
end;
procedure TTTW_API.GetGlobalEmotes(var ge: TList<TEmotes>);
var
jsonres: string;
begin
jsonres := getTTW('chat/emotes/global', ClientID, false);
ParseEmotes(jsonres, ge);
end;
end.