Roblox Friends API Tutorial

UPDATE 05/12/24

Roproxy can be a bit unpredictable and some functions I made with it in the past no longer work. I had to do a complete refresh to get them working again.

Hi again developers!, Welcome to this new part of API tutorials!, this time I’ll explain some functions and endpoints related to friends, invites, and followers

Itinerary:

  • Check friendship between players
  • Player friend online status
  • Follower and Friends Count
  • Check if a player is following another player

Lets Start!

IsFriendsWith(): Player is friend with another
The parameter is the UserId of a player [we’ll see if the joined player is his friend]

player:IsFriendWith(UserId: number)

--Server
game.Players.PlayerAdded:Connect(function(player)
	if player:IsFriendsWith(1) then -- Is he friend of Roblox? No way!
		print(player.Name .. " is friend with Roblox!")
	end
end)

We can also do this in the client using game.Players.LocalPlayer
.

Players:GetFriendAsync(): Get the player’s amount of friends and the name of each one.
Parameter is the player UserId from which we are getting this data.

Players:GetFriendAsync(UserId: number)

--Local
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local friendPages = Players:GetFriendsAsync(player.UserId)
local usernames = {} -- We are gonna storage the data here

local function iterPageItems(pages)
	return coroutine.wrap(function() -- We don't wanna delay the script
		local pagenum = 1
		
		while true do
			for _, item in ipairs(pages:GetCurrentPage()) do
				coroutine.yield(item, pagenum)
			end
			if pages.IsFinished then
				break
			end
			pages:AdvanceToNextPageAsync()
			pagenum = pagenum + 1
		end
	end)
end

for item, pageNo in iterPageItems(friendPages) do
	table.insert(usernames, item.Username)
end
-- In this case, I'm getting the username of the friends but you can get more data:
-- item.DisplayName: string (DisplayName of the friends)
-- item.IsOnline: boolean (true or false, the friend is online)
-- item.Username: string


