cgeorgiaw HF Staff commited on
Commit
f5f1694
·
1 Parent(s): f66b11f

update for huggingscience server

Browse files
Files changed (1) hide show
  1. app.py +65 -73
app.py CHANGED
@@ -31,12 +31,29 @@ bot = commands.Bot(command_prefix='!', intents=intents, max_messages=1000000)
31
  logger = logging.getLogger(__name__)
32
  logging.basicConfig(level=logging.DEBUG)
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  #rate_limiter = RateLimiter(max_calls=10, period=60) # needs testing
35
  message_cache = {}
36
 
37
  AUTO_BAN_ALERT_THRESHOLD = 7
38
- AUTO_BAN_EXEMPT_ROLE_IDS = {897381378172264449, 897376942817419265}
39
- # moderator = 1078351789843292311
40
 
41
  def is_exempt(member: discord.Member) -> bool:
42
  return any(getattr(r, "id", None) in AUTO_BAN_EXEMPT_ROLE_IDS for r in getattr(member, "roles", []))
@@ -52,8 +69,8 @@ async def on_message(message):
52
  global number_of_messages
53
  if message.author != bot.user:
54
  message_cache[message.id] = message
55
- lunarflu = bot.get_user(811235357663297546) #811235357663297546
56
-
57
  """Backup"""
58
 
59
  number_of_messages = number_of_messages + 1
@@ -69,20 +86,22 @@ async def on_message(message):
69
  if message.embeds:
70
  for embed in message.embeds:
71
  backup_message += f"\nEmbed Title: {embed.title}\nEmbed Description: {embed.description}"
72
- dm_message = await lunarflu.send(backup_message)
 
73
 
74
  """Antispam"""
75
  #Detecting certain unwanted strings
76
  try:
77
- forbidden_patterns = [r"@everyone",
78
- r"@here",
79
  r"(https?:\/\/|http?:\/\/)?(www.)?(discord.(gg|io|me|li)|discordapp.com\/invite|discord.com\/invite)\/[^\s\/]+?(?=\b)"]
80
  if any(re.search(pattern, message.content, re.IGNORECASE) for pattern in forbidden_patterns):
81
- ignored_role_ids = [897381378172264449, 897376942817419265] #admins, huggingfolks
82
  if any(role.id in ignored_role_ids for role in message.author.roles):
83
- if message.author != lunarflu:
84
  return
85
- dm_unwanted = await lunarflu.send(f" {lunarflu.mention} [experimental] SUSPICIOUS MESSAGE: {message_link} | {message.author}: {message.content}")
 
86
  except Exception as e:
87
  print(f"Antispam->Detecting certain unwanted strings Error: {e}")
88
 
@@ -127,7 +146,7 @@ async def on_message(message):
127
  # warning for 4+
128
  channel = message.channel
129
  if spam_count == false_positive_threshold:
130
- if channel.id != 996580741121065091: # admin channel excluded due to how automod messages are categorized by the discord bot
131
  await channel.send(f"{message.author.mention}, you may be posting too quickly! Please slow down a bit 🤗")
132
 
133
  var1 = message.created_at
@@ -135,11 +154,7 @@ async def on_message(message):
135
  print(f"seconds since last message by {message.author}: {(var1 - var2).total_seconds()}")
136
  print(f"spam_count: {spam_count}")
137
 
138
- test_server = os.environ.get('TEST_SERVER')
139
- if test_server == 'True':
140
- alert = "<@&1106995261487710411>" # test @alerts role
141
- if test_server == 'False':
142
- alert = "<@&1108342563628404747>" # normal @alerts role
143
 
