0

how do I make a a logger bot in discord.py which saves conversation into a text file.

So for example the bot saves all chats in a folder called "chatlogs" and in discord Server A every time someone says something that the bot can see, the bot logs it in a file called ServerA.txt and when Server B adds my bot, it generates a file called ServerB.txt and saves all Server B conversations in there.

Alex Wollan
  • 29
  • 1
  • 2
  • 9

1 Answers1

1

In an on_message event, open the file in append mode and write the latest message.

from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.event
async def on_message(message):
    guild = message.guild
    if guild:
        path = "chatlogs/{}.txt".format(guild.id)  
        with open(path, 'a+') as f:
            print("{0.timestamp} : {0.author.name} : {0.content}".format(message), file=f)
    await bot.process_commands(message)

bot.run("token")
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
  • @AlexWollan It should. – Patrick Haugh Oct 23 '18 at 17:36
  • But how would I make it, make a new text file on join a new guild? and delete text file when bot is removed? – Alex Wollan Oct 23 '18 at 17:43
  • Did you try running this code? It already creates a new file whenever it needs to. To remove the file you would write an `on_bot_remove` event that deletes the file with that name. Note that at the moment we only use server names, so if a server changes its name, events will get logged to a different file. You can prevent this by using the server id as the file name instead. – Patrick Haugh Oct 23 '18 at 17:49
  • I changed **@client.event** to **@bot.event** but I get this when I use bot (I use bot, because I have been using it throughout my code.) This is my error **@bot.event() TypeError: event() missing 1 required positional argument: 'coro'** also how would I use server ids instead? – Alex Wollan Oct 23 '18 at 17:54
  • You're decorating with `@bot.event()` instead of `@bot.event` – Patrick Haugh Oct 23 '18 at 17:58
  • No it wouldn't. See the documentation for [`wait_for`](https://discordpy.readthedocs.io/en/rewrite/api.html#discord.Client.wait_for), you can see an example of an `on_message` event there. – Patrick Haugh Oct 23 '18 at 18:03
  • It does nothing, when I changed it to @client.event, but returns no errors when something is written – Alex Wollan Oct 23 '18 at 18:07
  • @AlexWollan If you remove the `file=f`, do you see the messages being printed to the console instead of to the file? – Patrick Haugh Oct 23 '18 at 18:12
  • No I do not see the message, can I get your discord so we can talk quicker? – Alex Wollan Oct 23 '18 at 18:23
  • No (I'm on a work computer at the moment, so no discord). Could you post the code that you have in your question? There are a couple of gotchas (two `on_message` events for example), that are pretty easy to spot. – Patrick Haugh Oct 23 '18 at 18:28
  • Make it `@bot.event` if you're using `bot`. – Patrick Haugh Oct 23 '18 at 18:51
  • If you're using rewrite use `message.channel.guild.id` instead – Patrick Haugh Oct 23 '18 at 19:09
  • I get this **Traceback (most recent call last): File "C:\Python3\lib\site-packages\discord\client.py", line 220, in _run_event await coro(*args, **kwargs) File "C:/Users/cosmi/Desktop/__bot/main.py", line 60, in on_message path = "chatlogs/{}.txt".format(message.channel.guild.id) AttributeError: 'DMChannel' object has no attribute 'guild'** – Alex Wollan Oct 24 '18 at 05:25
  • How do you want messages on private channels handled? As for the other:https://stackoverflow.com/questions/49331096/why-does-on-message-stop-commands-from-working – Patrick Haugh Oct 24 '18 at 12:34
  • If it cant read private channels dont add them, if it can see add it. – Alex Wollan Oct 24 '18 at 16:00
  • Private channels don't have a server. Which file would you save the messages to? – Patrick Haugh Oct 24 '18 at 17:29
  • It does not save private channels – Alex Wollan Oct 24 '18 at 17:41
  • I edited it to ignore private channels. If you want to log private channels, create an `else` clause that defines a `path` for those private channels, then move the `open` clause out of the `if` to after that `else`. – Patrick Haugh Oct 24 '18 at 17:56