Last active
November 26, 2022 09:31
-
-
Save RealEthanPlayzDev/b95ecfca4fa4d651152ee4975a52a5a2 to your computer and use it in GitHub Desktop.
RbxHolodexAPI - A Holodex API wrapper for usage in Roblox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--// This is the v1 version of the RbxHolodexAPI, I suggest you to use the v2 instead. | |
--[[ | |
File name: HoloDexLuaAPI.lua | |
Author: RadiatedExodus (RealEthanPlayzDev) | |
API wrapper for Holodex (https://holodex.net) | |
--]] | |
local serv = { HttpService = game:GetService("HttpService") } | |
--// CLASS DEFINITION: HoloDexLuaAPI | |
local HoloDexLuaAPI = {} | |
HoloDexLuaAPI.__index = HoloDexLuaAPI | |
HoloDexLuaAPI.ClassName = "HoloDexLuaAPI" | |
--// [Internal] [NotExposed] function HttpReqHoloAPI(url: string, method: string, apikey: string) | |
local function HttpReqHoloAPI(url: string, method: string, apikey: string) | |
assert(typeof(url) == "string" or not tostring(url), "HttpReqHoloAPI: url is not a string.") | |
assert(typeof(method) == "string" or not tostring(method), "HttpReqHoloAPI: method is not a string.") | |
assert(typeof(apikey) == "string" or not tostring(apikey), "HttpReqHoloAPI: apikey is not a string.") | |
local success, ret = false, nil | |
local tries, maxtries = 0, 3 | |
repeat | |
tries += 1 | |
success, ret = pcall(serv.HttpService.RequestAsync, serv.HttpService, { | |
Url = tostring(url); | |
Method = string.upper(tostring(method)); | |
Headers = { | |
["Content-Type"] = "application/json"; | |
["X-APIKEY"] = tostring(apikey) or ""; --// X-APIKEY, see https://holodex.stoplight.io/ | |
}; | |
}) | |
until success or tries >= maxtries | |
return success, ret | |
end | |
--// [Yields/Async] function HoloDexLuaAPI:GetChannelInformation(channelId: string) | |
function HoloDexLuaAPI:GetChannelInformation(channelId: string) | |
assert(typeof(channelId) == "string", "HoloDexLuaAPI: GetChannelInformation: invalid argument #1 to 'GetChannelInformation' (string expected, got "..typeof(channelId)..")") | |
local success, ret = HttpReqHoloAPI(string.format("https://holodex.net/api/v2/channels/%s", tostring(channelId)), "GET", self.__apikey) | |
if not success then return error("HoloDexLuaAPI: GetChannelInformation: attempt to fetch information failure, possible error code:\n"..tostring(ret), 2) end | |
return serv.HttpService:JSONDecode(ret.Body) | |
end | |
--// [Yields/Async] function HoloDexLuaAPI:GetVideoMetadata(videoId: string, commentsAllowed: boolean) | |
function HoloDexLuaAPI:GetVideoMetadata(videoId: string, commentsAllowed: boolean) | |
assert(typeof(videoId) == "string", "HoloDexLuaAPI: GetChannelInformation: invalid argument #1 to 'GetVideoMetadata' (string expected, got "..typeof(videoId)..")") | |
local success, ret = HttpReqHoloAPI(string.format("https://holodex.net/api/v2/videos/%s?c=%s", tostring(videoId), (commentsAllowed and "1") or (not commentsAllowed and "0")), "GET", self.__apikey) | |
if not success then return error("HoloDexLuaAPI: GetVideoMetadata: attempt to fetch information failure, possible error code:\n"..tostring(ret), 2) end | |
return serv.HttpService:JSONDecode(ret.Body) | |
end | |
--// [Yields/Async] function HoloDexLuaAPI:GetUpcomingsForChannels(channels: table) | |
function HoloDexLuaAPI:GetUpcomingsForChannels(channels) | |
assert(typeof(channels) == "table", "HoloDexLuaAPI: GetUpcomingsForChannels: invalid argument #1 to 'GetUpcomingsForChannels' (table expected, got "..typeof(channels)..")") | |
channels = table.concat(channels, ",") | |
local success, ret = HttpReqHoloAPI(string.format("https://holodex.net/api/v2/users/live?channels=%s", channels), "GET", self.__apikey) | |
if not success then return error("HoloDexLuaAPI: GetUpcomingsForChannels: attempt to fetch information failure, possible error code:\n"..tostring(ret), 2) end | |
return serv.HttpService:JSONDecode(ret.Body) | |
end | |
--// [Yields/Async] function HoloDexLuaAPI:GetChannelList(lang: string?, limit: number|string?, order: string, org: string, type: string) | |
function HoloDexLuaAPI:GetChannelList(lang: string?, limit: number?, order: string, org: string, type: string) | |
local targeturl = "https://holodex.net/api/v2/channels" | |
local argcount = 1 | |
local prefix = "?" | |
--// lang | |
if lang and tostring(lang) then | |
if argcount ~= 1 then prefix = "&" end | |
argcount += 1 | |
targeturl ..= prefix.."lang="..tostring(lang) | |
end | |
--// limit | |
if limit and tonumber(limit) then | |
limit = tonumber(limit) | |
if argcount ~= 1 then prefix = "&" end | |
argcount += 1 | |
if limit >= 50 then warn("HoloDexLuaAPI: GetChannelList: limit cannot be above 50, will be set to 50 (previous value was ", limit, ")") limit = 50 end | |
targeturl ..= prefix.."limit="..tostring(limit) | |
end | |
--// order | |
if order and tostring(order) then | |
if argcount ~= 1 then prefix = "&" end | |
argcount += 1 | |
targeturl ..= prefix.."order="..tostring(order) | |
end | |
--// org | |
if org and tostring(org) then | |
if argcount ~= 1 then prefix = "&" end | |
argcount += 1 | |
targeturl ..= prefix.."org="..tostring(org) | |
end | |
--// type | |
if type and tostring(type) then | |
if argcount ~= 1 then prefix = "&" end | |
argcount += 1 | |
targeturl ..= prefix.."type="..tostring(type) | |
end | |
--//print(targeturl) | |
local success, ret = HttpReqHoloAPI(targeturl, "GET", self.__apikey) | |
if not success then return error("HoloDexLuaAPI: GetChannelList: attempt to fetch channel list failure, possible error code:\n"..tostring(ret), 2) end | |
return serv.HttpService:JSONDecode(ret.Body) | |
end | |
return { | |
--// CONSTRUCTOR new(apikey: string): HoloDexLuaAPI | |
new = function(apikey: string?) | |
return setmetatable({ | |
__apikey = tostring(apikey) or ""; | |
}, HoloDexLuaAPI) | |
end, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
File name: RbxHoloDexAPI.luau | |
Author: RadiatedExodus (RealEthanPlayzDev) | |
Version: 2.0.0 | |
API wrapper for Holodex, written in Luau for usage in Roblox | |
--]] | |
--// Static configuration | |
local BASE_HOLODEXAPI_URL = "https://holodex.net/api/v2" --// The base url of the Holodex api, must NOT end with a slash | |
--// Services | |
local serv = { | |
HttpService = game:GetService("HttpService"); | |
} | |
--// Functions | |
local function CheckHttpEnabled(customurl: string?) | |
return ({pcall(serv.HttpService.GetAsync, serv.HttpService, customurl or "https://google.com")})[1] | |
end | |
local function RequestHolodexAPI(method: string, path: string, query: any, body: string?, token: string?) | |
local Query do | |
if query then | |
Query = "" | |
for name, value in pairs(query) do | |
if (typeof(value) == "table") then | |
value = table.concat(value, ",") | |
end | |
if (typeof(value) == "boolean") then | |
value = if value then "1" else "0" | |
end | |
Query ..= if (Query == "") then serv.HttpService:UrlEncode(name).."="..serv.HttpService:UrlEncode(value) else "&"..serv.HttpService:UrlEncode(name).."="..serv.HttpService:UrlEncode(value) | |
end | |
end | |
end | |
local Url = BASE_HOLODEXAPI_URL..(if (string.sub(path, 1, 1) == "/") then path else "/"..path)..(if Query then "?"..Query else "") | |
print(Url) | |
return serv.HttpService:RequestAsync({ | |
Url = Url; | |
Method = method; | |
Headers = { | |
["X-APIKEY"] = token; | |
["Content-Type"] = "application/x-www-form-urlencoded"; | |
}; | |
Body = body; | |
}) | |
end | |
--// Enums | |
local VideoExtraInfos = { | |
Clips = "clips"; | |
Refers = "refers"; | |
Sources = "sources"; | |
Simulcasts = "simulcasts"; | |
Mentions = "mentions"; | |
Description = "description"; | |
LiveInfo = "live_info"; | |
ChannelStats = "channel_stats"; | |
Songs = "songs"; | |
} | |
local Ordering = { | |
Ascending = "asc"; | |
Descending = "desc"; | |
} | |
local VideoStatus = { | |
New = "new"; | |
Upcoming = "upcoming"; | |
Live = "live"; | |
Past = "past"; | |
Missing = "missing"; | |
} | |
local VideoType = { | |
Stream = "stream"; | |
Clip = "clip"; | |
} | |
local ChannelType = { | |
Subber = "subber"; | |
Vtuber = "vtuber"; | |
} | |
local VideoSearchSort = { | |
Newest = "newest"; | |
Oldest = "oldest"; | |
} | |
local HolodexAPI = {} | |
HolodexAPI.__index = HolodexAPI | |
HolodexAPI.__tostring = function(_) return "HolodexAPI" end | |
HolodexAPI.__metatable = "This metatable is locked" | |
--// Export enums | |
HolodexAPI.VideoExtraInfos = VideoExtraInfos | |
HolodexAPI.Ordering = Ordering | |
HolodexAPI.VideoStatus = VideoStatus | |
HolodexAPI.VideoType = VideoType | |
HolodexAPI.ChannelType = ChannelType | |
HolodexAPI.VideoSearchSort = VideoSearchSort | |
--// Argument types | |
export type QueryLiveAndUpcomingVideosQuery = { | |
channel_id: string?; | |
id: string?; | |
include: {string}?; | |
lang: string?; | |
limit: number?; | |
max_upcoming_hours: number?; | |
mentioned_channel_id: string?; | |
offset: number?; | |
order: ("asc" | "desc")?; | |
org: string?; | |
sort: string?; | |
status: ("new" | "upcoming" | "live" | "past" | "missing")?; | |
topic: string?; | |
type: ("stream" | "clip")?; | |
paginated: boolean?; | |
} | |
export type QueryVideosQuery = { | |
channel_id: string?; | |
id: string?; | |
include: {string}?; | |
lang: string?; | |
limit: number?; | |
max_upcoming_hours: number?; | |
mentioned_channel_id: string?; | |
offset: number?; | |
order: ("asc" | "desc")?; | |
org: string?; | |
sort: string?; | |
status: string?; | |
topic: string?; | |
from: string?; | |
paginated: boolean?; | |
to: string?; | |
} | |
export type QueryVideosRelatedToChannelQuery = { | |
include: {string}?; | |
lang: string?; | |
limit: number?; | |
offset: number?; | |
paginated: boolean?; | |
} | |
export type ListChannelsQuery = { | |
limit: number?; | |
offset: number?; | |
type: ("subber" | "vtuber")?; | |
lang: string?; | |
order: ("asc" | "desc")?; | |
org: string?; | |
sort: string?; | |
} | |
export type VideoSearchBody = { | |
sort: "oldest" | "newest"; | |
lang: {string}?; | |
target: {"clip" | "stream"}?; | |
conditions: {string}?; | |
topic: {string}?; | |
vch: {string}?; | |
org: {string}?; | |
paginated: boolean?; | |
offset: number?; | |
limit: number?; | |
} | |
export type CommentSearchBody = { | |
sort: "oldest" | "newest"; | |
lang: {string}?; | |
target: {"clip" | "stream"}?; | |
comment: string; | |
topic: {string}?; | |
vch: {string}?; | |
org: {string}?; | |
paginated: boolean?; | |
offset: number; | |
limit: number; | |
} | |
--// Query Live and Upcoming Videos | |
--// https://holodex.stoplight.io/docs/holodex/b675902a04ca9-query-live-and-upcoming-videos | |
function HolodexAPI:QueryLiveAndUpcomingVideos(query: QueryLiveAndUpcomingVideosQuery) | |
return RequestHolodexAPI("GET", "/live", query, nil, self.Token) | |
end | |
--// Query Videos | |
--// https://holodex.stoplight.io/docs/holodex/ba328f7332280-query-videos | |
function HolodexAPI:QueryVideos(query: QueryVideosQuery) | |
return RequestHolodexAPI("GET", "/videos", query, nil, self.Token) | |
end | |
--// Get Channel Information | |
--// https://holodex.stoplight.io/docs/holodex/5dfaf299ea9fd-get-channel-information | |
function HolodexAPI:GetChannelInformation(channelid: string) | |
return RequestHolodexAPI("GET", "/channels/"..channelid, nil, nil, self.Token) | |
end | |
--// Query Videos Related to Channel | |
--// https://holodex.stoplight.io/docs/holodex/643f06b1f7e4d-query-videos-related-to-channel | |
function HolodexAPI:QueryVideosRelatedToChannel(channelid: string, type: string, query: QueryVideosRelatedToChannelQuery) | |
return RequestHolodexAPI("GET", string.format("/channels/%s/%s", channelid, type), query, nil, self.Token) | |
end | |
--// Quickly Access Live / Upcoming for a set of Channels | |
--// https://holodex.stoplight.io/docs/holodex/f1e355dc4cb79-quickly-access-live-upcoming-for-a-set-of-channels | |
function HolodexAPI:QuickAccessLiveOrUpcomingWithSetOfChannels(channels: {string}) | |
return RequestHolodexAPI("GET", "/users/live", { channels = channels }, nil, self.Token) | |
end | |
--// Get a single Video's metadata | |
--// https://holodex.stoplight.io/docs/holodex/d18465c977416-get-a-single-video-s-metadata | |
function HolodexAPI:GetVideoMetadata(videoid: string, lang: string, commenttimestamp: boolean?) | |
return RequestHolodexAPI("GET", "/videos/"..videoid, { lang = lang, c = commenttimestamp }, nil, self.Token) | |
end | |
--// List Channels | |
--// https://holodex.stoplight.io/docs/holodex/4fd0f20623a29-list-channels | |
function HolodexAPI:ListChannels(query) | |
return RequestHolodexAPI("GET", "/channels", query, nil, self.Token) | |
end | |
--// Create a Search Video Search | |
--// https://holodex.stoplight.io/docs/holodex/7ef9a63c3d44a-create-a-search-video-search | |
function HolodexAPI:SearchVideo(body: VideoSearchBody) | |
return RequestHolodexAPI("POST", "/search/videoSearch", nil, serv.HttpService:JSONEncode(body), self.Token) | |
end | |
--// Create a Search Comment Search | |
--// https://holodex.stoplight.io/docs/holodex/1485e15cbe9e2-create-a-search-comment-search | |
function HolodexAPI:SearchComment(body: CommentSearchBody) | |
return RequestHolodexAPI("POST", "/search/commentSearch", nil, serv.HttpService:JSONEncode(body), self.Token) | |
end | |
local function constructor_HolodexAPI(token: string?, bypasshttpenabledcheck: boolean?) | |
assert(if bypasshttpenabledcheck then true else CheckHttpEnabled(), "This experience does not have allow http requests enabled, turn it on via game settings to use this module.") | |
return setmetatable({ | |
Token = token; | |
}, HolodexAPI) | |
end | |
return setmetatable({ | |
--// Constructor | |
new = constructor_HolodexAPI; | |
--// Enums (also exported in HolodexAPI) | |
VideoExtraInfos = VideoExtraInfos; | |
Ordering = Ordering; | |
VideoStatus = VideoStatus; | |
VideoType = VideoType; | |
ChannelType = ChannelType; | |
VideoSearchSort = VideoSearchSort; | |
}, { __call = function(_, ...) return constructor_HolodexAPI(...) end }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment