Changing users rank in roblox group

It’ll come from the previous request, if there are pages which can still be retrieved afterwards.

I’ve updated the function to also request subsequent pages. If you get rate limited, you’ll need to yield in between requests. I haven’t tested this code, so lmk if u get errors.

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];
        
            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let membershipId = membership.path.split("/")[3];
                return membershipId;
            }
        }

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken, currentPage = newData.nextPageToken, newData.groupMemberships;
    }
};

I got an error saying ReferenceError: pageToken is not defined
at getUserMembershipId (C:\Users\jenkins\Videos\fuelsystem\index.js:47:12)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async updateRoleProcess (C:\Users\jenkins\Videos\fuelsystem\index.js:101:24)

yeah sorry i got mixed up with my variable names i updated it in the code

I got another error saying Request ok. Code 200.
TypeError: Cannot read properties of undefined (reading ‘split’)
at getUserMembershipId (C:\Users\jenkins\Videos\fuelsystem\index.js:50:44)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async updateRoleProcess (C:\Users\jenkins\Videos\fuelsystem\index.js:102:24)

It’s my first time working with paginated data in this context, so you’ll need to bare with.
I’ve tested this and it should work.

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            if (!membership.user || !membership.path) {continue;};

            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];
        
            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let membershipId = membership.path.split("/")[3];
                return membershipId;
            }
        }

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken = newData.nextPageToken;
        currentPage = newData.groupMemberships;
    }
};

I got an error saying Request ok. Code 200.
Failed to parse resource path and its identifiers - groups/7045894/memberships/undefined.

change the bottom 3 lines of code to this

let newData = await newResponse.json();
console.log(newData.nextPageToken === pageToken, newData.groupMemberships[1] == currentPage[1]);
pageToken = newData.nextPageToken;
currentPage = newData.groupMemberships;

and tell me what outputs
very odd issue.

it prints out false false
false false
false false
false false
false false
false false
Failed to parse resource path and its identifiers - groups/7045894/memberships/undefined.

That means it’s checked all the pages of users of that group and not found the user. Or, there are no more pages to check, so the iteration never starts and no users are checked.

Could you answer my earlier question of how many people are at that rank in the group? It can affect the code’s result.

In the meantime, here’s something to account for the group not having enough people for multiple pages:

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken || 1;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            if (!membership.user || !membership.path) {continue;};

            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];

            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let splitted = membership.path.split("/");
                let membershipId = splitted[splitted.length - 1];
                return membershipId;
            }
        }

        if (pageToken === 1) {
            pageToken = 0;
            continue;
        };

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken = newData.nextPageToken;
        currentPage = newData.groupMemberships;
    }
};

there none at that rank I’m trying to rank the player to

That’s fine. It’s a matter of how many are in the group itself as this affects the result of the paginated data.

how many players in my group is 306

The only thing that could be causing the issue now is incorrect data.

Here’s the full code snippet:

const apiKey = "";
const groupId = 0;
const targetRole = "Rank name";
const targetUserId = 0;

async function getGroupRoleId(targetRole) {
    //send the GET request
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/roles?maxPageSize=20`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    let data = await response.json()

    if (response.status !== 200) {
        console.log(data.message);
    }

    for (let role of data.groupRoles) {
        if (role.displayName === targetRole) {
            return Number(role.id);
        }
    }
};

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken || 1;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            if (!membership.user || !membership.path) {continue;};

            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];

            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let splitted = membership.path.split("/");
                let membershipId = splitted[splitted.length - 1];
                return membershipId;
            }
        }

        if (pageToken === 1) {
            pageToken = 0;
            continue;
        };

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken = newData.nextPageToken;
        currentPage = newData.groupMemberships;
    }
};

async function updateUserRole(targetRoleId, targetMembershipId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships/${targetMembershipId}`, {
        method: "PATCH",
        headers: {
            "Content-Type": "application/json",
            "x-api-key": apiKey
        },
        body: JSON.stringify({
            "role": `groups/${groupId}/roles/${targetRoleId}`
        })
    });

    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    } else {
        console.log("Request ok. Code 200.")
    };
};

async function updateRoleProcess(userId, roleName) {
    let roleId = await getGroupRoleId(roleName);
    let membershipId = await getUserMembershipId(userId);
    await updateUserRole(roleId, membershipId);
};

updateRoleProcess(targetUserId, targetRole).catch(error => console.log(error));

Even though you have previously said they are correct, please copy and paste the things exactly into the corresponding constants:

  • API key, as a string
  • Group ID
  • Target UserId
  • Target role name, as a string

The code itself is fine, it accounts for groups with enough members for multiple pages as well as groups with not enough members for more than one page. I have tested with both types.

If you get an error, could you also send the code around the line the error came from?

