Build "Sort Replies" on a cast using Neynar and OpenRanks' Global Ranking API

Sort Direct Replies in a cast for your client

This guide expects you to have already have signed up for a Neynar account and have the basics set up ready to be able to consume Neynars' APIs. If you haven't, you can go through the getting started guide here.

Step 1: Getting Details of the Cast

To gather cast information, utilize Neynar by providing a URL identifier. While we're using constants here, you can also obtain these details dynamically from feeds or other sources.

This could also be done using castHashes just change the Identifier to the cast_hash and cast type to hash

// Step 1: Getting Details of the Cast 
const castIdentifier = "https://warpcast.com/dwr.eth/0xb1e61e72"
const castType = "url"
const USER_FID = 2025

Step 2: Accessing Responses with the Neynar API

In this step, we'll establish an asynchronous function named getCastWithResponses. This function takes three parameters: castIdentifier, castType, and viewerFID, and returns the cast along with its responses in an array.

Additionally, Neynar provides a few more parameters such as reply depth and include_chronological_parent_casts. For the purposes of this guide, we'll keep these set to their default values: 1 for reply depth and false for include_chronological_parent_casts.

// Step 2: Accessing Responses with the Neynar API
async function getCastWithResponses(castIdentifier, castType, viewerFID) {
    const neynarCastResponsesBaseURL = `https://api.neynar.com/v2/farcaster/cast/conversation`
    const urlCastResponsesParams = `identifier=${castIdentifier}&type=${castType}&reply_depth=1&include_chronological_parent_casts=false&viewer_fid=${viewerFID}`
    const neynarCastResponsesURL = `${neynarCastResponsesBaseURL}?${urlCastResponsesParams}`
    const neynarCastResponsesResponse = await fetch(neynarCastResponsesURL, {
        headers: {
            'Content-Type': 'application/json',
            api_key: process.env.NEYNAR_API_KEY
          },
    })
    const castWithResponses = await neynarCastResponsesResponse.json().then(res => res.conversation);
    // console.log(castWithResponses)
    return castWithResponses
}

We invoke this function and store the results in a variable named castWithResponses. Then, we define another variable called castDirectReplies, which is an array of objects containing all the direct replies. Later, we'll utilize this castDirectReplies array to generate and store global ranks for each reply.

const castWithResponses = await getCastWithResponses(castIdentifier, castType, USER_FID)
// console.log(castWithResponses)
const castDirectReplies = castWithResponses.cast.direct_replies;
// console.log(castDirectReplies)

Step 3: Using OpenRanks APIs to find out Global Rank of the users who replied

In this step, we use OpenRanks APIs to determine the global rank of users who replied directly. We define two functions:

  1. fetchGlobalRanks: This function takes an array of FIDs and returns their corresponding global ranks. As the API can handle only up to 100 FIDs at a time, we need to batch process the FIDs.

  2. getAllGlobalRanks: This function takes an array of FIDs similar to fetchGlobalRanks, but it divides the input array into chunks of 100 elements each to comply with the API requirement. It then retrieves global ranks for each chunk and aggregates them into a single array, which is returned. Thus, getAllGlobalRanks can process an array of any number of FIDs and return the global ranks for all of them.

// Step 4: Using OpenRanks APIs to find out Global Rank of the users who replied
async function fetchGlobalRanks(fidsArray) {
    const usersGlobalRankBaseURL = 'https://graph.cast.k3l.io/scores/global/engagement/fids'
    const usersGlobalRankResponse = await fetch(usersGlobalRankBaseURL, {
        method: 'POST',
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(fidsArray)
    });
    const usersGlobalRankResponseArray = await usersGlobalRankResponse.json().then(element => element.result)
    // console.log(usersGlobalRankResponseArray);
    return usersGlobalRankResponseArray
}
async function getAllGlobalRanks(fidsArray) {
    const chunkSize = 99
    let globalRanksArray = []
    for (let i = 0; i < fidsArray.length; i += chunkSize) {
        const chunk = fidsArray.slice(i, i + chunkSize)
        const chunkedGlobalRanksArray = await fetchGlobalRanks(chunk)
        globalRanksArray = globalRanksArray.concat(chunkedGlobalRanksArray)
    }
    return globalRanksArray
}

Now that we have the two functions defined, let's create an array of FIDs based on the authors of the replies. We'll achieve this using a simple map function and store the FIDs of all repliers in a variable called fidsOfRepliers. Then, we'll pass this array as an argument to the getAllGlobalRanks function and store the returned array of global ranks in a variable called usersGlobalRankResponseArray.

const fidsOfRepliers = castDirectReplies.map(reply => reply.author.fid)
// console.log(fidsOfRepliers)
const usersGlobalRankResponseArray = await getAllGlobalRanks(fidsOfRepliers)
// console.log(usersGlobalRankResponseArray);

Step 4: Adding Global Ranks to Direct Replies

In this step, we'll create a new array called castDirectRepliesWithGlobalRank. As the name suggests, it's essentially the same array as castDirectReplies from Step 2, but with the addition of global ranks. We'll achieve this by declaring a utility function called addGlobalRank, which takes two arrays as parameters: the first array is castWithDirectReplies, and the second one is usersGlobalRankResponses. It matches the FID and adds the global rank to each object.

// Step 4: Adding Global Ranks to Direct Replies
function addGlobalRank(array1, array2) {
    array1.forEach(item1 => {
        array2.forEach(item2 => {
            if (item1.author && item1.author.fid === item2.fid) {
                item1.author.globalRank = item2.rank;
            }
        });
    });
    return array1;
}
const castDirectRepliesWithGlobalRank = addGlobalRank(castDirectReplies, usersGlobalRankResponseArray)
// console.log(castDirectRepliesWithGlobalRank)

At the conclusion of this step, we now have a variable named castDirectRepliesWithGlobalRank. This variable contains an array comprising all the direct replies to the focused cast. Additionally, each reply within this array includes the global rank of its respective author.

Step 5: Sorting Replies by Authors' Global Rank

To complete the process, we need to sort the castDirectRepliesWithGlobalRank array in ascending order based on the authors' global ranks. To achieve this, we'll define a generalized function named sortByRankAscending. This function takes an array as input and returns a sorted array in ascending order based on the authors' global rank.

// Step 5: Sorting Replies by Authors' Global Rank
function sortByRankAscending(usersArray) {
    return usersArray.sort((a, b) => a.author.globalRank - b.author.globalRank);
}
const sortedRepliesBasedOnGlobalRankingsArray = sortByRankAscending(castDirectRepliesWithGlobalRank)
// console.log(sortedRepliesBasedOnGlobalRankingsArray)

Now, you have an array sorted based on the replies' authors' global rank. This can be utilized as a method to surface relevant replies first.

Last updated

Logo

Copyright 2024