Skip to main content

A discord.py-self-like library for pump.fun selfbot development

Project description

Usage

Features

  • Event-driven architecture with familiar decorator syntax
  • Automatic username detection from auth tokens
  • Message and reply handling with content moderation warnings
  • Built-in user banning functionality with messageId tracking
  • Automatic moderator permission detection
  • Built-in reconnection logic and error handling
  • Lightweight with minimal logging
  • Full async/await support
  • Structured data models for messages, users, and rooms

Quick Start

import asyncio
from pump_self_melon import Client

async def main():
    client = Client(token="your_auth_token")
    
    @client.event
    async def on_ready():
        print("Bot is ready!")
    
    @client.event
    async def on_message(message):
        print(f"{message.author.username}: {message.content}")
        
        if message.content.lower() == "ping":
            await client.send_message("pong!")
        
        elif message.content.lower() == "hello":
            await client.send_message(f"Hello {message.author.username}!")
    
    await client.start("room_id_here")

if __name__ == "__main__":
    asyncio.run(main())

Core Components

Client

The main client class handles websocket connections and event management.

from pump_self_melon import Client

client = Client(token="your_auth_token")

Optional parameters:

  • websocket_uri: Custom websocket URI (defaults to pump.fun chat)

Event Decorators

@client.event

Decorator for event handlers. Function name determines the event type:

@client.event
async def on_message(message):
    # Handle incoming messages
    pass

@client.event
async def on_ready():
    # Called when bot connects and authenticates
    pass

@client.event
async def on_join(room, user):
    # Called when joining a room
    pass

@client.event
async def on_error(error):
    # Handle errors
    pass

@client.listen()

Alternative event listener syntax:

@client.listen('message')
async def handle_message(message):
    # Handle messages
    pass

Sending Messages

send_message()

Send a regular message to the chat:

await client.send_message("Hello world!")
await client.send_message("Message", room_id="specific_room")

send_reply()

Send a reply to a specific message (includes reply context):

@client.event
async def on_message(message):
    if message.content == "reply to me":
        await client.send_reply(message, "This is a reply!")

Note: Regular messages (send_message) are less likely to be flagged by content moderation than replies (send_reply).

Data Models

Message

Represents a chat message:

message.id          # Message ID
message.content     # Message text
message.author      # User object
message.room        # Room object  
message.timestamp   # Datetime object
message.raw_data    # Original message data

User

Represents a user:

user.username       # Display name
user.address        # Wallet address

Room

Represents a chat room:

room.id             # Room identifier

Banning and Moderation

Enabling Banning

@client.event
async def on_ready():
    # Enable banning functionality
    client.enable_banning()
    
    # Check if you have mod permissions
    has_perms = await client.check_mod_permissions()
    if has_perms:
        print("Moderator permissions confirmed - banning active")
    else:
        print("No moderator permissions - banning disabled")

Banning Users by Message ID

Track and ban users based on their message IDs:

@client.event
async def on_message(message):
    # Check for inappropriate content
    if "spam" in message.content.lower():
        # Ban the user who sent this specific message
        success = await client.ban_user_by_message_id(
            message.id, 
            "Spam detected"
        )
        
        if success:
            print(f"Banned {message.author.username}")
        else:
            print(f"Failed to ban {message.author.username}")

Banning Users by Address

Directly ban users if you know their address:

# Ban a user by their wallet address
success = await client.ban_user_by_address(
    "user_wallet_address_here",
    "Inappropriate behavior"
)

Unbanning Users

# Unban a user by their wallet address  
success = await client.unban_user("user_wallet_address_here")

Ban Statistics

# Get banning statistics
stats = client.get_ban_stats()
print(f"Banned users: {stats['banned_users_count']}")
print(f"Has mod permissions: {stats['has_mod_permissions']}")

Automatic Moderation Example

import asyncio
from pump_self_melon import Client

# Phrases that trigger automatic banning
BAN_TRIGGERS = ["spam", "scam", "inappropriate content"]

client = Client(token="your_token")

@client.event
async def on_ready():
    client.enable_banning()
    print("Auto-moderation bot ready!")

@client.event  
async def on_message(message):
    message_lower = message.content.lower()
    
    for trigger in BAN_TRIGGERS:
        if trigger in message_lower:
            success = await client.ban_user_by_message_id(
                message.id,
                f"Auto-ban: {trigger}"
            )
            
            if success:
                print(f"Auto-banned {message.author.username}")
            break

await client.start("room_id", "username")

Requirements for Banning:

  • You must have moderator permissions in the room
  • Banning functionality must be enabled with client.enable_banning()
  • The library will automatically check and warn about missing permissions

Advanced Usage

Multiple Event Handlers

You can register multiple handlers for the same event:

@client.event
async def on_message(message):
    # First handler
    pass

@client.listen('message') 
async def another_handler(message):
    # Second handler
    pass

Error Handling

Handle errors gracefully:

@client.event
async def on_error(error):
    print(f"An error occurred: {error}")
    # Log to file, send notification, etc.

Custom Room and Username

Override defaults when starting:

await client.start("room_id", username="custom_name")

Manual Connection Control