i got an error saying TypeError: fetch failed
at node:internal/deps/undici/undici:13484:13
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async getGroupRoleId (C:\Users\jenkins\Videos\fuelsystem\index.js:8:20)
at async updateRoleProcess (C:\Users\jenkins\Videos\fuelsystem\index.js:108:18) {
[cause]: Error: getaddrinfo EAI_AGAIN apis.roblox.com
at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26) {
errno: -3001,
code: ‘EAI_AGAIN’,
syscall: ‘getaddrinfo’,
hostname: ‘apis.roblox.com
}
}

C:\Users\jenkins\Videos\fuelsystem>

That looks like an internal Node.js error, unless you input one of the constants which are substituted into the URL wrong. Check your constants and try again.

ok this time i got this error again Failed to parse resource path and its identifiers - groups/7045894/memberships/undefined.

can you send your full code (minus the API key) and a link to the group?

hers the code

 const groupId = 7045894;
const targetRole = "Suspended";
const targetUserId = 7030584619;

async function getGroupRoleId(targetRole) {
    //send the GET request
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/roles?maxPageSize=20`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    let data = await response.json()

    if (response.status !== 200) {
        console.log(data.message);
    }

    for (let role of data.groupRoles) {
        if (role.displayName === targetRole) {
            return Number(role.id);
        }
    }
};

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken || 1;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            if (!membership.user || !membership.path) {continue;};

            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];

            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let splitted = membership.path.split("/");
                let membershipId = splitted[splitted.length - 1];
                return membershipId;
            }
        }

        if (pageToken === 1) {
            pageToken = 0;
            continue;
        };

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken = newData.nextPageToken;
        currentPage = newData.groupMemberships;
    }
};

async function updateUserRole(targetRoleId, targetMembershipId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships/${targetMembershipId}`, {
        method: "PATCH",
        headers: {
            "Content-Type": "application/json",
            "x-api-key": apiKey
        },
        body: JSON.stringify({
            "role": `groups/${groupId}/roles/${targetRoleId}`
        })
    });

    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    } else {
        console.log("Request ok. Code 200.")
    };
};

async function updateRoleProcess(userId, roleName) {
    let roleId = await getGroupRoleId(roleName);
    let membershipId = await getUserMembershipId(userId);
    await updateUserRole(roleId, membershipId);
};

updateRoleProcess(targetUserId, targetRole).catch(error => console.log(error));

and here’s my group link Hilton Hotel and Resort | - Roblox

try this

const groupId = 7045894;
const targetRole = "Suspended";
const targetUserId = 7030584619;

async function getGroupRoleId(targetRole) {
    //send the GET request
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/roles?maxPageSize=20`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    let data = await response.json()

    if (response.status !== 200) {
        console.log(data.message);
    }

    for (let role of data.groupRoles) {
        if (role.displayName === targetRole) {
            return Number(role.id);
        }
    }
};

async function getUserMembershipId(targetUserId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50`, {
        method: "GET",
        headers: {
            "x-api-key": apiKey
        }
    });

    console.log(response.status!==200?String(response.Status) + response.statusText:"Request ok. Code 200.");
    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    };

    let pageToken = data.nextPageToken || 1;
    let currentPage = data.groupMemberships;

    while (pageToken) {
        for (let membership of currentPage) {
            if (!membership.user || !membership.path) {continue;};

            //check to see if it's the UserId of the user we want
            let splitted = membership.user.split("/");
            let userId = splitted[splitted.length - 1];

            if (userId == targetUserId) {
                //the UserIds match! Now, return the membership ID
                let splitted = membership.path.split("/");
                let membershipId = splitted[splitted.length - 1];
                return membershipId;
            }
        }

        if (pageToken === 1) {
            pageToken = 0;
            continue;
        };

        //membership not found on this page, let's advance to the next one
        let newResponse = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships?maxPageSize=50&pageToken=${pageToken}`, {
            method: "GET",
            headers: {
                "x-api-key": apiKey
            }
        });

        if (!newResponse.ok) { //if it failed for whatever reason
            warn("Failed to retrieve subsequent pages. Error code:", newResponse.status);
            break;
        };

        let newData = await newResponse.json();
        pageToken = newData.nextPageToken || 1;
        currentPage = newData.groupMemberships;
    }
};

async function updateUserRole(targetRoleId, targetMembershipId) {
    let response = await fetch(`https://apis.roblox.com/cloud/v2/groups/${groupId}/memberships/${targetMembershipId}`, {
        method: "PATCH",
        headers: {
            "Content-Type": "application/json",
            "x-api-key": apiKey
        },
        body: JSON.stringify({
            "role": `groups/${groupId}/roles/${targetRoleId}`
        })
    });

    let data = await response.json();

    if (response.status !== 200) {
        console.log(data.message);
    } else {
        console.log("Request ok. Code 200.")
    };
};

async function updateRoleProcess(userId, roleName) {
    let roleId = await getGroupRoleId(roleName);
    let membershipId = await getUserMembershipId(userId);
    await updateUserRole(roleId, membershipId);
};

updateRoleProcess(targetUserId, targetRole).catch(error => console.log(error));

it finally works is it possible to make an application center where players can apply in it well auto rank them