# Build Channel Trending Feeds for your Client using Neynar and OpenRank APIs

{% hint style="warning" %}
Channel rankings are live for top 100 popular channels based on this [dune query,](https://dune.com/queries/3422001/5745837) by 14th June, we'll support 500 channels. Here's a [sheet](https://docs.google.com/spreadsheets/d/1Hgv4hV0O0OgQ99Xx7NlHHF1DeRUgqTHPEtwEdm6CELs/edit#gid=0) with all the channels supported.
{% endhint %}

Developers can utilize the channel trending endpoints to seamlessly integrate with Neynar and promptly set up a channel feed. The current channel feed uses **channel rankings with moderators as seed peers** to identify relevant casts based on the interactions of the channel's top-ranked profiles.

Here's a simple guide demonstrating how you can use the Channel Trending Feed API alongside Neynar's API to create a channel trending feed for your clients. If you have previously gone through the "For You" guide, this process will be quite similar.

{% hint style="info" %}
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](https://docs.neynar.com/docs/getting-started-with-neynar) guide here.
{% endhint %}

### Step 1: Getting the channel

The primary required parameter for the OpenRanks API is the channel name. In this example, we are using a static string, but this can be customized according to the client developer's preference.

```javascript
const channelName = 'degen';
```

### Step 2: Retrieving Trending Cast Hashes for the Channel

In this step, we will create a function called `getChannelTrendingCastHashes`, which takes the following parameters: `channelName`, `agg`, `weights`, `offset`, `limit`, and `lite`. This function returns an array of cast hashes for the specified channel, sorted based on their trendiness.

Let's look at each of these parameters:

* **channelName**: The name of the channel.
* **agg**: The aggregation function used to determine how the weights should be aggregated. In simpler terms, it defines how the weights are amplified.
* **weights**: Specifies the importance given to each action on the cast (like, cast, recast, reply).
* **offset**: Used for pagination, indicating the number of casts to skip.
* **limit**: Used for pagination, specifying the number of casts to fetch.
* **lite**: A boolean parameter that, when set to true, reduces the payload to only return hashes instead of hashes and additional information.

To understand how the weights and agg parameters affect the feed, read [here](https://docs.openrank.com/integrations/farcaster/build-for-you-feeds-for-your-client-using-neynar-and-openrank#configuring-the-feed).

```javascript
async function getChannelTrendingCastHashes(channelName = 'degen', agg = 'sumsquare', weights = 'L1C10R5Y1', offset = 0, limit = 25, lite = true) {
  const openRankBaseURL = `https://graph.cast.k3l.io/channels/casts/popular/${channelName}`
  const channelTrendingCastHashesParams = `agg=${agg}&weights=${weights}&offset=${offset}&limit=${limit}&lite=${lite}`
  const channelTrendingCastHashesUrl = `${openRankBaseURL}?${channelTrendingCastHashesParams}`;
  const channelTrendingCastHashesResponse = await fetch(channelTrendingCastHashesUrl, {
    headers: {
      'Content-Type': 'application/json',
    },
  });
  return channelTrendingCastHashesResponse.json().then(response => response.result);
}
const channelTrendingCastHashesArray = await getChannelTrendingCastHashes();
console.log(channelTrendingCastHashesArray); // logs information about the cast hashes in ranked in order of recommendation
```

### Step 3: Using Neynar to retrieve cast data:

In the previous step, we successfully retrieved all the cast hashes in the order of their recommendation. Now, in this step, we will transform the response from the previous step and connect to the Neynar API to obtain the cast information for each of the hashes. Neynar offers a convenient API endpoint where you can pass an array of cast hashes and receive detailed information for each cast in the response.

We will create another function that takes an array of cast hashes as a parameter and returns an array of casts with all the necessary information to generate the feed. The `transformedCastHashesArray` variable will simply extract the hash values from the `channelTrendingCastHashesArray`.

```javascript
// Step 3: Integrating with Neynar to fetch the contents for these casts Hashes
const transformedCastHashesArray = channelTrendingCastHashesArray.map(element => element.cast_hash).join(',');
async function getChannelTrendingFeed(castHashesArray = []) {
  // https://docs.neynar.com/reference/casts
  const neynarBaseURL = 'https://api.neynar.com/v2/farcaster/casts'
  const neynarCastsURL = `${neynarBaseURL}?casts=${castHashesArray}`;
  const feedResponse = await fetch(neynarCastsURL, {
      headers: {
        'Content-Type': 'application/json',
        api_key: process.env.NEYNAR_API_KEY
      },
  });
  const feed = await feedResponse.json().then(response => response.result.casts);
  console.log(feed) // logs the feed which is an array in order of all casts

  return feed;
}

const channelTrendingFeed = await getChannelTrendingFeed(transformedCastHashesArray);
console.log(channelTrendingFeed); // logs the feed which is an array in order of all casts
```

### Enabling Paginating:

To build a client with infinite scrolling, you need to implement pagination. The `channelTrendingCastHashesUrl` already supports two parameters: `offset` (the number of casts to skip) and `limit` (the number of casts to fetch each time). These parameters are essential for generating a paginated feed.

Here’s how to enable pagination:

1. **Add Variables**: Declare a `page` variable outside the `paginatedFeed` function. This variable will represent the page number. Also, declare a `castsPerPage` variable to define the number of casts per page and an `offset` variable to track the number of casts to skip.
2. **Function Modification**: Enclose the function calls to `getChannelTrendingCastHashes()` and `getChannelTrendingFeed()` inside the `paginatedFeed()` function. This function should take `page` and `channelName` as parameters and return the paginated feed.

Here's a revised version of the code:

```javascript
let page = 1;
const channel = 'degen';
const castsInPage = await paginatedFeed(page, channel)
```

```javascript
async function paginatedFeed(page, channel) {

    const castsPerPage = 25;
    const offset = page * castsPerPage;

    // Step 1: Getting The Users FID
    const channelName = channel;

    // Step 2: Getting the ranked casts hashes for creating the Personalized For You Feed
    const channelTrendingCastHashesArray = await getChannelTrendingCastHashes(channel, 'sumsquare', 'L1C10R5Y1', offset, castsPerPage, true);
    console.log(channelTrendingCastHashesArray); // logs information about the cast hashes in ranked in order of recommendation
    const transformedCastHashesArray = channelTrendingCastHashesArray.map(element => element.cast_hash).join(',');

    // Step 3: Integrating with Neynar to fetch the contents for these casts Hashes
    const channelTrendingFeed = await getChannelTrendingFeed(transformedCastHashesArray);
    return channelTrendingFeed;
}
```

With this setup, the feed is paginated based on the page number and the number of casts per page. Calling `paginatedFeed(page, channelName)` with the appropriate parameters will return the desired paginated feed.

### Configuring the feed:

You can currently use the aggregation (`agg`) parameter and the `weights` parameter to change how the feed is generated. A detailed explanation of this process can be found [here](https://docs.openrank.com/integrations/farcaster/build-for-you-feeds-for-your-client-using-neynar-and-openrank#configuring-the-feed).