For advanced use cases:

await client.connect()
await client.join_room("room_id", "username")
await client.disconnect()

Content Moderation

The library automatically detects content moderation issues and logs warnings. These typically occur when:

  • Messages contain flagged content
  • Reply formatting triggers filters
  • Rate limits are exceeded

Monitor your logs for warnings like:

WARNING: Content moderation issue detected - message may have been filtered

Best Practices

  1. Use send_message over send_reply - Regular messages are less likely to be flagged
  2. Handle errors gracefully - Always implement error handlers
  3. Monitor content warnings - Watch for moderation issues

Examples

Echo Bot

@client.event
async def on_message(message):
    if message.content.startswith("echo "):
        text = message.content[5:]
        await client.send_message(f"Echo: {text}")

Welcome Bot

@client.event
async def on_join(room, user):
    await client.send_message(f"Welcome {user.username}!")

Command Handler

@client.event
async def on_message(message):
    if not message.content.startswith("!"):
        return
        
    command = message.content[1:].split()[0]
    
    if command == "ping":
        await client.send_message("Pong!")
    elif command == "help":
        await client.send_message("Available commands: !ping, !help")

Requirements

  • Python 3.9+
  • websockets 11.0.0+
  • aiohttp 3.8.0+

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please read our contributing guidelines and submit pull requests for any improvements.

Support

For issues and questions:

  • GitHub Issues: Report bugs and request features
  • Documentation: Check this README and docstrings
  • Examples: See the examples/ directory for more usage patterns

API Reference

Client

The main client class for connecting to pump.fun.

client = Client(token="your_token")  # Uses correct websocket URI automatically

Note: The library automatically uses the correct pump.fun chat websocket URI (wss://livechat.pump.fun/socket.io/?EIO=4&transport=websocket).

Methods

  • start(room_id, username=None) - Connect and start the client (username auto-fetched from token)
  • send_message(content, room_id=None, username=None) - Send a message
  • reply(message, content) - Reply to a message
  • disconnect() - Disconnect the client

Event Decorators

@client.event
async def on_ready():
    # Called when authenticated
    pass

@client.event
async def on_message(message):
    # Called for each message
    pass

@client.event
async def on_join(room, user):
    # Called when joining a room
    pass

@client.event
async def on_error(error):
    # Called on errors
    pass

# Alternative syntax
@client.listen('message')
async def message_handler(message):
    pass

Models

Message

message.id          # Message ID
message.content     # Message content
message.author      # User object
message.room        # Room object  
message.timestamp   # Datetime object
message.message_type # Message type
message.raw_data    # Raw message data

User

user.username       # Username
user.address        # Wallet address

Room

room.id            # Room/token ID

Utils

from pump_self_melon.utils import get_user_info, get_room_info

# Get user information
user_info = await get_user_info("auth_token")

# Get room/token information  
room_info = await get_room_info("room_id")

Examples

Basic Echo Bot

@client.event
async def on_message(message):
    if message.content.startswith("echo "):
        echo_text = message.content[5:]
        await client.reply(message, f"You said: {echo_text}")

Message Statistics

message_count = 0
user_messages = {}

@client.event
async def on_message(message):
    global message_count
    message_count += 1
    
    username = message.author.username
    user_messages[username] = user_messages.get(username, 0) + 1
    
    if message.content == "stats":
        top_users = sorted(user_messages.items(), key=lambda x: x[1], reverse=True)[:5]
        stats_text = f"Messages: {message_count}, Top: {', '.join(f'{u}({c})' for u,c in top_users)}"
        await client.send_message(stats_text)

Multiple Event Handlers

@client.listen('message')
async def log_messages(message):
    with open("chat.log", "a") as f:
        f.write(f"{message.timestamp}: {message.author.username}: {message.content}\n")

@client.listen('message') 
async def auto_respond(message):
    if "help" in message.content.lower():
        await client.send_message("Available commands: ping, echo, stats")

Testing

Run the manual tests:

python tests/manual_tests.py

Run examples:

python tests/examples.py

Run pytest (requires pytest installation):

pytest tests/

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pump_fun_self-1.0.2.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pump_fun_self-1.0.2-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file pump_fun_self-1.0.2.tar.gz.

File metadata

  • Download URL: pump_fun_self-1.0.2.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.8

File hashes

Hashes for pump_fun_self-1.0.2.tar.gz
Algorithm Hash digest
SHA256 7befae7e11e9fa98eddb8df39f554fe69e650f102baba5b6ae3b8170ca6432d6
MD5 dc36c5e1b08b5bfa69553e906a470a23
BLAKE2b-256 c4bdf7bee1330f3e3ab737b0cdb61ea0e9995de7673512063092f37aa23e7794

See more details on using hashes here.

File details

Details for the file pump_fun_self-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: pump_fun_self-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.8

File hashes

Hashes for pump_fun_self-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fe50c7be8d39156ce7a45746caf581b29322f42b6461c468d8778cbf85e225b8
MD5 b599cef8a9339b12169afef637dbbd7f
BLAKE2b-256 6eec05031c92375543b54504cb6714eb1b1c9a292b5c622e14f18541cf109e79

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page