Clients/Client2018/content/internal/AppShell/Modules/Shell/Http.lua

1016 lines
23 KiB
Lua

--[[
// Http.lua
// API for all web endpoints
// Calls are async
// Any calls to roblox.com need to use game:HttpGetAynsc() and game:HttpPostAynsc()
// use rbxGetAsync() and rbxPostAsync()
// Any calls to api.roblox.com should use HttpRbxApiService
// use rbxApiGetAsync() and rbxApiPostAsync()
// For calls to new services like avatar.roblox.com use game:HttpGetAsync()
// user rbxGetAsync() and rbxPostAsync()
// NOTE: You cannot currently get thumbnails with this API (please see the Thumbnail module), because
// Roblox GUIs cannot accept rbxcnd.com for the Image property.
// NOTE: game:HttpGetAsync() can no longer be used in networked DataModels.
// You may need to move endpoint call to C++ if you need to use an
// endpoint in-game
]]
local HttpService = game:GetService("HttpService")
local HttpRbxApiService = game:GetService("HttpRbxApiService")
local CoreGui = game:GetService("CoreGui")
local RobloxGui = CoreGui:FindFirstChild("RobloxGui")
local Modules = RobloxGui:FindFirstChild("Modules")
local ShellModules = Modules:FindFirstChild("Shell")
local Utility = require(ShellModules:FindFirstChild('Utility'))
local IsNewUsernameCheckEnabled = settings():GetFFlag("XboxUseNewValidUsernameCheck2")
local Http = {}
local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
BaseUrl = string.gsub(BaseUrl, "/m.", "/www.")
BaseUrl = string.gsub(BaseUrl, "http://", "https://")
local AssetGameBaseUrl = string.gsub(BaseUrl, "https://www.", "https://assetgame.")
local AccountSettingsUrl = string.gsub(BaseUrl, "https://www.", "https://accountsettings.")
Http.BaseUrl = BaseUrl
Http.AssetGameBaseUrl = AssetGameBaseUrl
-- Helper Functions
local function decodeJSON(json)
if json == nil or #json == 0 then
return nil
end
local success, result = pcall(function()
return HttpService:JSONDecode(json)
end)
if not success then
Utility.DebugLog("decodeJSON() failed because", result, "Input:", json)
return nil
end
return result
end
local function rbxGetAsync(path, returnRaw)
local success, result = pcall(function()
return game:HttpGetAsync(path)
end)
--
if not success then
Utility.DebugLog(path, "rbxGetAsync() failed because", result)
return nil
end
if returnRaw then
return result
end
return decodeJSON(result)
end
local function rbxPostAsync(path, params, contentType)
local success, result = pcall(function()
return game:HttpPostAsync(path, params, contentType)
end)
--
if not success then
Utility.DebugLog(path, "rbxPostAsync() failed because", result)
return nil
end
return decodeJSON(result)
end
local function rbxApiGetAsync(path)
local success, result = pcall(function()
return HttpRbxApiService:GetAsync(path)
end)
--
if not success then
Utility.DebugLog(path, "rbxApiGetAsync() failed because", result)
return nil
end
return decodeJSON(result)
end
local function rbxApiPostAsync(path, params, throttlePriority, contentType)
local success, result = pcall(function()
return HttpRbxApiService:PostAsync(path, params, throttlePriority, contentType)
end)
--
if not success then
Utility.DebugLog(path..params, "rbxApiPostAsync() failed because", result)
return nil
end
return decodeJSON(result)
end
local function buildServiceUrl(service)
return string.gsub(BaseUrl, "https://www.", "https://"..service..".")
end
-- Game Endpoints
--[[
Response json
[
{
"Id": 0,
"Name": "string",
"TimeOptionsAvailable": false,
"DefaultTimeOption": 0,
"GenresOptionsAvailable": true,
"NumberOfRows": 0,
"GameSetTargetId": 0
},
]
]]
function Http.GetGameSortsAsync()
return rbxGetAsync(BaseUrl.."games/default-sorts")
end
--[[
Respone json
{
"data": [
{
"CreatorID": 0,
"CreatorName": "string",
"CreatorUrl": "string",
"Plays": 0,
"Price": 0,
"ProductID": 0,
"IsOwned": false,
"IsVotingEnabled": true,
"TotalUpVotes": 0,
"TotalDownVotes": 0,
"TotalBought": 0,
"UniverseID": 0,
"HasErrorOcurred":false,
"GameDetailReferralUrl": "string",
"Url": "string",
"RetryUrl": "string",
"Final": true,
"Name": "string",
"PlaceID": 0,
"PlayerCount": 0,
"ImageId": 0,
"IsSecure": false,
"ShowExperimentalMode": false
},
]
"paging" {
"previousCursor": "string",
"previousUrl": "string",
"nextCursor": "string",
"nextUrl": "string"
}
}
]]
function Http.GetCuratedSortAsync(gameSetTargetId, maxRows)
local path = string.format("%sgames/set?GameSetTargetId=%d&MaxRows=%d", BaseUrl, gameSetTargetId, maxRows)
return rbxGetAsync(path)
end
-- the subsequent page request's maxRows depends on the first request (Http.GetCuratedSortAsync)
-- the maxRows info is included in pageUrl
-- this has the same response as Http.GetCuratedSortAsync
function Http.GetCuratedSortByUrlAsync(pageUrl)
return rbxGetAsync(pageUrl)
end
--[[
Response json
[
{
"CreatorID": 0,
"CreatorName": "string",
"CreatorUrl": "string",
"Plays": 0,
"Price": 0,
"ProductID": 0,
"IsOwned": false,
"IsVotingEnabled": true,
"TotalUpVotes": 0,
"TotalDownVotes": 0,
"TotalBought": 0,
"UniverseID": 0,
"HasErrorOcurred": false,
"GameDetailReferralUrl": "string",
"Url": "string",
"RetryUrl": "string",
"Final": true,
"Name": "string",
"PlaceID": 0,
"PlayerCount": 0,
"ImageId": 0,
"IsSecure": false,
"ShowExperimentalMode": false
},
]
]]
function Http.GetSortAsync(startRows, maxRows, sortId, timeFilter)
local path =
string.format("%sgames/list-json?sortFilter=%d&StartRows=%d&MaxRows=%d&searchAllGames=false&filterByDeviceType=true",
BaseUrl, sortId, startRows, maxRows)
if timeFilter then
path = string.format("%s&timeFilter=%d", path, timeFilter)
end
return rbxGetAsync(path)
end
-- Response, see Http.GetSortAsync
function Http.GetUserFavoritesAsync(startRows, maxRows)
local path = string.format("%sgames/moreresultsuncached-json?sortFilter=MyFavorite&StartRows=%d&"..
"MaxRows=%d&searchAllGames=true&filterByDeviceType=true",
BaseUrl, startRows, maxRows)
return rbxGetAsync(path)
end
-- Response, see Http.GetSortAsync
function Http.GetUserRecentAsync(startRows, maxRows)
local path = string.format("%sgames/moreresultsuncached-json?sortFilter=MyRecent&StartRows=%d&"..
"MaxRows=%d&searchAllGames=true&filterByDeviceType=true",
BaseUrl, startRows, maxRows)
return rbxGetAsync(path)
end
-- Response, see Http.GetSortAsync
function Http.GetUserPlacesAsync(startIndex, pageSize, userid)
local path = string.format("%sgames/list-users-games-json?userid=%d&startIndex=%d&pageSize=%d",
BaseUrl, userid, startIndex, pageSize)
return rbxGetAsync(path)
end
-- Response, see Http.GetSortAsync
function Http.SearchGamesAsync(startRows, maxRows, keyword)
local path = string.format("%sgames/list-json?keyword=%s&StartRows=%d&MaxRows=%d&filterByDeviceType=true",
BaseUrl, HttpService:UrlEncode(keyword), startRows, maxRows)
return rbxGetAsync(path)
end
--[[
Response json
{
"AssetId": 0,
"Name": "string",
"Description": "string",
"Created": "string",
"Updated": "string",
"FavoritedCount": 0,
"Url": "string",
"ReportAbuseAbsoluteUrl": "string",
"IsFavoritedByUser": false,
"IsFavoritesUnavailable": false,
"UserCanManagePlace": false,
"VisitedCount": 0,
"MaxPlayers": 8,
"Builder": "string",
"BuilderId": 0,
"BuilderAbsoluteUrl": "string",
"IsPlayable": true,
"ReasonProhibited": "string",
"ReasonProhibitedMessage": "string",
"IsBuildersClubOnly": false,
"IsCopyingAllowed": true,
"BuildersClubOverlay": "string",
"PlayButtonType": "string",
"AssetGenre": "string",
"AssetGenreViewModel": {
"DisplayName": "string",
"Id": 0
},
"OnlineCount": 0,
"UniverseId": 0,
"UniverseRootPlaceId": 0,
"TotalUpVotes": 0,
"TotalDownVotes": 0,
"UserVote": true,
"OverridesDefaultAvatar": false,
"UsePortraitMode": false,
"IsExperimental": false,
"Price": 0
}
]]
function Http.GetGameDetailsAsync(placeId)
return rbxGetAsync(BaseUrl.."places/api-get-details?assetId="..tostring(placeId))
end
--[[
Response json
{
"Id": 0,
"PlaceId": 0,
"ImageId": 0,
"IconUrl": "string",
"IconFinal": true,
"WikiUrl": "string",
"ReleaseDate": "string",
"IconUpdateSuccess": true,
"IconUpdateMessage": "string"
}
]]
function Http.GetGameIconIdAsync(placeId)
return rbxGetAsync(BaseUrl.."places/icons/json?placeId="..tostring(placeId))
end
--[[
Response json
{
"VotingModel":{
"ShowVotes": true,
"UpVotes": 0,
"DownVotes": 0,
"CanVote": false,
"UserVote": false,
"HasVoted": false,
"ReasonForNotVoteable": "string"
},
"ShowVotes": true
}
]]
function Http.GetGameVotesAsync(placeId)
return rbxGetAsync(BaseUrl.."PlaceItem/GameDetailsVotingPanelJson?placeId="..tostring(placeId))
end
--[[
Response json
[
{
"Creator":{
"CreatorName": "string",
"CreatorTargetId": 0,
"CreatorType": 0
},
"GameName": "string",
"GameSeoUrl": "string",
"GameThumbnail": {
"AssetId": 0,
"AssetHash": null,
"AssetTypeId": 0,
"Url": "string",
"IsFinal": true
},
"PlaceId": 0,
"ImageId": 0
},
]
]]
function Http.GetRecommendedGamesAsync(currentPlaceId)
return rbxGetAsync(BaseUrl.."Games/GetRecommendedGamesJson?currentPlaceId="..tostring(currentPlaceId))
end
--[[
Response json
{
"IsJpegThumbnailEnabled": true,
"PlaceId": 0,
"thumbnails": [
{
"AssetId": 0,
"AssetHash":null,
"AssetTypeId": 0,
"Url": "string",
"IsFinal": true
}
],
"thumbnailCount": 1,
"IsVideoAutoplayedOnReady": false,
"ShowYouTubeVideo": true,
"IsMobile": false,
"PlaceThumbnailsResources": {
"LabelNext": "string",
"LabelPrevious": "string",
"State": 0
}
}
]]
function Http.GetGameThumbnailsAsync(placeId)
return rbxGetAsync(BaseUrl.."thumbnail/place-thumbnails?placeId="..tostring(placeId))
end
--[[
Response json
{
"PlaceId": 0,
"GameBadges": [
{
"BadgeAssetId": 0,
"CreatorId": 0,
"IsOwned": true,
"Rarity": 0,
"RarityName": "string",
"TotalAwarded": 0,
"TotalAwardedYesterday": 0,
"Created": "string",
"Updated": "string",
"AssetSeoUrl": "string",
"Thumbnail": {
"Final": false,
"Url": "string",
"RetryUrl": "string",
"UserId": 0,
"EndpointType": "string"
},
"Name": "string",
"FormatName": "string",
"Description": "string",
"AssetRestrictionIcon": null
},
],
"GameBadgesResources": {
"HeadingGameBadges":"Game Badges",
"LabelRarityCakeWalk":"Cake Walk",
"LabelRarityChallenging":"Challenging",
"LabelRarityEasy":"Easy",
"LabelRarityExtreme":"Extreme",
"LabelRarityFreebie":"Freebie",
"LabelRarityHard":"Hard",
"LabelRarityImpossible":"Impossible",
"LabelRarityInsane":"Insane",
"LabelRarityModerate":"Moderate",
"LabelRarity":"Rarity",
"LabelSeeMore":"See More",
"LabelWonEver":"Won Ever",
"LabelWonYesterday":"Won Yesterday",
"State":0
}
}
]]
-- TODO: Remove with FFlagXboxUpdateBadgeEndpoints
function Http.GetGameBadgeDataAsync(placeId)
return rbxGetAsync(BaseUrl.."badges/list-badges-for-place/json?placeId="..tostring(placeId))
end
--[[
Response json
{
"previousPageCursor": "string",
"nextPageCursor": "string",
"data": [
{
"id": 0,
"name": "string",
"description": "string",
"enabled": true,
"iconImageId": 0,
"created": "2018-07-05T17:45:05.868Z",
"updated": "2018-07-05T17:45:05.868Z",
"statistics": {
"pastDayAwardedCount": 0,
"awardedCount": 0,
"winRatePercentage": 0
},
"awardingUniverse": {
"id": 0,
"name": "string",
"rootPlaceId": 0
}
}
]
}
]]
function Http.GetBadgesForUniverseAsync(universeId, cursor)
local url = string.format("%sv1/universes/%d/badges?sortOrder=Asc&limit=100", buildServiceUrl("badges"), universeId)
if cursor then
url = string.format(url.."&cursor=%s", cursor)
end
return rbxGetAsync(url)
end
--[[
Response json
{
"data": [
{
"badgeId": 0,
"awardedDate": "2018-07-05T17:52:25.648Z"
}
]
}
]]
function Http.GetUserAwardedBadgesAsync(userId, badgeIdsTable)
local badgeIds = table.concat(badgeIdsTable, ",")
local url = string.format("%sv1/users/%d/badges/awarded-dates?badgeIds=%s", buildServiceUrl("badges"), userId, badgeIds)
return rbxGetAsync(url)
end
--[[
Response json
{
"success": true,
"message": "string"
}
]]
function Http.PostFavoriteToggleAsync(assetId)
return rbxPostAsync(BaseUrl.."favorite/toggle?assetID="..tostring(assetId), "favoriteToggle")
end
--[[
Response json
{
"Success": true,
"Message": "string",
"ModalType": "string",
"Model": {
"ShowVotes": true,
"UpVotes": 0,
"DownVotes": 0,
"CanVote": true,
"UserVote": true,
"HasVoted": false,
"ReasonForNotVoteable": "string"
}
}
]]
function Http.PostGameVoteAsync(assetId, status)
return rbxPostAsync(BaseUrl.."voting/vote?assetId="..tostring(assetId).."&vote="..tostring(status), "vote")
end
-- Social
--[[
Response json - none
]]
function Http.RegisterAppPresence()
return rbxApiPostAsync("presence/register-app-presence", "",
Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationJson)
end
--[[
Response json
{
"userId": 0,
"isEnabled": true,
"created": "string",
"updated": "string"
}
]]
function Http.GetCrossplayEnabledStatusAsync()
return rbxApiGetAsync("user/CrossPlayStatus")
end
--[[
Response json
{
"success": true
}
]]
function Http.PostCrossplayStatusAsync(value)
return rbxApiPostAsync("user/CrossPlayStatus?isEnabled="..tostring(value), "")
end
--[[
Response json
{
{
"VisitorId": 0,
"GameId": "string",
"IsOnline": true,
"LastOnline": "string",
"LastLocation": "string",
"LocationType": 0,
"PlaceId": 0,
"UserName": "string"
},
}
]]
function Http.GetOnlineFriendsAsync()
return rbxApiGetAsync("my/friendsonline")
end
--[[
Response json
{
"recommendedUsers": [
{
"userId": 0,
"userName": "string",
"userProfilePageUrl": "string",
"userPresenceType": "Offline"
}
]
}
]]
--Only get used in studio mode
function Http.GetRecommendedUsersndsAsync()
local url = string.format("%s/v1/recommended-users", buildServiceUrl("friends"))
return rbxGetAsync(url)
end
--[[
Response json
{
"userPresences": [
{
"userPresenceType": "Offline",
"lastLocation": "string",
"placeId": 0,
"rootPlaceId": 0,
"gameId": "string",
"userId": 0,
"lastOnline": "2018-05-07T22:18:08.290Z"
}
]
}
]]
--Only get used in studio mode
function Http.GetUsersPresenceAsync(userIds)
local userIdsModel = {
userIds = userIds,
}
userIdsModel = HttpService:JSONEncode(userIdsModel)
local url = string.format("%s/v1/presence/users", buildServiceUrl("presence"))
return rbxPostAsync(url, userIdsModel)
end
-- Account
--[[
Response json
{
"Robux": 0
}
]]
function Http.GetPlatformUserBalanceAsync()
return rbxApiGetAsync("my/platform-currency-budget")
end
--[[
Response json
{
"robux": 0
}
]]
function Http.GetTotalUserBalanceAsync()
return rbxApiGetAsync("currency/balance")
end
--[[
Response json
{
"IsValid": true
"Data": {
"TotalItems": null,
"Start": 0,
"End": 0,
"Page": 0,
"nextPageCursor": "string",
"previousPageCursor": "string",
"ItemsPerPage":0 ,
"PageType": "string",
"Items": [
{
"AssetRestrictionIcon": {
"TooltipText": "string",
"CssTag": "string",
"LoadAssetRestrictionIconCss": true,
"HasTooltip": false
},
"Item":{
"AssetId": 0,
"Name": "string",
"AbsoluteUrl": "string",
"AssetType": 0,
"AssetTypeFriendlyLabel": "string",
"Description": "string",
"Genres": "string",
"GearAttributes": "string",
"AssetCategory": 0,
"CurrentVersionId": 0,
"IsApproved": false,
"LastUpdated": "string",
"LastUpdatedBy": "string",
"AudioUrl": "string"
},
"Creator":{
"Id": 1,
"Name": "string",
"Type": 1,
"CreatorProfileLink": "string"
},
"Product":{
"Id": 0,
"PriceInRobux": 0,
"IsForSale": false,
"IsPublicDomain": true,
"IsResellable": false,
"IsLimited": false,
"IsLimitedUnique": false,
"SerialNumber": 0,
"IsRental": false,
"RentalDurationInHours": 0,
"BcRequirement": 0,
"TotalPrivateSales": 0,
"SellerId": 0,
"SellerName": "string",
"LowestPrivateSaleUserAssetId": 0,
"IsXboxExclusiveItem": false,
"OffsaleDeadline": "string",
"NoPriceText": "string",
"IsFree": true
},
"PrivateServer": false,
"Thumbnail": {
"Final": true,
"Url": "string",
"RetryUrl": "string",
"IsApproved": false
},
"UserItem":{
"UserAsset": 0,
"IsItemOwned": false,
"ItemOwnedCount": 0,
"IsRentalExpired": false,
"IsItemCurrentlyRented": false,
"CanUserBuyItem": false,
"RentalExpireTime": "string",
"CanUserRentItem": false
}
}
]
}
}
]]
function Http.GetUserOwnedPackagesAsync(userId, currentPage)
currentPage = currentPage or 1
local packageAssetIdType = 32
return rbxGetAsync(BaseUrl.."users/inventory/list-json?userId="..tostring(userId)..
"&assetTypeId="..tostring(packageAssetIdType).."&pageNumber="..tostring(currentPage))
end
--[[
Response json
{
"assetIds": [
0
]
}
]]
function Http.GetCurrentlyWearingAsync(userId)
local url = string.format("%s/v1/users/%d/currently-wearing",
buildServiceUrl("avatar"), userId)
return rbxGetAsync(url)
end
-- Avatar/Inventory
--[[
Response json
{
"assetIds:" [
0
]
}
]]
function Http.GetPackageAssetsAsync(packageId)
local url = string.format("%s/v1/packages/%d/assets", buildServiceUrl("inventory"), packageId)
return rbxGetAsync(url)
end
--[[
Respone json
{
"invalidAssets": [
{
"id": 0,
"name": "string",
"assetType": {
"id": 0,
"name": "string"
}
}
],
"invalidAssetIds": [
0,
],
"success": true
}
]]
function Http.SetWearingAssetsAsync(assetIds)
local assetIdsModel = {
assetIds = assetIds,
}
assetIdsModel = HttpService:JSONEncode(assetIdsModel)
local url = string.format("%s/v1/avatar/set-wearing-assets", buildServiceUrl("avatar"))
return rbxPostAsync(url, assetIdsModel)
end
--[[
Response json
{
"sl_translate": "string",
"AssetID": 0,
"AssetName": "string",
"AssetType": "string",
"AssetIsWearable": true,
"SellerName": "string",
"TransactionVerb": "string",
"Price": 0,
"Currency": 0,
"IsMultiPrivateSale": false
}
]]
function Http.PurchaseProductAsync(productId, expectedPrice, expectedSellerId, expectedCurrency)
local formattedUrl = string.format("%sAPI/Item.ashx?rqtype=purchase&productID=%d&expectedCurrency="..
"%d&expectedPrice=%d&expectedSellerID=%d",
BaseUrl, productId, expectedCurrency, expectedPrice, expectedSellerId)
return rbxPostAsync(formattedUrl, "")
end
--[[
Response json
{
"Products": [
{
"TargetId": 0,
"ProductType": "string",
"AssetId": 0,
"ProductId": 0,
"Name": "string",
"Description": "string",
"AssetTypeId": 0,
"Creator": {
"Id": 0,
"Name": "string",
"CreatorType": "string",
"CreatorTargetId": 0
},
"IconImageAssetId": 0,
"Created": "string",
"Updated": "string",
"PriceInRobux": 0,
"PriceInTickets": null,
"Sales": 0,
"IsNew": false,
"IsForSale": true,
"IsPublicDomain": false,
"IsLimited": false,
"IsLimitedUnique": false,
"Remaining": 0,
"MinimumMembershipLevel": 0,
"ContentRatingTypeId": 0
},
]
}
]]
function Http.GetXboxProductsAsync(startIndex, count)
startIndex = startIndex or 0
count = count or 100
local url = string.format("xbox/catalog/contents?startIndex=%d&count=%d", startIndex, count)
return rbxApiGetAsync(url)
end
--[[
Response - redirects to the cdn url; game engine takes care of this
]]
function Http.GetThumbnailUrlForAsset(assetId, width, height)
width = width or 420
height = height or 420
return AssetGameBaseUrl.."Thumbs/Asset.ashx?width="..tostring(width).."&height="..tostring(height)..
"&assetId="..tostring(assetId)
end
--[[
Response json
{
"Url": "string",
"Final": true,
"SubstitutionType": 0
}
]]
function Http.GetAssetThumbnailFinalAsync(assetId, width, height, format)
return rbxGetAsync(AssetGameBaseUrl.."asset-thumbnail/json?assetId="..tostring(assetId).."&width="..tostring(width)..
"&height="..tostring(height).."&format="..format)
end
--[[
Response json
{
"Url": "string",
"Final": true,
"SubstitutionType": 0
}
]]
function Http.GetAssetAvatarFinalAsync(userId, width, height, format)
local result = rbxGetAsync(BaseUrl..'avatar-thumbnail/json?userId='..tostring(userId)..'&width='..tostring(width)..
'&height='..tostring(height)..'&format='..format)
return result
end
--[[
]]
function Http.GetOutfitThumbnailFinalAsync(outfitId, width, height, format)
local requestData = {["userOutfitId"] = outfitId}
local requestDataJson = HttpService:JSONEncode(requestData)
local encodedRequestData = requestDataJson and HttpService:UrlEncode(requestDataJson) or ""
local url = string.format("%savatar-thumbnails?params=%s", BaseUrl, encodedRequestData)
local result = rbxGetAsync(url)
return result
end
--[[
Response json - none
]]
function Http.ReportAbuseAsync(reportingItemTypeName, reportingItemId, reportCategoryId, comment)
local jsonPostBody = {
reportingItemTypeName = reportingItemTypeName;
reportingItemId = tostring(reportingItemId);
reportCategoryId = tostring(reportCategoryId);
comment = comment;
}
local params = HttpService:JSONEncode(jsonPostBody)
if params then
return rbxApiPostAsync("moderation/reportabuse", params,
Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationJson)
end
end
-- Achievements
--[[
Response json
{
"count": 1
}
]]
function Http.GetConsecutiveDaysLoggedInAsync()
local url = string.format("/xbox/get-login-consecutive-days")
return rbxApiGetAsync(url)
end
--[[
Response json
{
"UserId": 0,
"TargetType": "string",
"PlatformTypeId": 0,
"VoteCount": 0
}
]]
function Http.GetVoteCountAsync()
local url = string.format("/user/get-vote-count?targetType=Place")
return rbxApiGetAsync(url)
end
-- Account Linking
--[[
Response - TODO
]]
function Http.IsValidUsername(username)
if not username then
return
end
if IsNewUsernameCheckEnabled then
local url = string.format("%sv1/xbox/is-username-valid?username=%s",
AccountSettingsUrl, HttpService:UrlEncode(username))
return rbxGetAsync(url)
else
local url = string.format("signup/is-username-valid?username=%s", HttpService:UrlEncode(username))
return rbxApiGetAsync(url)
end
end
--[[
Response json
{
"IsValid": true,
"ErrorCode": 0,
"ErrorMessage": "string"
}
]]
function Http.IsValidPassword(username, password)
if not username or not password then
return
end
local url = string.format("signup/is-password-valid?username=%s&password=%s",
HttpService:UrlEncode(username), HttpService:UrlEncode(password))
return rbxApiGetAsync(url)
end
return Http