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
# 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
# Function to get the last 50 unique posters in a channel
def get_last_50_unique_posters(channel_name, api_key=None):
channel = get_channel(channel_name, api_key) # Get channel information
channel_parent_url = channel["parent_url"] # Extract the channel's parent URL
unique_posters = set()
cursor = ''
while len(unique_posters) < 50:
casts_response = get(
"v2/farcaster/feed", # Endpoint to get the channel's feed
{
"feed_type": "channel", # Feed type for channel
"channel_url": channel_parent_url, # Channel's parent URL
"cursor": cursor, # Pagination cursor
},
api_key=api_key # Optional API key
)
for cast in casts_response["casts"]:
unique_posters.add(cast["author"]["username"])
if len(unique_posters) == 50:
break
cursor = casts_response["next"]["cursor"] # Update the cursor for pagination
return list(unique_posters) # Return the list of unique posters
# Main function to get the last cast by a user in a specific channel or list the last 50 unique posters in /plan
def main(fc_username=None, fc_channel_name='plan'):
api_key = os.getenv('NEYNAR_API_KEY')
if fc_username:
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, api_key=api_key) # 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]}')
else:
unique_posters = get_last_50_unique_posters(fc_channel_name, api_key=api_key)
print(f'Last 50 unique people who posted in /{fc_channel_name}:')
for poster in unique_posters:
print(poster)
# Entry point of the script
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Get last cast by user in channel or list last 50 unique posters in /plan') # Create an argument parser
parser.add_argument('fc_username', type=str, nargs='?', default=None, help='Farcaster username (optional)') # Add optional 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
main(args.fc_username, args.fc_channel_name) # Call the main function with the parsed arguments