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