144
  await bot.log_channel.send(
145
  f"[EXPERIMENTAL ALERT] {message.author} may be posting too quickly! \n"
@@ -162,13 +177,7 @@ async def on_message(message):
162
  print("Autoban: could not resolve Member, skipping.")
163
  else:
164
  # Prepare alert ping safely
165
- test_server = os.environ.get('TEST_SERVER')
166
- if test_server == 'True':
167
- alert = "<@&1106995261487710411>" # test alerts
168
- elif test_server == 'False':
169
- alert = "<@&1108342563628404747>" # prod alerts
170
- else:
171
- alert = "" # no ping fallback
172
 
173
  # Skip bots and exempt roles
174
  if member.bot or is_exempt(member):
@@ -194,7 +203,7 @@ async def on_message(message):
194
  try:
195
  await member.send(
196
  f"You have been automatically banned from **{message.guild.name}** for repeated spam. "
197
- f"If this was an error, please contact @lunarflu."
198
  )
199
  except Exception as dm_err:
200
  print(f"Could not DM user before ban: {dm_err}")
@@ -372,7 +381,7 @@ async def on_member_ban(guild, banned_user):
372
  else:
373
  print(f'{entry2.user} banned {entry2.target} (no reason specified)')
374
 
375
- content = "<@&1108342563628404747>" # @alerts role
376
  embed = Embed(color=Color.red())
377
  embed.set_author(name=f"{entry2.target} ID: {entry2.target.id}", icon_url=entry2.target.avatar.url if entry2.target.avatar else bot.user.avatar.url)
378
  embed.title = "User Banned"
@@ -385,11 +394,10 @@ async def on_member_ban(guild, banned_user):
385
  embed.add_field(name="Reason", value=ban_reason, inline=False)
386
  embed.set_footer(text=f"{convert_to_timezone(datetime.utcnow(), zurich_tz)}")
387
 
388
- #user = bot.get_user(811235357663297546)
389
- await bot.log_channel.send(content=content, embed=embed)
390
 
391
  try:
392
- dm_message = await banned_user.send(f"You've been banned from the Hugging Face Discord. To appeal, reach out to <@811235357663297546> via DM")
393
  except Exception as e:
394
  print(f"Could not send DM to banned user: {e}")
395
 
@@ -407,7 +415,7 @@ async def on_member_unban(guild, unbanned_user):
407
  moderator = entry.user
408
 
409
  created_and_age = f"{unbanned_user.created_at}"
410
- content = "<@&1108342563628404747>" # @alerts role
411
  embed = Embed(color=Color.red())
412
  embed.set_author(name=f"{unbanned_user} ID: {unbanned_user.id}", icon_url=unbanned_user.avatar.url if unbanned_user.avatar else bot.user.avatar.url)
413
  embed.title = "User Unbanned"
@@ -416,10 +424,8 @@ async def on_member_unban(guild, unbanned_user):
416
  embed.add_field(name="Moderator", value=moderator.mention, inline=True)
417
  embed.add_field(name="Nickname", value=moderator.nick, inline=True)
418
  embed.set_footer(text=f"{convert_to_timezone(datetime.utcnow(), zurich_tz)}")
419
-
420
- #user = bot.get_user(811235357663297546)
421
- #dm_message = await user.send(content=content, embed=embed)
422
- await bot.log_channel.send(content=content, embed=embed)
423
 
424
  except Exception as e:
425
  print(f"on_member_unban Error: {e}")
@@ -431,7 +437,7 @@ async def on_member_unban(guild, unbanned_user):
431
  async def on_member_join(member):
432
  try:
433
  await asyncio.sleep(5)
434
- guild = bot.get_guild(879548962464493619)
435
 
436
  embed = Embed(color=Color.blue())
437
  avatar_url = member.avatar.url if member.avatar else bot.user.avatar.url
@@ -524,25 +530,6 @@ async def on_guild_role_delete(role):
524
  print(f"on_guild_role_delete Error: {e}")
525
 
526
 
527
- @bot.event
528
- async def on_guild_role_update(before, after):
529
- try:
530
- # editing roles, could expand this
531
- if before.name != after.name:
532
- embed = Embed(description=f'Role {before.mention} was renamed to {after.name}', color=Color.orange())
533
- await bot.log_channel.send(embed=embed)
534
-
535
- if before.permissions.administrator != after.permissions.administrator:
536
- # changes involving the administrator permission / sensitive permissions (can help to prevent mistakes)
537
- content = "<@&1108342563628404747>" # @alerts role
538
- embed = Embed(description=f'Role {after.mention} had its administrator permission {"enabled" if after.permissions.administrator else "disabled"}', color=Color.red())
539
- await bot.log_channel.send(content=content, embed=embed)
540
- except Exception as e:
541
- print(f"on_guild_role_update Error: {e}")
542
-
543
-
544
-
545
-
546
 
547
 
548
  @bot.event
@@ -651,14 +638,16 @@ class PersistentRoleSelectionView(View):
651
  # Command that sends the role buttons message.
652
  @bot.command(name="role_buttons")
653
  async def role_buttons(ctx):
654
- # Only allow lunarflu (ID 811235357663297546) to use this command.
655
- if ctx.author.id != 811235357663297546:
656
  await ctx.send("You are not authorized to use this command.", delete_after=10)
657
  return
658
 
659
- # List the role IDs you want to include (replace these with your actual role IDs).
660
- role_ids = [1014517792550166630, 1014548568238997616, 1014548769355862036, 1077250031180071023, 1093982736961785877, 1359533406102487281, 1174686719166124168, 1361696873764618381]
661
- roles = [ctx.guild.get_role(rid) for rid in role_ids if ctx.guild.get_role(rid) is not None]
 
 
662
 
663
  # Create the persistent view.
664
  view = PersistentRoleSelectionView(roles)
@@ -691,24 +680,27 @@ async def on_ready():
691
  await asyncio.sleep(5)
692
  print('Logged on as', bot.user)
693
  await asyncio.sleep(5)
694
- bot.log_channel = bot.get_channel(1036960509586587689) # admin-logs
695
  await asyncio.sleep(5)
696
  print(bot.log_channel)
697
- guild = bot.get_guild(879548962464493619)
698
-
 
 
 
 
 
 
699
  if guild:
700
- role_ids = [1014517792550166630, 1014548568238997616, 1014548769355862036, 1077250031180071023, 1093982736961785877, 1359533406102487281, 1174686719166124168, 1361696873764618381]
701
- roles = [guild.get_role(rid) for rid in role_ids if guild.get_role(rid) is not None]
702
- persistent_view = PersistentRoleSelectionView(roles)
703
- bot.add_view(persistent_view) # This makes the view persistent across restarts.
704
-
705
- for channel in guild.text_channels: # helps with more accurate logging across restarts
706
- try:
707
- message_cache.update({m.id: m async for m in channel.history(limit=10000)})
708
- print(f"Finished caching messages for channel: {channel.name}")
709
- except Exception as e:
710
- print(f"An error occurred while fetching messages from {channel.name}: {e}")
711
- await asyncio.sleep(0.1)
712
 
713
 
714
 
 
31
  logger = logging.getLogger(__name__)
32
  logging.basicConfig(level=logging.DEBUG)
33
 
34
+ # ============================================================
35
+ # CONFIGURATION — edit these for your server
36
+ # ============================================================
37
+ GUILD_ID = 1417920887549857874 # your server's ID
38
+ LOG_CHANNEL_ID = 1418169465555910699 # channel where mod events are posted
39
+ ADMIN_USER_ID = 847651116863062047 # ban-appeal contact + owner of !role_buttons
40
+ EXEMPT_ROLE_IDS = { # roles exempt from spam detection / autoban
41
+ 1418158261735264327,
42
+ 1419966815559225344,
43
+ 1418179704065884243,
44
+ 1418886227830112297,
45
+ 1418510579894845472,
46
+ }
47
+ ALERT_ROLE_ID = 1418510579894845472 # role pinged on spam alerts / bans
48
+ ADMIN_CHANNEL_ID = None # set to a channel ID to suppress spam warnings there
49
+ SELF_ASSIGN_ROLE_IDS = [] # role IDs for !role_buttons (empty disables)
50
+ # ============================================================
51
+
52
  #rate_limiter = RateLimiter(max_calls=10, period=60) # needs testing
53
  message_cache = {}
54
 
55
  AUTO_BAN_ALERT_THRESHOLD = 7
56
+ AUTO_BAN_EXEMPT_ROLE_IDS = EXEMPT_ROLE_IDS
 
57
 
58
  def is_exempt(member: discord.Member) -> bool:
59
  return any(getattr(r, "id", None) in AUTO_BAN_EXEMPT_ROLE_IDS for r in getattr(member, "roles", []))
 
69
  global number_of_messages
70
  if message.author != bot.user:
71
  message_cache[message.id] = message
72
+ admin_user = bot.get_user(ADMIN_USER_ID)
73
+
74
  """Backup"""
75
 
76
  number_of_messages = number_of_messages + 1
 
86
  if message.embeds:
87
  for embed in message.embeds:
88
  backup_message += f"\nEmbed Title: {embed.title}\nEmbed Description: {embed.description}"
89
+ if admin_user is not None:
90
+ dm_message = await admin_user.send(backup_message)
91
 
92
  """Antispam"""
93
  #Detecting certain unwanted strings
94
  try:
95
+ forbidden_patterns = [r"@everyone",
96
+ r"@here",
97
  r"(https?:\/\/|http?:\/\/)?(www.)?(discord.(gg|io|me|li)|discordapp.com\/invite|discord.com\/invite)\/[^\s\/]+?(?=\b)"]
98
  if any(re.search(pattern, message.content, re.IGNORECASE) for pattern in forbidden_patterns):
99
+ ignored_role_ids = list(EXEMPT_ROLE_IDS)
100
  if any(role.id in ignored_role_ids for role in message.author.roles):
101
+ if message.author.id != ADMIN_USER_ID:
102
  return
103
+ if admin_user is not None:
104
+ dm_unwanted = await admin_user.send(f" {admin_user.mention} [experimental] SUSPICIOUS MESSAGE: {message_link} | {message.author}: {message.content}")
105
  except Exception as e:
106
  print(f"Antispam->Detecting certain unwanted strings Error: {e}")
107
 
 
146
  # warning for 4+
147
  channel = message.channel
148
  if spam_count == false_positive_threshold:
149
+ if ADMIN_CHANNEL_ID is None or channel.id != ADMIN_CHANNEL_ID:
150
  await channel.send(f"{message.author.mention}, you may be posting too quickly! Please slow down a bit 🤗")
151
 
152
  var1 = message.created_at
 
154
  print(f"seconds since last message by {message.author}: {(var1 - var2).total_seconds()}")
155
  print(f"spam_count: {spam_count}")
156
 
157
+ alert = f"<@&{ALERT_ROLE_ID}>"
 
 
 
 
158
 
159
  await bot.log_channel.send(
160
  f"[EXPERIMENTAL ALERT] {message.author} may be posting too quickly! \n"
 
177
  print("Autoban: could not resolve Member, skipping.")
178
  else:
179
  # Prepare alert ping safely
180
+ alert = f"<@&{ALERT_ROLE_ID}>"
 
 
 
 
 
 
181
 
182
  # Skip bots and exempt roles
183
  if member.bot or is_exempt(member):
 
203
  try:
204
  await member.send(
205
  f"You have been automatically banned from **{message.guild.name}** for repeated spam. "
206
+ f"If this was an error, please contact <@{ADMIN_USER_ID}>."
207
  )
208
  except Exception as dm_err:
209
  print(f"Could not DM user before ban: {dm_err}")
 
381
  else:
382
  print(f'{entry2.user} banned {entry2.target} (no reason specified)')
383
 
384
+ content = f"<@&{ALERT_ROLE_ID}>"
385
  embed = Embed(color=Color.red())
386
  embed.set_author(name=f"{entry2.target} ID: {entry2.target.id}", icon_url=entry2.target.avatar.url if entry2.target.avatar else bot.user.avatar.url)
387
  embed.title = "User Banned"
 
394
  embed.add_field(name="Reason", value=ban_reason, inline=False)
395
  embed.set_footer(text=f"{convert_to_timezone(datetime.utcnow(), zurich_tz)}")
396
 
397
+ await bot.log_channel.send(content=content, embed=embed)
 
398
 
399
  try:
400
+ dm_message = await banned_user.send(f"You've been banned from {guild.name}. To appeal, reach out to <@{ADMIN_USER_ID}> via DM")
401
  except Exception as e:
402
  print(f"Could not send DM to banned user: {e}")
403
 
 
415
  moderator = entry.user
416
 
417
  created_and_age = f"{unbanned_user.created_at}"
418
+ content = f"<@&{ALERT_ROLE_ID}>"
419
  embed = Embed(color=Color.red())
420
  embed.set_author(name=f"{unbanned_user} ID: {unbanned_user.id}", icon_url=unbanned_user.avatar.url if unbanned_user.avatar else bot.user.avatar.url)
421
  embed.title = "User Unbanned"
 
424
  embed.add_field(name="Moderator", value=moderator.mention, inline=True)
425
  embed.add_field(name="Nickname", value=moderator.nick, inline=True)
426
  embed.set_footer(text=f"{convert_to_timezone(datetime.utcnow(), zurich_tz)}")
427
+
428
+ await bot.log_channel.send(content=content, embed=embed)
 
 
429
 
430
  except Exception as e:
431
  print(f"on_member_unban Error: {e}")
 
437
  async def on_member_join(member):
438
  try:
439
  await asyncio.sleep(5)
440
+ guild = bot.get_guild(GUILD_ID)
441
 
442
  embed = Embed(color=Color.blue())
443
  avatar_url = member.avatar.url if member.avatar else bot.user.avatar.url
 
530
  print(f"on_guild_role_delete Error: {e}")
531
 
532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
 
534
 
535
  @bot.event
 
638
  # Command that sends the role buttons message.
639
  @bot.command(name="role_buttons")
640
  async def role_buttons(ctx):
641
+ # Only the configured admin user is allowed to invoke this command.
642
+ if ctx.author.id != ADMIN_USER_ID:
643
  await ctx.send("You are not authorized to use this command.", delete_after=10)
644
  return
645
 
646
+ if not SELF_ASSIGN_ROLE_IDS:
647
+ await ctx.send("No self-assignable roles configured. Set SELF_ASSIGN_ROLE_IDS in app.py.", delete_after=15)
648
+ return
649
+
650
+ roles = [ctx.guild.get_role(rid) for rid in SELF_ASSIGN_ROLE_IDS if ctx.guild.get_role(rid) is not None]
651
 
652
  # Create the persistent view.
653
  view = PersistentRoleSelectionView(roles)
 
680
  await asyncio.sleep(5)
681
  print('Logged on as', bot.user)
682
  await asyncio.sleep(5)
683
+ bot.log_channel = bot.get_channel(LOG_CHANNEL_ID)
684
  await asyncio.sleep(5)
685
  print(bot.log_channel)
686
+ guild = bot.get_guild(GUILD_ID)
687
+
688
+ if guild and SELF_ASSIGN_ROLE_IDS:
689
+ roles = [guild.get_role(rid) for rid in SELF_ASSIGN_ROLE_IDS if guild.get_role(rid) is not None]
690
+ if roles:
691
+ persistent_view = PersistentRoleSelectionView(roles)
692
+ bot.add_view(persistent_view) # This makes the view persistent across restarts.
693
+
694
  if guild:
695
+ for channel in guild.text_channels: # helps with more accurate logging across restarts
696
+ try:
697
+ message_cache.update({m.id: m async for m in channel.history(limit=10000)})
698
+ print(f"Finished caching messages for channel: {channel.name}")
699
+ except Exception as e:
700
+ print(f"An error occurred while fetching messages from {channel.name}: {e}")
701
+ await asyncio.sleep(0.1)
702
+ else:
703
+ print(f"on_ready: could not find guild with ID {GUILD_ID}. Is the bot in the server?")
 
 
 
704
 
705
 
706