0
# Messaging and Inbox
1
2
PRAW provides comprehensive messaging and inbox management capabilities including private messages, comment replies, username mentions, modmail conversations, and notification handling. These features enable bot communication and user interaction management.
3
4
## Capabilities
5
6
### Inbox Management
7
8
Access and manage the authenticated user's inbox with various message types and filtering options.
9
10
```python { .api }
11
class Inbox:
12
def __init__(self, reddit): ...
13
14
def all(self, **kwargs):
15
"""
16
Get all inbox items (messages, comments, mentions).
17
18
Parameters:
19
- limit: Number of items (default: 25, max: 100)
20
- mark: Whether to mark as read ("true", "false", or None)
21
- params: Additional query parameters
22
23
Returns:
24
ListingGenerator of Message/Comment instances
25
"""
26
27
def unread(self, **kwargs):
28
"""
29
Get unread inbox items.
30
31
Parameters:
32
- limit: Number of items (default: 25, max: 100)
33
- mark: Whether to mark as read when accessed
34
- params: Additional query parameters
35
36
Returns:
37
ListingGenerator of unread Message/Comment instances
38
"""
39
40
def messages(self, **kwargs):
41
"""
42
Get private messages only.
43
44
Parameters:
45
- limit: Number of messages (default: 25, max: 100)
46
- mark: Whether to mark as read ("true", "false", or None)
47
- params: Additional query parameters
48
49
Returns:
50
ListingGenerator of Message instances
51
"""
52
53
def comment_replies(self, **kwargs):
54
"""
55
Get comment replies to user's comments.
56
57
Parameters:
58
- limit: Number of replies (default: 25, max: 100)
59
- mark: Whether to mark as read ("true", "false", or None)
60
- params: Additional query parameters
61
62
Returns:
63
ListingGenerator of Comment instances
64
"""
65
66
def submission_replies(self, **kwargs):
67
"""
68
Get comment replies to user's submissions.
69
70
Parameters:
71
- limit: Number of replies (default: 25, max: 100)
72
- mark: Whether to mark as read ("true", "false", or None)
73
- params: Additional query parameters
74
75
Returns:
76
ListingGenerator of Comment instances
77
"""
78
79
def mentions(self, **kwargs):
80
"""
81
Get username mentions (/u/username).
82
83
Parameters:
84
- limit: Number of mentions (default: 25, max: 100)
85
- mark: Whether to mark as read ("true", "false", or None)
86
- params: Additional query parameters
87
88
Returns:
89
ListingGenerator of Comment instances containing mentions
90
"""
91
92
def sent(self, **kwargs):
93
"""
94
Get sent private messages.
95
96
Parameters:
97
- limit: Number of messages (default: 25, max: 100)
98
- params: Additional query parameters
99
100
Returns:
101
ListingGenerator of sent Message instances
102
"""
103
```
104
105
### Message Management
106
107
Manage individual messages with marking, blocking, and reporting capabilities.
108
109
```python { .api }
110
def mark_read(self, items: list):
111
"""
112
Mark messages or comments as read.
113
114
Parameters:
115
- items: List of Message/Comment instances to mark as read
116
"""
117
118
def mark_unread(self, items: list):
119
"""
120
Mark messages or comments as unread.
121
122
Parameters:
123
- items: List of Message/Comment instances to mark as unread
124
"""
125
126
def collapse(self, items: list):
127
"""
128
Collapse messages in inbox.
129
130
Parameters:
131
- items: List of Message instances to collapse
132
"""
133
134
def uncollapse(self, items: list):
135
"""
136
Uncollapse messages in inbox.
137
138
Parameters:
139
- items: List of Message instances to uncollapse
140
"""
141
142
def block(self, user):
143
"""
144
Block a user from sending messages.
145
146
Parameters:
147
- user: Redditor instance or username to block
148
"""
149
150
def unblock(self, user):
151
"""
152
Unblock a user, allowing them to send messages again.
153
154
Parameters:
155
- user: Redditor instance or username to unblock
156
"""
157
```
158
159
### Private Message Classes
160
161
Handle private messages between users and subreddit messaging.
162
163
```python { .api }
164
class Message:
165
"""Private message between users."""
166
167
def __init__(self, reddit, id: str = None): ...
168
169
def reply(self, body: str):
170
"""
171
Reply to the private message.
172
173
Parameters:
174
- body: Reply message content (markdown supported)
175
176
Returns:
177
Message instance of the reply
178
"""
179
180
def mark_read(self):
181
"""Mark this message as read."""
182
183
def mark_unread(self):
184
"""Mark this message as unread."""
185
186
def block_user(self):
187
"""Block the sender of this message."""
188
189
def report(self, reason: str):
190
"""
191
Report the message.
192
193
Parameters:
194
- reason: Report reason
195
"""
196
197
class SubredditMessage:
198
"""Message sent to/from a subreddit."""
199
200
def __init__(self, reddit, id: str = None): ...
201
202
def mute(self):
203
"""Mute the user in modmail (moderator only)."""
204
205
def unmute(self):
206
"""Unmute the user in modmail (moderator only)."""
207
```
208
209
### Message Properties and Data
210
211
Access message metadata, content, and threading information.
212
213
```python { .api }
214
# Message properties
215
id: str # Message ID
216
subject: str # Message subject
217
body: str # Message content
218
body_html: str # Message HTML content
219
author: Redditor # Message sender
220
dest: str # Message recipient username
221
created_utc: float # Creation timestamp (UTC)
222
context: str # Thread context (for comment replies)
223
224
# Message status
225
new: bool # Whether message is unread
226
was_comment: bool # Whether from comment reply
227
first_message: str # ID of first message in thread
228
first_message_name: str # Fullname of first message
229
parent_id: str # Parent message ID (for threading)
230
231
# Subreddit messages
232
subreddit: Subreddit # Associated subreddit (for subreddit messages)
233
```
234
235
### Modmail System
236
237
Modern modmail conversations and message management.
238
239
```python { .api }
240
class ModmailConversation:
241
"""Modern modmail conversation."""
242
243
def __init__(self, reddit, id: str = None): ...
244
245
def reply(
246
self,
247
body: str,
248
*,
249
author_hidden: bool = False,
250
internal: bool = False
251
):
252
"""
253
Reply to modmail conversation.
254
255
Parameters:
256
- body: Reply content (markdown supported)
257
- author_hidden: Hide moderator name
258
- internal: Internal moderator note (not visible to user)
259
260
Returns:
261
ModmailMessage instance
262
"""
263
264
def archive(self):
265
"""Archive the conversation."""
266
267
def unarchive(self):
268
"""Unarchive the conversation."""
269
270
def highlight(self):
271
"""Highlight the conversation."""
272
273
def unhighlight(self):
274
"""Remove highlight from conversation."""
275
276
def mute(self):
277
"""Mute the user (prevent further messages)."""
278
279
def unmute(self):
280
"""Unmute the user."""
281
282
def read(self):
283
"""Mark conversation as read."""
284
285
def unread(self):
286
"""Mark conversation as unread."""
287
288
class ModmailMessage:
289
"""Individual message in modmail conversation."""
290
291
def __init__(self, reddit, id: str = None): ...
292
293
class ModmailAction:
294
"""Modmail action/event in conversation."""
295
296
def __init__(self, reddit, id: str = None): ...
297
```
298
299
### Modmail Properties and Data
300
301
Access modmail conversation metadata and message threading.
302
303
```python { .api }
304
# Conversation properties
305
id: str # Conversation ID
306
subject: str # Conversation subject
307
state: int # Conversation state (0=new, 1=in_progress, 2=archived, etc.)
308
last_updated: str # Last update timestamp
309
last_user_update: str # Last user update timestamp
310
last_mod_update: str # Last moderator update timestamp
311
last_unread: str # Last unread timestamp
312
313
# Participants
314
authors: list # List of conversation participants
315
participant: Redditor # Main user participant (non-moderator)
316
317
# Message threading
318
messages: list # List of ModmailMessage instances
319
obj_ids: list # List of message/action IDs in order
320
321
# Conversation metadata
322
is_auto: bool # Whether auto-generated
323
is_repliable: bool # Whether user can reply
324
is_highlighted: bool # Whether highlighted by moderators
325
num_messages: int # Total number of messages
326
owner: Subreddit # Subreddit that owns the conversation
327
```
328
329
### Inbox Streaming
330
331
Stream new inbox items in real-time for immediate notification processing.
332
333
```python { .api }
334
def stream(self, **kwargs):
335
"""
336
Stream new inbox items as they arrive.
337
338
Parameters:
339
- pause_after: Pause after this many requests
340
- skip_existing: Skip items created before stream start
341
- attribute_name: Specific inbox attribute to stream ("unread", "messages", etc.)
342
343
Yields:
344
Message/Comment instances as they arrive
345
346
Continuously monitors inbox and yields new items immediately.
347
"""
348
```
349
350
### Message Composition
351
352
Send private messages to users and subreddits.
353
354
```python { .api }
355
def message(
356
self,
357
recipient: str,
358
subject: str,
359
message: str,
360
*,
361
from_subreddit = None
362
):
363
"""
364
Send private message.
365
366
Parameters:
367
- recipient: Username or subreddit name (with /r/ prefix)
368
- subject: Message subject
369
- message: Message content (markdown supported)
370
- from_subreddit: Send from subreddit instead of user account
371
372
Returns:
373
None (message is queued for delivery)
374
"""
375
```
376
377
## Usage Examples
378
379
### Basic Inbox Management
380
381
```python
382
import praw
383
384
reddit = praw.Reddit(...)
385
386
# Check unread messages
387
print("Unread messages:")
388
for item in reddit.inbox.unread(limit=10):
389
if hasattr(item, 'subject'): # It's a private message
390
print(f"Message from {item.author}: {item.subject}")
391
print(f"Content: {item.body[:100]}...")
392
else: # It's a comment reply
393
print(f"Reply from {item.author}: {item.body[:100]}...")
394
395
# Mark as read
396
item.mark_read()
397
398
# Get all inbox items
399
print("\nAll inbox:")
400
for item in reddit.inbox.all(limit=20):
401
print(f"From: {item.author}, Type: {type(item).__name__}")
402
```
403
404
### Private Message Handling
405
406
```python
407
# Send private message
408
reddit.redditor("recipient_username").message(
409
subject="Hello from my bot",
410
message="This is a test message sent using PRAW.\n\nThanks!"
411
)
412
413
# Process incoming messages
414
for message in reddit.inbox.messages(limit=10):
415
print(f"Message from {message.author}: {message.subject}")
416
print(f"Content: {message.body}")
417
418
# Reply to message
419
if "help" in message.body.lower():
420
message.reply("Here's some help information...")
421
422
# Block problematic users
423
if "spam" in message.body.lower():
424
message.block_user()
425
print(f"Blocked user: {message.author}")
426
```
427
428
### Comment Reply Management
429
430
```python
431
# Process comment replies
432
print("Comment replies:")
433
for reply in reddit.inbox.comment_replies(limit=15):
434
print(f"Reply to your comment by {reply.author}:")
435
print(f"Content: {reply.body}")
436
print(f"Parent comment context: {reply.context}")
437
438
# Reply to the reply
439
if "question" in reply.body.lower():
440
reply.reply("Thanks for your question! Here's my answer...")
441
442
# Process submission replies
443
print("\nSubmission replies:")
444
for reply in reddit.inbox.submission_replies(limit=10):
445
print(f"Reply to your post by {reply.author}:")
446
print(f"Content: {reply.body[:100]}...")
447
```
448
449
### Username Mention Handling
450
451
```python
452
# Process username mentions
453
print("Username mentions:")
454
for mention in reddit.inbox.mentions(limit=10):
455
print(f"Mentioned by {mention.author} in r/{mention.subreddit}:")
456
print(f"Context: {mention.body[:200]}...")
457
458
# Reply to mention
459
mention.reply("Thanks for the mention!")
460
461
# Get full submission context
462
submission = mention.submission
463
print(f"Mentioned in: {submission.title}")
464
```
465
466
### Bulk Message Management
467
468
```python
469
# Mark multiple items as read
470
unread_items = list(reddit.inbox.unread(limit=50))
471
if unread_items:
472
reddit.inbox.mark_read(unread_items)
473
print(f"Marked {len(unread_items)} items as read")
474
475
# Mark specific items as unread
476
recent_messages = list(reddit.inbox.messages(limit=5))
477
reddit.inbox.mark_unread(recent_messages)
478
print("Marked recent messages as unread")
479
480
# Collapse old messages
481
old_messages = []
482
for message in reddit.inbox.messages(limit=100):
483
if hasattr(message, 'created_utc'):
484
# Messages older than 30 days
485
if time.time() - message.created_utc > 30 * 24 * 3600:
486
old_messages.append(message)
487
488
if old_messages:
489
reddit.inbox.collapse(old_messages)
490
print(f"Collapsed {len(old_messages)} old messages")
491
```
492
493
### Modmail Conversation Management
494
495
```python
496
# Access subreddit modmail (requires moderation permissions)
497
subreddit = reddit.subreddit("mysubreddit")
498
499
# Get modmail conversations
500
for conversation in subreddit.modmail.conversations():
501
print(f"Conversation: {conversation.subject}")
502
print(f"Participant: {conversation.participant}")
503
print(f"State: {conversation.state}")
504
print(f"Messages: {conversation.num_messages}")
505
506
# Reply to conversation
507
if conversation.state == 0: # New conversation
508
conversation.reply(
509
"Thanks for contacting the moderators. We'll look into this.",
510
author_hidden=False
511
)
512
513
# Archive resolved conversations
514
if "resolved" in conversation.subject.lower():
515
conversation.archive()
516
517
# Create new modmail conversation
518
subreddit.modmail.create(
519
subject="Moderator Notice",
520
body="This is an official message from the moderation team.",
521
recipient="target_username"
522
)
523
```
524
525
### Real-time Inbox Monitoring
526
527
```python
528
import time
529
530
# Stream new inbox items
531
print("Monitoring inbox for new items...")
532
for item in reddit.inbox.stream():
533
print(f"\nNew inbox item from {item.author}:")
534
535
if hasattr(item, 'subject'): # Private message
536
print(f"Message: {item.subject}")
537
print(f"Content: {item.body[:100]}...")
538
539
# Auto-reply to messages containing "info"
540
if "info" in item.body.lower():
541
item.reply("Here's the information you requested...")
542
543
else: # Comment reply or mention
544
print(f"Comment: {item.body[:100]}...")
545
546
# Check if it's a mention
547
if f"/u/{reddit.user.me().name}" in item.body:
548
print("This is a username mention!")
549
550
# Mark as read automatically
551
item.mark_read()
552
553
# Stream only unread messages
554
print("Monitoring only unread messages...")
555
for message in reddit.inbox.stream(attribute_name="unread"):
556
print(f"New unread from {message.author}: {message.subject}")
557
# Process unread message
558
message.mark_read()
559
```
560
561
### Advanced Message Filtering
562
563
```python
564
# Filter messages by criteria
565
def process_inbox_with_filters():
566
important_keywords = ["urgent", "important", "help"]
567
568
for item in reddit.inbox.all(limit=50):
569
# Skip if already processed
570
if not item.new:
571
continue
572
573
# Check for important keywords
574
is_important = False
575
text_to_check = ""
576
577
if hasattr(item, 'subject'): # Private message
578
text_to_check = f"{item.subject} {item.body}"
579
else: # Comment
580
text_to_check = item.body
581
582
for keyword in important_keywords:
583
if keyword.lower() in text_to_check.lower():
584
is_important = True
585
break
586
587
if is_important:
588
print(f"IMPORTANT: {item.author} - {text_to_check[:100]}...")
589
# Process important message immediately
590
if hasattr(item, 'reply'):
591
item.reply("Thanks for your message. A moderator will respond shortly.")
592
593
# Mark as read
594
item.mark_read()
595
596
process_inbox_with_filters()
597
```
598
599
### Message Threading and Context
600
601
```python
602
# Handle threaded conversations
603
def process_message_thread(message):
604
"""Process a message and its thread context."""
605
606
print(f"Message from {message.author}: {message.subject}")
607
608
# If this is part of a thread, get the original message
609
if hasattr(message, 'first_message') and message.first_message:
610
print(f"This is part of thread: {message.first_message}")
611
612
# If this is a comment reply, get context
613
if hasattr(message, 'context') and message.context:
614
print(f"Comment context: {message.context}")
615
616
# Get the parent submission
617
submission = message.submission
618
print(f"Reply was on post: {submission.title}")
619
620
# Process the message content
621
print(f"Content: {message.body}")
622
623
return message
624
625
# Process messages with threading context
626
for message in reddit.inbox.messages(limit=20):
627
process_message_thread(message)
628
print("---")
629
```
630
631
## Types
632
633
```python { .api }
634
class InboxableMixin:
635
"""Mixin for objects that can be in inbox."""
636
637
def block_user(self):
638
"""Block the author of this item."""
639
640
def collapse(self):
641
"""Collapse this inbox item."""
642
643
def uncollapse(self):
644
"""Uncollapse this inbox item."""
645
646
def mark_read(self):
647
"""Mark as read."""
648
649
def mark_unread(self):
650
"""Mark as unread."""
651
652
class MessageableMixin:
653
"""Mixin for objects that can receive messages."""
654
655
def message(self, subject: str, message: str, **kwargs):
656
"""Send message to this entity."""
657
```