```
import requests # Import the requests library for making HTTP requests
import argparse # Import the argparse library for parsing command-line arguments
import os # Import the os library for accessing environment variables
from airstack.execute_query import AirstackClient
import asyncio
# Function to make a get request to Airstack API
async def airstack_query(query, api_key=None):
api_key = os.environ.get("AIRSTACK_API_KEY")
if api_key is None:
raise Exception("Please set the AIRSTACK_API_KEY environment variable")
api_client = AirstackClient(api_key=api_key)
execute_query_client = api_client.create_execute_query_object(query=query)
query_response = await execute_query_client.execute_query()
data = query_response.data
error = query_response.error
if query_response.error is not None:
raise Exception(error)
return data
# Function to make a GET request to the Neynar API
def get(endpoint, args, api_key=None):
url = f"https://api.neynar.com/{endpoint}" # Construct the full URL for the endpoint
params = args.copy() # Copy the arguments to avoid modifying the original dictionary
if api_key is None:
api_key = os.getenv('NEYNAR_API_KEY') # Retrieve the API key from the environment variable
if api_key is None:
raise ValueError("API key not provided")
params["api_key"] = api_key # Add the API key to the parameters
response = requests.get(url, params=params) # Make the GET request
return response.json() # Return the response as JSON
# Function to get user information by Farcaster username
def get_user(fc_username, api_key=None):
user_response = get(
"v1/farcaster/user-by-username", # Endpoint to get user by username
{
"username": fc_username, # Parameter: Farcaster username
},
api_key=api_key # Optional API key
)
if "result" not in user_response:
raise ValueError("No user found.") # Raise an error if no user is found
return user_response["result"]["user"] # Return the user information
# Function to get casts (posts) by a user with their Farcaster ID (fid)
def get_user_casts(fid, cursor='', api_key=None):
return get(
"v2/farcaster/feed", # Endpoint to get user's feed
{
"feed_type": "filter", # Filter type for the feed
"filter_type": "fids", # Filter by fids (Farcaster IDs)
"fids": fid, # Parameter: user's Farcaster ID
"with_recasts": "false", # Exclude recasts
"cursor": cursor, # Pagination cursor
},
api_key=api_key # Optional API key
)
# Function to search for channels
def get_channels(query, api_key=None):
return get(
"v2/farcaster/channel/search", # Endpoint to search channels
{
"q": query, # Search query
},
api_key=api_key # Optional API key
)
# Function to get a specific channel by query
def get_channel(query, api_key=None):
channels_response = get_channels(query, api_key) # Get channels matching the query
if len(channels_response["channels"]) == 0:
raise ValueError("No channel found.") # Raise an error if no channel is found
return channels_response["channels"][0] # Return the first matching channel
# Main function to get the last cast by a user in a specific channel
def get_last_cast_by_user(fc_username, fc_channel_name):
user = get_user(fc_username) # Get user information
fid = user["fid"] # Extract the user's Farcaster ID
channel = get_channel(fc_channel_name) # Get channel information
channel_parent_url = channel["parent_url"] # Extract the channel's parent URL
# Find the last cast by the user in the channel
found_cast = None
cursor = ''
while not found_cast:
casts_response = get_user_casts(fid, cursor=cursor) # Get user's casts
for cast in casts_response["casts"]:
if cast["parent_url"] == channel_parent_url:
found_cast = cast # Found the cast in the specified channel
cursor = casts_response["next"]["cursor"] # Update the cursor for pagination
# Print the details of the found cast
print(f'{fc_username} last casted in /{fc_channel_name} at {found_cast["timestamp"]}:')
print()
print(found_cast['text'])
print()
print('Hash:', found_cast['hash'])
print('Warpcast URL:', f'https://warpcast.com/{fc_username}/{found_cast["hash"][:8]}')
def get_last_50_unique_posters(fc_channel_name):
# channel = get_channel(fc_channel_name) # Get channel information
# channel_parent_url = channel["parent_url"] # Extract the channel's parent URL
# "https://warpcast.com/~/channel/plan"
# query taken from yosephks https://app.airstack.xyz/query/kXhn9i70Lh
# modified to escape curly braces
query = """
query MyQuery {
FarcasterCasts(
input: {
filter: {rootParentUrl: {_eq: "https://warpcast.com/~/channel/plan"}}, blockchain: ALL}
) {
Cast {
castedBy {
profileName
fid: userId
}
fid
hash
id
castedAtTimestamp
}
}
}
"""
data = asyncio.run(airstack_query(query))
fid_list = []
user_list = []
for cast_data in data['FarcasterCasts']['Cast']:
fid = cast_data['fid']
profile_name = cast_data['castedBy']['profileName']
if fid in fid_list:
continue
fid_list.append(fid)
user_list.append(profile_name)
return user_list[:50]
# Entry point of the script
if __name__ == "__main__":
# TODO: add this functionality back in later, just focused on the last 50 unique posters for now
# parser = argparse.ArgumentParser(description='Get last cast by user in channel') # Create an argument parser
# parser.add_argument('fc_username', type=str, help='Farcaster username') # Add Farcaster username argument
# parser.add_argument('fc_channel_name', type=str, nargs='?', default='plan', help='Channel name (default: plan)') # Add optional channel name argument with default value
#
# args = parser.parse_args() # Parse the command-line arguments
# get_last_cast_by_user(args.fc_username, args.fc_channel_name) # Call the main function with the parsed arguments
parser = argparse.ArgumentParser(description='Get last 50 unique posters in channel') # Create an argument parser
parser.add_argument('fc_channel_name', type=str, nargs='?', default='plan', help='Channel name (default: plan)') # Add optional channel name argument with default value
args = parser.parse_args() # Parse the command-line arguments
get_last_50_unique_posters(fc_channel_name=args.fc_channel_name)
```