aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: c46a625ec3cec844cb4b6548822326aa2ec060f7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# UmaBot

A modular Reddit bot for automated post moderation built with Python and PRAW.

## Features

- **Spam Detection**: Automatically removes posts from users who post more than 3 times in 24 hours
- **Intelligent In-Character Moderator**: Uses GPT-5-nano to evaluate in-character posts and make smart moderation decisions
- **Modular Design**: Easy to add new moderation rules
- **Configurable Messages**: Customizable removal messages
- **Dry Run Mode**: Test the bot without actually removing posts
- **Comprehensive Logging**: Detailed logs for monitoring and debugging

### Intelligent In-Character Moderation

The bot features an advanced AI-powered in-character moderator that:

- **Auto-Flairing**: Automatically changes in-character posts to "Art" flair when they're primarily showcasing artwork
- **Quality Control**: Removes brief in-character posts while preserving high-quality content
- **Smart Evaluation**: Uses GPT-5-nano to analyze post content, creativity, effort, and engagement potential
- **User Communication**: Sends detailed mod mail explaining decisions and providing guidance

## Quick Start

### 1. Install Dependencies

```bash
# Using Rye (recommended)
rye sync

# Or using pip
pip install -r requirements.txt
```

### 2. Set Up Reddit API

1. Go to https://www.reddit.com/prefs/apps
2. Click "Create App" or "Create Another App"
3. Fill in the details:
   - **Name**: UmaBot
   - **Type**: Script
   - **Description**: Reddit moderation bot
   - **About URL**: (leave blank)
   - **Redirect URI**: http://localhost:8080
4. Note down the `client_id` (under the app name) and `client_secret`

### 3. Configure Environment Variables

Create a `.env` file in the project root:

```env
# Reddit API Credentials
REDDIT_CLIENT_ID=your_client_id_here
REDDIT_CLIENT_SECRET=your_client_secret_here
REDDIT_USERNAME=your_reddit_username
REDDIT_PASSWORD=your_reddit_password
# OpenAI API Credentials
OPENAI_API_KEY=your_openai_api_key_here

# Subreddit Configuration
SUBREDDIT_NAME=your_subreddit_name

# Bot Messages
ROLEPLAY_MESSAGE=Your post has been removed. Only one in-character post is allowed per user.

# Bot Settings
CHECK_INTERVAL=60
MAX_POSTS_PER_DAY=3
DRY_RUN=false
```

### 4. Test the Bot

```bash
# Test Reddit connection
python -m umabot --test

# Run in dry-run mode (won't actually remove posts)
python -m umabot --dry-run

# Run the bot normally
python -m umabot
```

## Usage

### Command Line Options

```bash
python -m umabot [OPTIONS]

Options:
  --verbose, -v    Enable verbose logging
  --dry-run        Run in dry-run mode (don't actually remove posts)
  --test           Test Reddit connection and exit
  --help           Show help message
```

### Adding New Rules

The bot is designed to be modular. To add a new rule:

1. Create a new file in `src/umabot/rules/`
2. Inherit from the `Rule` base class
3. Implement the required methods:
   - `should_remove(submission)`: Return `True` if the post should be removed
   - `get_removal_message(submission)`: Return the message to post when removing

Example:

```python
from .base import Rule

class MyCustomRule(Rule):
    def should_remove(self, submission):
        # Your logic here
        return False

    def get_removal_message(self, submission):
        return "Your post was removed for violating our custom rule."
```

4. Add the rule to the bot in `src/umabot/bot.py`:

```python
from .rules import MyCustomRule

# In the __init__ method:
self.rules = [
    SpamDetector(config),
    RoleplayLimiter(config),
    MyCustomRule(config)  # Add your new rule
]
```

## Deployment

### Render (Recommended)

1. Fork or clone this repository
2. Connect your repository to Render
3. Create a new Web Service
4. Configure the environment variables in Render's dashboard
5. Deploy!

The `render.yaml` file is included for easy deployment.

### Other Platforms

The bot can be deployed on any platform that supports Python:

- **Railway**: Use the `railway.toml` configuration
- **Heroku**: Use the `Procfile` and `requirements.txt`
- **PythonAnywhere**: Upload the code and set environment variables
- **Google Cloud**: Use Cloud Functions or App Engine

## Configuration

### Environment Variables

| Variable                      | Description                                    | Default        |
| ----------------------------- | ---------------------------------------------- | -------------- |
| `REDDIT_CLIENT_ID`            | Reddit API client ID                           | Required       |
| `REDDIT_CLIENT_SECRET`        | Reddit API client secret                       | Required       |
| `REDDIT_USERNAME`             | Reddit bot username                            | Required       |
| `REDDIT_PASSWORD`             | Reddit bot password                            | Required       |
| `REDDIT_USER_AGENT`           | User agent string                              | `UmaBot/0.1.0` |
| `SUBREDDIT_NAME`              | Target subreddit name                          | Required       |
| `ROLEPLAY_MESSAGE`            | Message for in-character removals              | Customizable   |
| `CHECK_INTERVAL`              | Seconds between checks                         | `60`           |
| `MAX_POSTS_PER_DAY`           | Max posts per user in time window              | `3`            |
| `MAX_ROLEPLAY_POSTS_PER_DAY`  | Max in-character posts per user in time window | `1`            |
| `POST_LIMIT_WINDOW_HOURS`     | Time window for post limits (hours)            | `24`           |
| `ROLEPLAY_LIMIT_WINDOW_HOURS` | Time window for in-character limits (hours)    | `24`           |
| `ROLEPLAY_SURGE_THRESHOLD_1`  | First surge threshold for in-character posts   | `20`           |
| `ROLEPLAY_SURGE_THRESHOLD_2`  | Second surge threshold for in-character posts  | `40`           |
| `ROLEPLAY_SURGE_THRESHOLD_3`  | Third surge threshold for in-character posts   | `60`           |
| `DRY_RUN`                     | Enable dry-run mode                            | `false`        |

## Development

### Project Structure

```
src/umabot/
├── __init__.py          # Main package entry point
├── __main__.py          # Module entry point
├── bot.py              # Main bot class
├── cli.py              # Command-line interface
├── config.py           # Configuration management
└── rules/              # Moderation rules
    ├── __init__.py
    ├── base.py         # Base rule class
    ├── spam_detector.py
    └── roleplay_limiter.py
```

### Running Tests

```bash
# Install dev dependencies
rye sync

# Run tests
pytest

# Format code
black src/

# Lint code
flake8 src/
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Support

If you encounter any issues:

1. Check the logs in `umabot.log`
2. Verify your Reddit API credentials
3. Ensure the bot has moderator permissions in the subreddit
4. Check that the subreddit name is correct

## Security Notes

- Never commit your `.env` file or Reddit credentials
- Use environment variables for all sensitive data
- The bot account should have moderator permissions in the target subreddit
- Consider using Reddit's OAuth2 flow for production deployments