print(usernames) -- Username of each friend
print(#usernames) --Number of Friends

.
player:GetFriendsOnline(): This is a quick method to get ONLINE friends only.
Parameter is the maximum of online friends we are getting, default: 200
player:IsFriendWith(MaxAmount: number)

--Local
local onlineFriends = player:GetFriendsOnline()

local DictStatus = { -- A dictionary that I made
	[0] = "is online on mobile",
	[1] = "is playing on mobile",
	[2] = "is online",
	[3] = "is on Roblox studio",
	[4] = "is playing a game",
	[5] = "is on Xbox",
	[6] = "is on TeamCreate"
}

for i, friend in pairs(onlineFriends) do
	print(friend.UserName, DictStatus[friend.LocationType], "| seen at: "..friend.LastLocation)
	
	-- More data you can get:
	-- friend.VisitorId: number (Their UserId)
	-- friend.DisplayName: string (Show DisplayName instead of Username)
	
	if friend.PlaceId then -- Game Location
		warn(friend.UserName.." played at: "..friend.PlaceId)
	end
end

.

Social Service and Invites

Prompt the Invite UI to a player: This is generally used to reward players for inviting their friends.

--LocalScript inside button
local SocialService = game:GetService("SocialService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local button = script.Parent

button.MouseButton1Click:Connect(function()
	local canInvite = SocialService:CanSendGameInviteAsync(player)
	if canInvite then --check if the function is possible
		SocialService:PromptGameInvite(player) --prompt
	end
end)

.

Invite a specific player: Remember GetFriendsOnline? We can use this to occasionally send prompts to the player to invite one of their friends who is online.

--Local
local Players = game:GetService("Players")
local SocialService = game:GetService("SocialService")
local player = Players.LocalPlayer

-- you can loop this to be checking online friends
local OnlineFriends = player:GetFriendsOnline()
if #OnlineFriends ~= 0 then
	local randomFriend = OnlineFriends[math.random(1, #OnlineFriends)]
	
	local options = Instance.new("ExperienceInviteOptions")
	options.PromptMessage = "Invite "..randomFriend.UserName.." to this amazing game?"
	options.InviteUser = randomFriend.VisitorId -- Specific invite sending
	
	if SocialService:CanSendGameInviteAsync(player, randomFriend.VisitorId) then
		SocialService:PromptGameInvite(player, options)
	end
end

.
Rewarding a player for inviting: Adding this one is pretty tough since it’s prone to be abused by players and also the fact that FollowUserId may fail sometimes.

The invite prompt with SocialService is optional. This checks if a player has joined another (without needing an invitation).

--Server
game.Players.PlayerAdded:Connect(function(player)
	for index, plr in pairs(game.Players:GetPlayers()) do
		if player.FollowUserId == plr.UserId then
			-- Reward plr
		end
	end
end)

As said before, this is without any invitation so it’s not viable. Also you should add some Datastore for rewards to avoid abuse and infinite reward bugs
.

Warning:

From here on we are going to need HttpService which means: we need to activate the API and some permissions, all of the below functions wont work without the following requirements

.
Roproxy wont only help us for this, but will be our travel companion to all Roblox endpoints, since roblox doesnt allow access to them.

Some endpoints arent ‘GET’ method, Roproxy cannot get out of that limit so I will only explain some of these.

Get Player Follower count:

--Server
local HttpService = game:GetService("HttpService")

local UserId = 1
local Table = "https://friends.roproxy.com/v1/users/"..UserId.."/followers/count"
local response = HttpService:RequestAsync({
	Url = Table,
	Method = "GET"
});
if response.Success then
	local TableBody = HttpService:JSONDecode(response.Body)
	print("Player has "..TableBody.count.." followers")
end

.
Check if player is following another’s profile: Probably the section with the most topics talking about it.

local HttpService = game:GetService("HttpService")

local FollowerId = 5713770001
local FollowedId = 1

function PlayerisFollowing(Follower: number, BeingFollowed: number, cursor: string)
	if cursor == nil then cursor = "" end
	
	local Str = "http://friends.roproxy.com/v1/users/"..Follower.."/followings?&cursor="..cursor.."&sortOrder=Asc&limit=100"
	local response = HttpService:RequestAsync({
		Url = Str,
		Method = "GET"
	})
	
	if response.Success then
		local Body = HttpService:JSONDecode(response.Body)
		local nextPageCursor = Body.nextPageCursor
		
		for index, v in pairs(Body.data) do
			if v.id == BeingFollowed then
				return true
			end
		end
		
		if nextPageCursor ~= nil then
			PlayerisFollowing(Follower, BeingFollowed, nextPageCursor)
		end
	end
	return false
end

PlayerisFollowing(FollowerId, FollowedId)

Anything extra you want to see about the Friends API can be found here. Ive made some more tutorials on specific APIs, feel free to explore

Thank you for supporting these tutorials, bye!

51 Likes

what does the “Followed” and “Follower” do? what do I put there?

Hello! Thank you for trusting this topic despite its age

As the name indicates:
“Follower” means the person who follows “Followed”

In the script we have Roblox (1) as “Followed”, and since the “Follower” (1159951169) is following him, the script will print. Its used to verify if a person follows another

You only have to put the UserId player property in both cases; Ex: Roblox = 1

Update: This is the most meaningless explanation I’ve ever seen, by this I meant follow the PROFILES, not following someone in-game or something like that.

1 Like

Thank you for the the reply! I thought it did something completely different.

Hate to ask, but has anyone figured out a more reliable approach to a player following another individual? The only thing I can think of is just using pcalls.

how to make i make it so that i can prompt the user a button, once clicked they are automatically following eachother

roproxy wont refresh the following

having the same issue! would look forward to a solution…

Hi! I had to update the entire topic cuz a lot of things didn’t work. I also updated the code for that (it took a while because I forgot how “nextpageCursor” worked).

It’s already tested, it should work now:

local HttpService = game:GetService("HttpService")

local FollowerId = 5713770001 -- Random player following him
local FollowedId = 1 -- Roblox

function PlayerisFollowing(Follower: number, BeingFollowed: number, cursor: string)
	if cursor == nil then cursor = "" end
	
	local Str = "http://friends.roproxy.com/v1/users/"..Follower.."/followings?&cursor="..cursor.."&sortOrder=Asc&limit=100"
	local response = HttpService:RequestAsync({
		Url = Str,
		Method = "GET"
	})
	
	if response.Success then
		local Body = HttpService:JSONDecode(response.Body)
		local nextPageCursor = Body.nextPageCursor
		
		for index, v in pairs(Body.data) do
			if v.id == BeingFollowed then
				return true
			end
		end
		
		if nextPageCursor ~= nil then
			PlayerisFollowing(Follower, BeingFollowed, nextPageCursor)
		end
	end
	return false
end

PlayerisFollowing(FollowerId, FollowedId)

Nice resource!

This is a bit off-topic but I’m just wondering how did you make these text boxes. Is it something to do with embeds? It looks really clean!

<kbd>message</kbd>

itll look like this when done correctly

you’re welcome

1 Like