async def on_message(self, message: discord.Message): # Prevent feedback loop if str(message.author) == DISCORD_USERNAME: return filtered_content = DiscordHelper.filter_content(message) learn = True # Learn from private messages if message.guild is None and DISCORD_LEARN_FROM_DIRECT_MESSAGE: DiscordTrainingDataManager().store(message) learn = True # Learn from all server messages elif message.guild is not None and DISCORD_LEARN_FROM_ALL: if str(message.channel) not in DISCORD_LEARN_CHANNEL_EXCEPTIONS: DiscordTrainingDataManager().store(message) learn = True # Learn from User elif str(message.author) == DISCORD_LEARN_FROM_USER: DiscordTrainingDataManager().store(message) learn = True # real-time learning if learn: self._worker.send( ConnectorRecvMessage(filtered_content, learn=True, reply=False)) self._worker.recv() # Reply to mentions for mention in message.mentions: if str(mention) == DISCORD_USERNAME: self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: await channel.send(message.channel, reply) return # Reply to private messages if message.guild is None: self._logger.debug("Private Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: await channel.send(message.channel, reply) return
def run(self): from storage.discord import DiscordTrainingDataManager self._logger = logging.getLogger(self.__class__.__name__) self._db = DiscordTrainingDataManager() self._client = DiscordClient(self) self._client.loop.create_task(self._watchdog()) self._client.run(self._credentials.token)
def train(self, retrain_structure: bool = False, retrain_markov: bool = False): self._logger.info("Training begin") self._train_markov(retrain_markov) self._train_structure(retrain_structure) # Mark data as trained if self._twitter_connector is not None: from storage.twitter import TwitterTrainingDataManager TwitterTrainingDataManager().mark_trained() if self._discord_connector is not None: from storage.discord import DiscordTrainingDataManager DiscordTrainingDataManager().mark_trained() ImportTrainingDataManager().mark_trained() self._logger.info("Training end")
async def on_message(self, message: discord.Message): # Ignore attachements and Feedback Loop if message.attachments or message.author.bot: return filtered_content = DiscordHelper.filter_content(message) # Ignore empty and letter messages if not len(filtered_content) > 2: return if filtered_content == '': return learn = False # Learn from private messages if message.guild is None and DISCORD_LEARN_FROM_DIRECT_MESSAGE: DiscordTrainingDataManager().store(message) learn = True # Learn from all server messages elif message.guild is not None and DISCORD_LEARN_FROM_ALL: if str(message.channel) not in DISCORD_LEARN_CHANNEL_EXCEPTIONS: DiscordTrainingDataManager().store(message) learn = True # Learn will accept new input from specified channel and neglect specified user elif str(message.channel) in DISCORD_LEARN_CHANNEL and message.content is not None: if str(message.author) in DISCORD_NEGLECT_LEARN: return else: DiscordTrainingDataManager().store(message) learn = True # Learn from Specific User elif str(message.author) == DISCORD_LEARN_FROM_USER: DiscordTrainingDataManager().store(message) learn = True # Real-time learning if learn: self._worker.send(ConnectorRecvMessage(filtered_content, learn=True, reply=False)) self._worker.recv() # This pulls from discord config, just the embed footer for gags TALKING_VARIANT = random.choice(TALKING_TO) # Reply to mentions # Typically has embeds so be sure to enable the embed permission across all channels for mention in message.mentions: if str(mention) == DISCORD_USERNAME: self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = TALKING_VARIANT + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # Extra chunck where the bot will reply via keyword or prefix found in CHATTER_PREFIX # Keep in mind this can happen anywhere the bot has access to send messages if message.content.lower().startswith(tuple(CHATTER_PREFIX)): self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = TALKING_VARIANT + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # Channel which the bot will respond without any prefixes or @mentions elif str(message.channel) in DISCORD_AUTO_TALK and message.content is not None: self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = str(TALKING_VARIANT) + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # For the bot to reply in private messages, no embeds for private channels elif message.guild is None: self._logger.debug("Private Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: await asyncio.sleep(0.25) await message.channel.send(reply) return
def _preprocess_markov_data(self, all_training_data: bool = False): spacy_preprocessor = SpacyPreprocessor() self._logger.info("Training_Preprocessing_Markov(Import)") if not all_training_data: imported_messages = ImportTrainingDataManager().new_training_data() else: imported_messages = ImportTrainingDataManager().all_training_data() for message_idx, message in enumerate(imported_messages): # Print Progress if message_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Markov(Import): %f%%" % (message_idx / len(imported_messages) * 100)) doc = self._nlp(MarkovFilters.filter_input(message[0].decode())) spacy_preprocessor.preprocess(doc) tweets = None if self._twitter_connector is not None: self._logger.info("Training_Preprocessing_Markov(Twitter)") from storage.twitter import TwitterTrainingDataManager if not all_training_data: tweets = TwitterTrainingDataManager().new_training_data() else: tweets = TwitterTrainingDataManager().all_training_data() for tweet_idx, tweet in enumerate(tweets): # Print Progress if tweet_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Markov(Twitter): %f%%" % (tweet_idx / len(tweets) * 100)) doc = self._nlp(MarkovFilters.filter_input(tweet[0].decode())) spacy_preprocessor.preprocess(doc) discord_messages = None if self._discord_connector is not None: self._logger.info("Training_Preprocessing_Markov(Discord)") from storage.discord import DiscordTrainingDataManager if not all_training_data: discord_messages = DiscordTrainingDataManager( ).new_training_data() else: discord_messages = DiscordTrainingDataManager( ).all_training_data() for message_idx, message in enumerate(discord_messages): # Print Progress if message_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Markov(Discord): %f%%" % (message_idx / len(discord_messages) * 100)) doc = self._nlp(MarkovFilters.filter_input( message[0].decode())) spacy_preprocessor.preprocess(doc) return spacy_preprocessor
def _preprocess_structure_data(self): structure_preprocessor = StructurePreprocessor() self._logger.info("Training_Preprocessing_Structure(Import)") imported_messages = ImportTrainingDataManager().all_training_data( limit=STRUCTURE_MODEL_TRAINING_MAX_SIZE, order_by='id', order='desc') for message_idx, message in enumerate(imported_messages): # Print Progress if message_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Structure(Import): %f%%" % (message_idx / min(STRUCTURE_MODEL_TRAINING_MAX_SIZE, len(imported_messages)) * 100)) doc = self._nlp(MarkovFilters.filter_input(message[0].decode())) if not structure_preprocessor.preprocess(doc): return structure_preprocessor tweets = None if self._twitter_connector is not None: self._logger.info("Training_Preprocessing_Structure(Twitter)") from storage.twitter import TwitterTrainingDataManager tweets = TwitterTrainingDataManager().all_training_data( limit=STRUCTURE_MODEL_TRAINING_MAX_SIZE, order_by='timestamp', order='desc') for tweet_idx, tweet in enumerate(tweets): # Print Progress if tweet_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Structure(Twitter): %f%%" % (tweet_idx / min(STRUCTURE_MODEL_TRAINING_MAX_SIZE, len(tweets)) * 100)) doc = self._nlp(MarkovFilters.filter_input(tweet[0].decode())) if not structure_preprocessor.preprocess(doc): return structure_preprocessor discord_messages = None if self._discord_connector is not None: self._logger.info("Training_Preprocessing_Structure(Discord)") from storage.discord import DiscordTrainingDataManager discord_messages = DiscordTrainingDataManager().all_training_data( limit=STRUCTURE_MODEL_TRAINING_MAX_SIZE, order_by='timestamp', order='desc') for message_idx, message in enumerate(discord_messages): # Print Progress if message_idx % 100 == 0: self._logger.info( "Training_Preprocessing_Structure(Discord): %f%%" % (message_idx / min(STRUCTURE_MODEL_TRAINING_MAX_SIZE, len(discord_messages)) * 100)) doc = self._nlp(MarkovFilters.filter_input( message[0].decode())) if not structure_preprocessor.preprocess(doc): return structure_preprocessor return structure_preprocessor
async def on_message(self, message: discord.Message): # Ignore attachements and Feedback Loop if message.attachments or message.author.bot: return filtered_content = DiscordHelper.filter_content(message) # Ignore empty and letter messages if not len(filtered_content) > 2: return if filtered_content == '': return lang_check = detectlanguage.simple_detect(filtered_content) # Checks if the message is english or not lang_es = 'en' if lang_check != lang_es: return learn = False # Learn from private messages DISCORD_LEARN_SERVER_ID_EXCEPTION = list(map(int, DISCORD_LEARN_SERVER_ID_EXCEPTIONS)) # Take note there is an S DISCORD_LEARN_NEGLECT_UID = list(map(int, DISCORD_LEARN_NEGLECT_UIDS)) if message.guild is None: # checks for black listed user/s if not str(message.author) in DISCORD_LEARN_NEGLECT_USERNAMES or message.author.id in DISCORD_LEARN_NEGLECT_UID: # if user/s not in list, bot will learn if DISCORD_LEARN_FROM_DIRECT_MESSAGE is True: DiscordTrainingDataManager().store(message) learn = True # Learn from server elif message.guild is not None: # bot will ignore specified server ID's if message.guild.id not in DISCORD_LEARN_SERVER_ID_EXCEPTION: # Learn from Specific User if str(message.author) == DISCORD_LEARN_FROM_USER: DiscordTrainingDataManager().store(message) learn = True # bot will always learn from this channel except from black listed user/s if str(message.channel) in DISCORD_LEARN_CHANNEL and not str(message.author) in DISCORD_LEARN_NEGLECT_USERNAME or message.author.id in DISCORD_LEARN_NEGLECT_UID: if message.content is not None: DiscordTrainingDataManager().store(message) learn = True # section where the bot will learn everything if DISCORD_LEARN_FROM_ALL is True: # specify the channel where you do not want the bot to learn from if str(message.channel) not in DISCORD_LEARN_CHANNEL_EXCEPTIONS: DiscordTrainingDataManager().store(message) learn = True # Real-time learning if learn: self._worker.send(ConnectorRecvMessage(filtered_content, learn=True, reply=False)) self._worker.recv() # This pulls from discord config, just the embed footer for gags TALKING_VARIANT = random.choice(TALKING_TO) # Reply to mentions # Typically has embeds so be sure to enable the embed permission across all channels for mention in message.mentions: if str(mention) == DISCORD_USERNAME: self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = TALKING_VARIANT + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # Extra chunck where the bot will reply via keyword or prefix found in CHATTER_PREFIX # Keep in mind this can happen anywhere the bot has access to send messages and embeds if message.content.lower().startswith(tuple(CHATTER_PREFIX)): self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = TALKING_VARIANT + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # Channel which the bot will respond without any prefixes or @mentions elif str(message.channel) in DISCORD_AUTO_TALK and message.content is not None: self._logger.debug("Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: embed = discord.Embed(description=reply, color=message.author.color) embed.set_footer(text = str(TALKING_VARIANT) + message.author.name, icon_url = message.author.avatar_url) embed.timestamp = datetime.utcnow() await asyncio.sleep(0.25) await message.channel.send(embed=embed) return # For the bot to reply in private messages, no embeds for private channels elif message.guild is None: self._logger.debug("Private Message: %s" % filtered_content) self._worker.send(ConnectorRecvMessage(filtered_content)) reply = self._worker.recv() self._logger.debug("Reply: %s" % reply) if reply is not None: await asyncio.sleep(0.25) await message.channel.send(reply) return