Skip to content

Commit f7f5a74

Browse files
authored
Merge pull request #153 from kyb3r/anon-cmd
Anon cmd and internal message logging
2 parents aef0c1a + 3125be3 commit f7f5a74

File tree

6 files changed

+75
-20
lines changed

6 files changed

+75
-20
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77

8+
# v2.10.0
9+
10+
### Added
11+
- `anonreply` command to anonymously reply to the recipient.
12+
The username of the anonymous user defaults to the `mod_tag` (the footer text of a mod reply). The avatar defaults the guild icon url. However you can change both of these via the `anon_username`, `anon_avatar_url` and `anon_tag` config variables.
13+
14+
### Changed
15+
Your bot now logs all messages sent in a thread channel, including discussions that take place. You can now toggle to view them in the log viewer app.
16+
817
# v2.9.4
918
Fixed a small bug due to a typo.
1019

bot.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SOFTWARE.
2323
"""
2424

25-
__version__ = '2.9.4'
25+
__version__ = '2.10.0'
2626

2727
import asyncio
2828
import uvloop
@@ -362,8 +362,15 @@ async def on_message(self, message):
362362
cmd = message.content[len(prefix):].strip()
363363
if cmd in self.snippets:
364364
message.content = f'{prefix}reply {self.snippets[cmd]}'
365+
366+
ctx = await self.get_context(message)
367+
if ctx.command:
368+
return await self.invoke(ctx)
369+
370+
thread = await self.threads.find(channel=ctx.channel)
365371

366-
await self.process_commands(message)
372+
if thread is not None:
373+
await self.modmail_api.append_log(message, type='internal')
367374

368375
async def on_guild_channel_delete(self, channel):
369376
if channel.guild != self.modmail_guild:

cogs/modmail.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ async def logs(self, ctx, *, member: Union[discord.Member, discord.User, obj]=No
367367
await session.run()
368368

369369
@commands.command()
370-
@trigger_typing
371370
async def reply(self, ctx, *, msg=''):
372371
"""Reply to users using this command.
373372
@@ -376,15 +375,25 @@ async def reply(self, ctx, *, msg=''):
376375
ctx.message.content = msg
377376
thread = await self.bot.threads.find(channel=ctx.channel)
378377
if thread:
378+
await ctx.trigger_typing()
379379
await thread.reply(ctx.message)
380380

381381
@commands.command()
382-
@trigger_typing
382+
async def anonreply(self, ctx, *, msg=''):
383+
ctx.message.content = msg
384+
thread = await self.bot.threads.find(channel=ctx.channel)
385+
if thread:
386+
await ctx.trigger_typing()
387+
await thread.reply(ctx.message, anonymous=True)
388+
389+
@commands.command()
383390
async def note(self, ctx, *, msg=''):
384391
"""Take a note about the current thread, useful for noting context."""
385392
ctx.message.content = msg
386393
thread = await self.bot.threads.find(channel=ctx.channel)
394+
387395
if thread:
396+
await ctx.trigger_typing()
388397
await thread.note(ctx.message)
389398

390399
@commands.command()

core/clients.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,15 @@ def append_log(self, message, channel_id='', type='thread_message'):
167167
},
168168
# message properties
169169
'content': message.content,
170-
'attachments': [i.url for i in message.attachments],
171-
'type': type
170+
'type': type,
171+
'attachments': [
172+
{
173+
'id': a.id,
174+
'filename': a.filename,
175+
'is_image': a.width is not None,
176+
'size': a.size,
177+
'url': a.url
178+
} for a in message.attachments ]
172179
}
173180
}
174181
return self.request(self.logs + f'/{channel_id}', method='PATCH', payload=payload)
@@ -253,18 +260,23 @@ async def append_log(self, message, channel_id='', type='thread_message'):
253260
payload = {
254261
'timestamp': str(message.created_at),
255262
'message_id': str(message.id),
256-
# author
257263
'author': {
258264
'id': str(message.author.id),
259265
'name': message.author.name,
260266
'discriminator': message.author.discriminator,
261267
'avatar_url': message.author.avatar_url,
262268
'mod': not isinstance(message.channel, discord.DMChannel),
263269
},
264-
# message properties
265270
'content': message.content,
266-
'attachments': [i.url for i in message.attachments],
267-
'type': type
271+
'type': type,
272+
'attachments': [
273+
{
274+
'id': a.id,
275+
'filename': a.filename,
276+
'is_image': a.width is not None,
277+
'size': a.size,
278+
'url': a.url
279+
} for a in message.attachments ]
268280
}
269281

