Metadata-Version: 2.4
Name: pump.fun-self
Version: 1.0.0
Summary: A discord.py-self-like library for pump.fun selfbot development
Author-email: melon <stevebsons@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/melon/pump-self
Project-URL: Repository, https://github.com/melon/pump-self
Project-URL: Issues, https://github.com/melon/pump-self/issues
Keywords: pump.fun,selfbot,discord.py,websocket,chat,bot
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Communications :: Chat
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENCE
Requires-Dist: websockets>=11.0.0
Requires-Dist: aiohttp>=3.8.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Dynamic: license-file

# Pump-Self

A discord.py-self-like library for creating selfbots on pump.fun. Build custom bots with an intuitive event-driven architecture.

## Features

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

## Installation

```bash
pip install pump-self
```

## Quick Start

```python
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.

```python
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:

```python
@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:

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

### Sending Messages

#### send_message()
Send a regular message to the chat:

```python
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):

```python
@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:

```python
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:

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

### Room
Represents a chat room:

```python
room.id             # Room identifier
```

## Advanced Usage

### Multiple Event Handlers
You can register multiple handlers for the same event:

```python
@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:

```python
@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:

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

### Manual Connection Control
For advanced use cases:

```python
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. **Respect rate limits** - Don't spam messages
4. **Monitor content warnings** - Watch for moderation issues
5. **Keep tokens secure** - Never commit tokens to version control

## Examples

### Echo Bot
```python
@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
```python
@client.event
async def on_join(room, user):
    await client.send_message(f"Welcome {user.username}!")
```

### Command Handler
```python
@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.

```python
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

```python
@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
```python
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
```python
user.username       # Username
user.address        # Wallet address
```

#### Room
```python
room.id            # Room/token ID
```

### Utils

```python
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
```python
@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
```python
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
```python
@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:
```bash
python tests/manual_tests.py
```

Run examples:
```bash
python tests/examples.py
```

Run pytest (requires pytest installation):
```bash
pytest tests/
```

## License

MIT License
