1

I'm setting up a bot that pings someone if specific criteria are met. As an example, let's say the person wants to be pinged if someone says "apple" in the chat.

I'm trying to set up a system where if a person types "!ping apple" in the chat, they will be notified whenever the word "apple" appears in the chat. However, I can't figure out a way to store this information in a list based on the user automatically. What I'd like to be able to do is the following:

  1. User says "!ping apple"

  2. The bot appends "apple" to a list that's assigned to that person.

  3. If "apple" is said in the chat, the bot pings that person.

Is there an way to do this (preferably efficiently)? One strategy I tried was based off of this post about renaming strings to variables (which took the user's @, cut off the @ and #xxxx, removed spaces, then turned the resulting string into a variable that contained the list) but that has the potential for creating a bunch of bugs and isn't pythonic.

One strategy that might work is to say "!ping <word> <name of user>" but that seems like I'd run into the same problem; having a string instead of a variable.

Stephen
  • 35
  • 8

1 Answers1

0

There are multiple ways to do this but personally I would do this:

I'm going to assume you are using the built in ext.commands.cog module for simplicity. It would be slightly different if you are using a different core.

Have a config either either built into your core or have it locally in your cog. I'm going to use the methods self.get_settings() as the method that would get the dict. You will also need a method to save the settings such as self.save_settings()

@commands.command()
async def ping(self, ctx: commands.Context, word: str):
   settings = self.get_settings()
   settings[word] = ctx.author.id  #gets the user id from the person
   self.save_settings(settings)

Then your listener would be like

@commands.Cog.listener()
async def on_message(self, message: discord.Message):
   settings = self.get_settings()
   if message.content in settings:
      await message.channel.send(f'<@{settings[message.content]}>')

A simple settings manager can be just: (you need to import json btw)

def get_settings():
   with open('settings.json', 'r') as file:
      return json.load(file)

def save_settings(settings):
   with open('settings.json', 'r') as file:
      json.dump(settings, file)

This would be the most simple way to do so.

Edit: Implementation of the Settings manager

Kingsley Zhong
  • 358
  • 2
  • 9
  • I'm confused. When I try to use get_settings(), I get the error message "AttributeError: 'ping' object has no attribute 'get_settings' " which I assume is due to me improperly using it. By the way, I think I'm using the ext.commands.cog module; I coded "from discord.ext import commands" previously (and then put the @commands.command() bit into a class, etc.). – Stephen Aug 18 '20 at 05:46
  • Sorry if I wasn't clear, you need to make your own get_settings() function. – Kingsley Zhong Aug 18 '20 at 05:48
  • You will also need a save_settings() function. Sorry I forgot to add that. – Kingsley Zhong Aug 18 '20 at 05:50
  • In all honestly if you want you can not make a function like that and just use json's load and dump. – Kingsley Zhong Aug 18 '20 at 05:50
  • That's the part I'm confused on, though; how would I go about getting and saving the settings for a specific user (i.e. how should I approach get_settings() and save_settings() )? JSON is somewhat close to what I want, I can't use key and value pairs to cross-reference with another list. – Stephen Aug 18 '20 at 05:57
  • Edited to add a simple implementation, each key of the dict is the word that you're trying to get it to trigger and the value is the user id that has requested the action (I would recommend a list to avoid having one user overriding the other if both requested the same word). Discord registers user pings as <@USERID> so that's how it works. – Kingsley Zhong Aug 18 '20 at 06:05
  • Ah, that makes sense. Thanks! – Stephen Aug 18 '20 at 07:52