270282
return await self.logs.find_one_and_update(

core/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ class ConfigManager:
1111
'mention', 'disable_autoupdates', 'prefix',
1212
'main_category_id', 'sent_emoji', 'blocked_emoji',
1313
'thread_creation_response', 'twitch_url', 'mod_color',
14-
'recipient_color', 'mod_tag'
14+
'recipient_color', 'mod_tag', 'anon_username', 'anon_avatar_url',
15+
'anon_tag'
1516
}
1617

1718
internal_keys = {

core/thread.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,8 @@ async def note(self, message):
182182
self.bot.modmail_api.append_log(message, self.channel.id, type='system'),
183183
self.send(message, self.channel, note=True)
184184
)
185-
186185

187-
async def reply(self, message):
186+
async def reply(self, message, anonymous=False):
188187
if not message.content and not message.attachments:
189188
raise commands.UserInputError
190189
if all(not g.get_member(self.id) for g in self.bot.guilds):
@@ -196,13 +195,14 @@ async def reply(self, message):
196195

197196
tasks = [
198197
# in thread channel
199-
self.send(message, self.channel, from_mod=True),
198+
self.send(message, destination=self.channel, from_mod=True, anonymous=anonymous),
200199
# to user
201-
self.send(message, self.recipient, from_mod=True)
200+
self.send(message, destination=self.recipient, from_mod=True, anonymous=anonymous)
202201
]
203202

203+
204204
self.bot.loop.create_task(
205-
self.bot.modmail_api.append_log(message, self.channel.id)
205+
self.bot.modmail_api.append_log(message, self.channel.id, type='anonymous' if anonymous else 'thread_message')
206206
)
207207

208208
if self.close_task is not None:
@@ -215,7 +215,7 @@ async def reply(self, message):
215215

216216
await asyncio.gather(*tasks)
217217

218-
async def send(self, message, destination=None, from_mod=False, note=False):
218+
async def send(self, message, destination=None, from_mod=False, note=False, anonymous=False):
219219
if self.close_task is not None:
220220
# cancel closing if a thread message is sent.
221221
await self.cancel_closure()
@@ -244,10 +244,21 @@ async def send(self, message, destination=None, from_mod=False, note=False):
244244

245245
# store message id in hidden url
246246
if not note:
247-
em.set_author(name=author,
248-
icon_url=author.avatar_url,
247+
248+
if anonymous and from_mod and not isinstance(destination, discord.TextChannel):
249+
# Anonymously sending to the user.
250+
name = self.bot.config.get('anon_username', self.bot.config.get('mod_tag', 'Moderator'))
251+
avatar_url = self.bot.config.get('anon_avatar_url', self.bot.guild.icon_url)
252+
else:
253+
# Normal message
254+
name = str(author)
255+
avatar_url = author.avatar_url
256+
257+
em.set_author(name=name,
258+
icon_url=avatar_url,
249259
url=message.jump_url)
250260
else:
261+
# Special note messages
251262
em.set_author(
252263
name=f'Note ({author.name})',
253264
icon_url=system_avatar_url,
@@ -301,7 +312,13 @@ def is_image_url(u, _):
301312

302313
if from_mod:
303314
em.color = self.bot.mod_color
304-
em.set_footer(text=self.bot.config.get('mod_tag', 'Moderator'))
315+
if anonymous and isinstance(destination, discord.TextChannel): # Anonymous reply sent in thread channel
316+
em.set_footer(text='Anonymous Reply')
317+
elif not anonymous:
318+
em.set_footer(text=self.bot.config.get('mod_tag', 'Moderator')) # Normal messages
319+
else:
320+
em.set_footer(text=self.bot.config.get('anon_tag', 'Response')) # Anonymous reply sent to user
321+
305322
elif note:
306323
em.color = discord.Color.blurple()
307324
else:

0 commit comments

Comments
 (0)