0
# Moderation
1
2
PRAW provides comprehensive moderation capabilities for Reddit communities including content moderation, user management, subreddit configuration, moderation logs, queues, and advanced moderator tools. These features enable effective community management and content curation.
3
4
## Capabilities
5
6
### Submission Moderation
7
8
Moderate Reddit submissions with approval, removal, and advanced moderation actions.
9
10
```python { .api }
11
class SubmissionModeration:
12
def __init__(self, submission): ...
13
14
def approve(self):
15
"""
16
Approve the submission.
17
18
Removes from moderation queue and makes visible to users.
19
"""
20
21
def remove(self, *, mod_note: str = None, spam: bool = None):
22
"""
23
Remove the submission.
24
25
Parameters:
26
- mod_note: Internal moderator note (visible to other mods)
27
- spam: Whether to mark as spam (trains spam filter)
28
"""
29
30
def spam(self):
31
"""
32
Mark submission as spam.
33
34
Equivalent to remove(spam=True). Trains Reddit's spam filter.
35
"""
36
37
def distinguish(self, *, how: str = "yes", sticky: bool = False):
38
"""
39
Distinguish the submission (moderator only).
40
41
Parameters:
42
- how: Distinguish type ("yes", "no", "admin", "special")
43
- sticky: Pin to top of subreddit
44
"""
45
46
def undistinguish(self):
47
"""Remove distinguish from submission."""
48
49
def ignore_reports(self):
50
"""Ignore future reports on this submission."""
51
52
def unignore_reports(self):
53
"""Stop ignoring reports on this submission."""
54
55
def lock(self):
56
"""Lock submission (prevent new comments)."""
57
58
def unlock(self):
59
"""Unlock submission (allow new comments)."""
60
61
def nsfw(self):
62
"""Mark submission as NSFW."""
63
64
def sfw(self):
65
"""Mark submission as SFW (not NSFW)."""
66
67
def spoiler(self):
68
"""Mark submission as spoiler."""
69
70
def unspoiler(self):
71
"""Remove spoiler mark from submission."""
72
73
def contest_mode(self, *, state: bool = True):
74
"""
75
Enable or disable contest mode.
76
77
Parameters:
78
- state: True to enable, False to disable
79
80
Contest mode randomizes comment order and hides scores.
81
"""
82
83
def sticky(self, *, state: bool = True, bottom: bool = True):
84
"""
85
Sticky or unsticky the submission.
86
87
Parameters:
88
- state: True to sticky, False to unsticky
89
- bottom: Sticky to bottom slot (False for top slot)
90
"""
91
92
def suggested_sort(self, sort: str = "blank"):
93
"""
94
Set suggested comment sort order.
95
96
Parameters:
97
- sort: Sort order ("confidence", "top", "new", "controversial",
98
"old", "random", "qa", "live", "blank" to clear)
99
"""
100
101
def flair(
102
self,
103
text: str = None,
104
css_class: str = None,
105
flair_template_id: str = None
106
):
107
"""
108
Set submission flair.
109
110
Parameters:
111
- text: Flair text
112
- css_class: CSS class for styling
113
- flair_template_id: Template ID for predefined flair
114
"""
115
116
def create_note(
117
self,
118
*,
119
note: str,
120
thing = None,
121
**kwargs
122
):
123
"""
124
Create moderator note for submission.
125
126
Parameters:
127
- note: Note content
128
- thing: Associated object (comment, etc.)
129
"""
130
```
131
132
### Comment Moderation
133
134
Moderate Reddit comments with approval, removal, and distinguishing capabilities.
135
136
```python { .api }
137
class CommentModeration:
138
def __init__(self, comment): ...
139
140
def approve(self):
141
"""
142
Approve the comment.
143
144
Removes from moderation queue and makes visible to users.
145
"""
146
147
def remove(self, *, mod_note: str = None, spam: bool = None):
148
"""
149
Remove the comment.
150
151
Parameters:
152
- mod_note: Internal moderator note (visible to other mods)
153
- spam: Whether to mark as spam (trains spam filter)
154
"""
155
156
def spam(self):
157
"""
158
Mark comment as spam.
159
160
Equivalent to remove(spam=True). Trains Reddit's spam filter.
161
"""
162
163
def distinguish(self, *, how: str = "yes", sticky: bool = False):
164
"""
165
Distinguish the comment.
166
167
Parameters:
168
- how: Distinguish type ("yes", "no", "admin", "special")
169
- sticky: Pin to top of comment thread
170
"""
171
172
def undistinguish(self):
173
"""Remove distinguish from comment."""
174
175
def ignore_reports(self):
176
"""Ignore future reports on this comment."""
177
178
def unignore_reports(self):
179
"""Stop ignoring reports on this comment."""
180
181
def lock(self):
182
"""Lock comment thread (prevent replies)."""
183
184
def unlock(self):
185
"""Unlock comment thread (allow replies)."""
186
187
def show(self):
188
"""Make comment visible (if hidden due to low score)."""
189
190
def create_note(
191
self,
192
*,
193
note: str,
194
thing = None,
195
**kwargs
196
):
197
"""
198
Create moderator note for comment.
199
200
Parameters:
201
- note: Note content
202
- thing: Associated object
203
"""
204
```
205
206
### Subreddit Moderation
207
208
Comprehensive subreddit management and moderation capabilities.
209
210
```python { .api }
211
class SubredditModeration:
212
def __init__(self, subreddit): ...
213
214
def accept_moderator_invite(self):
215
"""Accept pending moderator invitation."""
216
217
def approve(self, thing):
218
"""
219
Approve submission or comment.
220
221
Parameters:
222
- thing: Submission or Comment instance to approve
223
"""
224
225
def remove(
226
self,
227
thing,
228
*,
229
mod_note: str = None,
230
spam: bool = None
231
):
232
"""
233
Remove submission or comment.
234
235
Parameters:
236
- thing: Submission or Comment instance to remove
237
- mod_note: Internal moderator note
238
- spam: Whether to mark as spam
239
"""
240
241
def spam(self, thing):
242
"""
243
Mark content as spam.
244
245
Parameters:
246
- thing: Submission or Comment instance to mark as spam
247
"""
248
249
def distinguish(
250
self,
251
thing,
252
*,
253
how: str = "yes",
254
sticky: bool = False
255
):
256
"""
257
Distinguish content as moderator.
258
259
Parameters:
260
- thing: Submission or Comment instance to distinguish
261
- how: Distinguish type ("yes", "no", "admin", "special")
262
- sticky: Pin content
263
"""
264
265
def ignore_reports(self, thing):
266
"""
267
Ignore reports on content.
268
269
Parameters:
270
- thing: Submission or Comment instance
271
"""
272
273
def unignore_reports(self, thing):
274
"""
275
Stop ignoring reports on content.
276
277
Parameters:
278
- thing: Submission or Comment instance
279
"""
280
281
def notes(self, **kwargs):
282
"""
283
Get moderator notes.
284
285
Parameters:
286
- limit: Number of notes (default: 25, max: 100)
287
- params: Additional query parameters
288
289
Returns:
290
ListingGenerator of moderator notes
291
"""
292
293
def create_note(
294
self,
295
*,
296
redditor,
297
note: str,
298
thing = None,
299
**kwargs
300
):
301
"""
302
Create moderator note.
303
304
Parameters:
305
- redditor: Redditor instance or username
306
- note: Note content
307
- thing: Associated submission/comment
308
"""
309
```
310
311
### Moderation Queues and Logs
312
313
Access various moderation queues and activity logs.
314
315
```python { .api }
316
def log(self, **kwargs):
317
"""
318
Get moderation log entries.
319
320
Parameters:
321
- limit: Number of entries (default: 25, max: 100)
322
- mod: Filter by moderator username
323
- action: Filter by action type
324
- params: Additional query parameters
325
326
Returns:
327
ListingGenerator of ModAction instances
328
"""
329
330
def queue(self, **kwargs):
331
"""
332
Get moderation queue (reported/flagged content).
333
334
Parameters:
335
- limit: Number of items (default: 25, max: 100)
336
- only: Filter by type ("submissions", "comments")
337
- params: Additional query parameters
338
339
Returns:
340
ListingGenerator of Submission/Comment instances requiring moderation
341
"""
342
343
def reports(self, **kwargs):
344
"""
345
Get reported content.
346
347
Parameters:
348
- limit: Number of items (default: 25, max: 100)
349
- only: Filter by type ("submissions", "comments")
350
- params: Additional query parameters
351
352
Returns:
353
ListingGenerator of reported Submission/Comment instances
354
"""
355
356
def spam(self, **kwargs):
357
"""
358
Get spam queue.
359
360
Parameters:
361
- limit: Number of items (default: 25, max: 100)
362
- only: Filter by type ("submissions", "comments")
363
- params: Additional query parameters
364
365
Returns:
366
ListingGenerator of spam-filtered Submission/Comment instances
367
"""
368
369
def modqueue(self, **kwargs):
370
"""
371
Get items requiring moderator attention.
372
373
Parameters:
374
- limit: Number of items (default: 25, max: 100)
375
- only: Filter by type ("submissions", "comments")
376
- params: Additional query parameters
377
378
Returns:
379
ListingGenerator of items needing moderation
380
"""
381
382
def unmoderated(self, **kwargs):
383
"""
384
Get unmoderated submissions.
385
386
Parameters:
387
- limit: Number of submissions (default: 25, max: 100)
388
- params: Additional query parameters
389
390
Returns:
391
ListingGenerator of unmoderated Submission instances
392
"""
393
394
def edited(self, **kwargs):
395
"""
396
Get recently edited content.
397
398
Parameters:
399
- limit: Number of items (default: 25, max: 100)
400
- only: Filter by type ("submissions", "comments")
401
- params: Additional query parameters
402
403
Returns:
404
ListingGenerator of edited Submission/Comment instances
405
"""
406
```
407
408
### User Management
409
410
Manage subreddit users including banning, muting, and role assignments.
411
412
```python { .api }
413
def banned(self, **kwargs):
414
"""
415
Get banned users list.
416
417
Parameters:
418
- limit: Number of users (default: 25, max: 100)
419
- params: Additional query parameters
420
421
Returns:
422
ListingGenerator of banned Redditor instances with ban info
423
"""
424
425
def muted(self, **kwargs):
426
"""
427
Get muted users list.
428
429
Parameters:
430
- limit: Number of users (default: 25, max: 100)
431
- params: Additional query parameters
432
433
Returns:
434
ListingGenerator of muted Redditor instances
435
"""
436
437
def wiki_banned(self, **kwargs):
438
"""
439
Get wiki-banned users list.
440
441
Parameters:
442
- limit: Number of users (default: 25, max: 100)
443
- params: Additional query parameters
444
445
Returns:
446
ListingGenerator of wiki-banned Redditor instances
447
"""
448
449
def contributors(self, **kwargs):
450
"""
451
Get approved submitters list.
452
453
Parameters:
454
- limit: Number of users (default: 25, max: 100)
455
- params: Additional query parameters
456
457
Returns:
458
ListingGenerator of contributor Redditor instances
459
"""
460
461
def wiki_contributors(self, **kwargs):
462
"""
463
Get wiki contributors list.
464
465
Parameters:
466
- limit: Number of users (default: 25, max: 100)
467
- params: Additional query parameters
468
469
Returns:
470
ListingGenerator of wiki contributor Redditor instances
471
"""
472
473
def moderators(self, **kwargs):
474
"""
475
Get moderators list.
476
477
Parameters:
478
- params: Additional query parameters
479
480
Returns:
481
ModeratorListing of moderator Redditor instances with permissions
482
"""
483
```
484
485
### User Action Methods
486
487
Perform moderation actions on users.
488
489
```python { .api }
490
def ban(
491
self,
492
redditor,
493
*,
494
ban_reason: str = None,
495
ban_message: str = None,
496
duration: int = None,
497
mod_note: str = None
498
):
499
"""
500
Ban a user from the subreddit.
501
502
Parameters:
503
- redditor: Redditor instance or username
504
- ban_reason: Public ban reason
505
- ban_message: Private message to banned user
506
- duration: Ban duration in days (None for permanent)
507
- mod_note: Internal moderator note
508
"""
509
510
def unban(self, redditor):
511
"""
512
Unban a user from the subreddit.
513
514
Parameters:
515
- redditor: Redditor instance or username
516
"""
517
518
def mute(self, redditor, *, mod_note: str = None):
519
"""
520
Mute a user (prevent modmail messages).
521
522
Parameters:
523
- redditor: Redditor instance or username
524
- mod_note: Internal moderator note
525
"""
526
527
def unmute(self, redditor):
528
"""
529
Unmute a user (allow modmail messages).
530
531
Parameters:
532
- redditor: Redditor instance or username
533
"""
534
535
def contributor_add(self, redditor):
536
"""
537
Add user as approved submitter.
538
539
Parameters:
540
- redditor: Redditor instance or username
541
"""
542
543
def contributor_remove(self, redditor):
544
"""
545
Remove user from approved submitters.
546
547
Parameters:
548
- redditor: Redditor instance or username
549
"""
550
551
def moderator_add(
552
self,
553
redditor,
554
*,
555
permissions: list = None
556
):
557
"""
558
Add user as moderator.
559
560
Parameters:
561
- redditor: Redditor instance or username
562
- permissions: List of permissions to grant
563
"""
564
565
def moderator_remove(self, redditor):
566
"""
567
Remove user as moderator.
568
569
Parameters:
570
- redditor: Redditor instance or username
571
"""
572
573
def moderator_invite(
574
self,
575
redditor,
576
*,
577
permissions: list = None
578
):
579
"""
580
Invite user to be moderator.
581
582
Parameters:
583
- redditor: Redditor instance or username
584
- permissions: List of permissions to grant
585
"""
586
```
587
588
### Subreddit Settings Management
589
590
Manage subreddit configuration and settings.
591
592
```python { .api }
593
def settings(self):
594
"""
595
Get current subreddit settings.
596
597
Returns:
598
Dictionary with subreddit configuration
599
"""
600
601
def update(self, **settings):
602
"""
603
Update subreddit settings.
604
605
Parameters:
606
- title: Subreddit title
607
- public_description: Short description
608
- description: Full description (markdown)
609
- submission_type: "any", "link", "self"
610
- subreddit_type: "public", "private", "restricted"
611
- over_18: NSFW subreddit
612
- allow_images: Allow image posts
613
- allow_videos: Allow video posts
614
- allow_polls: Allow poll posts
615
- spoilers_enabled: Enable spoiler tags
616
- suggested_comment_sort: Default comment sort
617
- collapse_deleted_comments: Collapse deleted comments
618
- comment_score_hide_mins: Minutes to hide comment scores
619
- exclude_banned_modqueue: Exclude banned users from modqueue
620
- spam_links: Spam filter strength for links
621
- spam_selfposts: Spam filter strength for self posts
622
- spam_comments: Spam filter strength for comments
623
- wiki_edit_age: Minimum account age to edit wiki
624
- wiki_edit_karma: Minimum karma to edit wiki
625
- wikimode: Wiki mode ("disabled", "modonly", "anyone")
626
"""
627
```
628
629
### Removal Reasons Management
630
631
Manage removal reasons for consistent moderation messaging.
632
633
```python { .api }
634
class RemovalReason:
635
"""Removal reason template."""
636
637
def __init__(self, subreddit, id: str = None): ...
638
639
def delete(self):
640
"""Delete this removal reason."""
641
642
def update(self, **kwargs):
643
"""Update removal reason properties."""
644
645
def removal_reasons(self):
646
"""
647
Get removal reasons list.
648
649
Returns:
650
List of RemovalReason instances
651
"""
652
653
def create_removal_reason(
654
self,
655
message: str,
656
title: str,
657
**kwargs
658
):
659
"""
660
Create new removal reason.
661
662
Parameters:
663
- message: Removal message template
664
- title: Reason title/name
665
"""
666
```
667
668
### Modmail Management
669
670
Handle modern modmail conversations and actions.
671
672
```python { .api }
673
def modmail_conversations(self, **kwargs):
674
"""
675
Get modmail conversations for subreddit.
676
677
Parameters:
678
- limit: Number of conversations (default: 25, max: 100)
679
- sort: Sort order ("recent", "mod", "user", "unread")
680
- state: Filter by state (0=new, 1=in_progress, 2=archived, etc.)
681
682
Returns:
683
ListingGenerator of ModmailConversation instances
684
"""
685
686
def create_modmail_conversation(
687
self,
688
subject: str,
689
body: str,
690
recipient: str,
691
**kwargs
692
):
693
"""
694
Create new modmail conversation.
695
696
Parameters:
697
- subject: Conversation subject
698
- body: Initial message content
699
- recipient: Username to start conversation with
700
"""
701
```
702
703
### Moderator Permissions
704
705
Reddit moderator permission types and management.
706
707
```python { .api }
708
# Available moderator permissions
709
MODERATOR_PERMISSIONS = [
710
"access", # Access moderation tools
711
"config", # Manage settings and sidebar
712
"flair", # Manage flair
713
"mail", # Access modmail
714
"posts", # Approve/remove posts and comments
715
"wiki", # Manage wiki
716
"all" # All permissions
717
]
718
719
# Permission management in moderator actions
720
def invite_moderator_with_permissions():
721
subreddit.moderator_invite(
722
"new_moderator",
723
permissions=["posts", "flair", "mail"]
724
)
725
```
726
727
## Usage Examples
728
729
### Basic Content Moderation
730
731
```python
732
import praw
733
734
reddit = praw.Reddit(...)
735
subreddit = reddit.subreddit("mysubreddit")
736
737
# Process moderation queue
738
print("Processing moderation queue:")
739
for item in subreddit.mod.queue(limit=20):
740
print(f"Reported: {item.title if hasattr(item, 'title') else item.body[:50]}")
741
print(f"Reports: {item.num_reports}")
742
743
# Auto-approve items with low report count from trusted users
744
if item.num_reports <= 2 and item.author.comment_karma > 1000:
745
item.mod.approve()
746
print(f"Auto-approved post by {item.author}")
747
748
# Remove obvious spam
749
if "spam" in str(item.title).lower() or "spam" in str(item.body).lower():
750
item.mod.remove(spam=True, mod_note="Obvious spam content")
751
print(f"Removed spam by {item.author}")
752
753
# Process reports
754
print("\nProcessing reports:")
755
for item in subreddit.mod.reports(limit=15):
756
print(f"Reported item by {item.author}: {item.num_reports} reports")
757
# Manual review required for multiple reports
758
if item.num_reports >= 3:
759
print("Manual review needed - multiple reports")
760
```
761
762
### User Management
763
764
```python
765
# Ban management
766
def moderate_user(username, action, reason=None):
767
user = reddit.redditor(username)
768
769
if action == "ban":
770
subreddit.banned.add(
771
user,
772
ban_reason="Rule violation",
773
ban_message=f"You have been banned for: {reason}",
774
duration=7, # 7-day ban
775
mod_note=f"Banned by bot: {reason}"
776
)
777
print(f"Banned {username} for 7 days")
778
779
elif action == "mute":
780
subreddit.muted.add(user, mod_note=f"Muted: {reason}")
781
print(f"Muted {username}")
782
783
elif action == "unban":
784
subreddit.banned.remove(user)
785
print(f"Unbanned {username}")
786
787
# Check banned users
788
print("Banned users:")
789
for banned_user in subreddit.banned(limit=10):
790
print(f"Banned: {banned_user.name}")
791
print(f"Reason: {banned_user.ban_reason}")
792
print(f"Duration: {banned_user.days_left} days left")
793
794
# Manage contributors
795
trusted_users = ["user1", "user2", "user3"]
796
for username in trusted_users:
797
subreddit.contributor.add(reddit.redditor(username))
798
print(f"Added {username} as contributor")
799
```
800
801
### Automated Moderation Rules
802
803
```python
804
import re
805
806
def automated_content_moderation():
807
"""Automated moderation based on rules."""
808
809
# Spam patterns
810
spam_patterns = [
811
r"click here",
812
r"free money",
813
r"buy now",
814
r"limited time"
815
]
816
817
# Check new submissions
818
for submission in subreddit.new(limit=50):
819
# Skip if already moderated
820
if hasattr(submission, 'approved_by') and submission.approved_by:
821
continue
822
823
# Check for spam patterns
824
text_to_check = f"{submission.title} {submission.selftext}".lower()
825
is_spam = any(re.search(pattern, text_to_check) for pattern in spam_patterns)
826
827
if is_spam:
828
submission.mod.remove(
829
spam=True,
830
mod_note="Auto-removed: spam pattern detected"
831
)
832
print(f"Auto-removed spam: {submission.title}")
833
continue
834
835
# Auto-approve from trusted users
836
if submission.author.comment_karma > 5000 and submission.author.link_karma > 1000:
837
submission.mod.approve()
838
print(f"Auto-approved trusted user: {submission.author}")
839
840
# Flair enforcement
841
if not submission.link_flair_text and subreddit.display_name in ["programming", "askreddit"]:
842
submission.mod.remove(mod_note="No flair - auto-removed")
843
submission.reply(
844
"Your post was removed because it doesn't have flair. "
845
"Please add appropriate flair and resubmit."
846
)
847
print(f"Removed for missing flair: {submission.title}")
848
849
automated_content_moderation()
850
```
851
852
### Moderation Logging and Analytics
853
854
```python
855
from collections import defaultdict
856
import datetime
857
858
def analyze_moderation_activity():
859
"""Analyze moderation patterns."""
860
861
mod_actions = defaultdict(int)
862
mod_activity = defaultdict(int)
863
864
# Analyze moderation log
865
for action in subreddit.mod.log(limit=1000):
866
mod_actions[action.action] += 1
867
mod_activity[action.mod.name] += 1
868
869
print(f"{action.created_utc}: {action.mod} - {action.action}")
870
if hasattr(action, 'target_title'):
871
print(f" Target: {action.target_title}")
872
873
# Print statistics
874
print("\nModeration Actions Summary:")
875
for action, count in sorted(mod_actions.items(), key=lambda x: x[1], reverse=True):
876
print(f"{action}: {count}")
877
878
print("\nModerator Activity:")
879
for mod, count in sorted(mod_activity.items(), key=lambda x: x[1], reverse=True):
880
print(f"{mod}: {count} actions")
881
882
analyze_moderation_activity()
883
```
884
885
### Advanced Queue Processing
886
887
```python
888
def process_all_queues():
889
"""Process all moderation queues systematically."""
890
891
# Process spam queue
892
print("Processing spam queue:")
893
for item in subreddit.mod.spam(limit=50):
894
# Double-check if it's actually spam
895
if item.author.comment_karma < -10: # Negative karma user
896
item.mod.remove(spam=True)
897
print(f"Confirmed spam removal: {item.author}")
898
else:
899
# Might be false positive, approve
900
item.mod.approve()
901
print(f"Approved false positive: {item.author}")
902
903
# Process unmoderated queue
904
print("\nProcessing unmoderated:")
905
for submission in subreddit.mod.unmoderated(limit=30):
906
# Basic quality check
907
if len(submission.title) < 10:
908
submission.mod.remove(mod_note="Title too short")
909
elif submission.author.link_karma > 100:
910
submission.mod.approve()
911
else:
912
# Needs manual review
913
print(f"Manual review needed: {submission.title}")
914
915
# Process edited content
916
print("\nChecking edited content:")
917
for item in subreddit.mod.edited(limit=20):
918
# Re-check edited content for rule violations
919
if hasattr(item, 'selftext') and len(item.selftext) > 5000:
920
print(f"Long edited post needs review: {item.title}")
921
922
process_all_queues()
923
```
924
925
### Removal Reason Management
926
927
```python
928
# Create standard removal reasons
929
def setup_removal_reasons():
930
"""Set up standard removal reasons."""
931
932
reasons = [
933
{
934
"title": "Low Quality",
935
"message": "Your post was removed for being low quality. Please see our posting guidelines."
936
},
937
{
938
"title": "Rule 1 - Be Civil",
939
"message": "Your comment was removed for violating Rule 1: Be Civil. Personal attacks are not allowed."
940
},
941
{
942
"title": "Spam",
943
"message": "Your post was removed as spam. Self-promotion should be limited to 10% of your activity."
944
}
945
]
946
947
for reason_data in reasons:
948
try:
949
subreddit.mod.create_removal_reason(**reason_data)
950
print(f"Created removal reason: {reason_data['title']}")
951
except Exception as e:
952
print(f"Failed to create reason: {e}")
953
954
# Use removal reasons when moderating
955
def moderate_with_reasons():
956
for item in subreddit.mod.queue(limit=10):
957
if item.num_reports >= 2:
958
# Get appropriate removal reason
959
reasons = subreddit.mod.removal_reasons()
960
spam_reason = next((r for r in reasons if "spam" in r.title.lower()), None)
961
962
if spam_reason and "buy" in item.selftext.lower():
963
item.mod.remove(mod_note=f"Used reason: {spam_reason.title}")
964
print(f"Removed with spam reason: {item.title}")
965
```
966
967
## Types
968
969
```python { .api }
970
class ModAction:
971
"""Moderation log entry."""
972
973
id: str # Action ID
974
action: str # Action type ("approve", "remove", "ban", etc.)
975
mod: Redditor # Moderator who performed action
976
target_author: str # Target user (for user actions)
977
target_title: str # Target content title
978
target_permalink: str # Target content link
979
created_utc: float # Action timestamp (UTC)
980
subreddit: Subreddit # Subreddit where action occurred
981
details: str # Additional action details
982
983
class ModmailConversation:
984
"""Modern modmail conversation."""
985
986
id: str # Conversation ID
987
subject: str # Conversation subject
988
participant: Redditor # Main participant (non-moderator)
989
authors: list # All conversation participants
990
state: int # Conversation state
991
last_updated: str # Last update timestamp
992
is_highlighted: bool # Whether highlighted
993
num_messages: int # Number of messages
994
995
class ThingModerationMixin:
996
"""Base moderation capabilities."""
997
998
def approve(self):
999
"""Approve the item."""
1000
1001
def remove(self, **kwargs):
1002
"""Remove the item."""
1003
1004
def spam(self):
1005
"""Mark as spam."""
1006
1007
def ignore_reports(self):
1008
"""Ignore reports."""
1009
1010
def unignore_reports(self):
1011
"""Stop ignoring reports."""
1012
1013
class ModNoteMixin:
1014
"""Moderator note capabilities."""
1015
1016
def create_note(self, **kwargs):
1017
"""Create moderator note."""
1018
```