[PYTHON] Create a bot that only returns the result of morphological analysis with MeCab on Discord

Referenced articles

Overview

As the title says,

root@4c506a68cd26:~# python --version
Python 3.7.7
root@4c506a68cd26:~# mecab --version
mecab of 0.996

Preparation

I will omit it because it only follows the "referenced article".

I didn't understand one point, or misunderstood, I thought that there was a setting to specify the endpoint somewhere when deploying locally or to heroku, so I searched variously. I didn't write it anywhere, but somehow I came to a conclusion, so I wrote it so that I don't forget Whether it's local or running on a server on the Internet, it connects to the Discord server and is recognized as online while client.run (TOKEN) is running and running. I think that's what it means. I haven't read the source code and it's not reliable information, but I think that's probably the case.

Preparation around heroku

Log in to heroku from the CLI.

heroku login

Log in to heroku in your browser.

Log in to the Container Registry on Heroku.

heroku container:login

Set Discord TOKEN.

heroku config:set TOKEN=hogehoge

Docker settings

FROM python:3.7-slim

ENV HOME=/app
WORKDIR /app

#Used to install NEologd
RUN apt-get update && apt-get install -y \
  build-essential \
  curl \
  git \
  openssl \
  sudo \
  zip \
  file

#Install MeCab
RUN apt-get update && apt-get install -y \
  mecab \
  libmecab-dev \
  mecab-ipadic \
  mecab-ipadic-utf8

RUN cd /usr/share/mecab && \
    git clone https://github.com/neologd/mecab-ipadic-neologd.git && \
    cd mecab-ipadic-neologd/ && \
    ./bin/install-mecab-ipadic-neologd -n -a -y -p /usr/share/mecab/dic/mecab-ipadic-neologd/

COPY requirements.txt ./requirements.txt

RUN pip install -r requirements.txt

COPY . .

# discord_bot.Run py to launch the bot
CMD ["python", "discord_bot.py"]

Library settings used

requirements.txt


mecab-python3
discord.py

bot implementation

From all messages, without using commands

discord_bot.py


import os
import MeCab
import discord

TOKEN = os.environ["TOKEN"]
PREFIX = "mecab "

client = discord.Client()

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

@client.event
async def on_message(message):
    print("received message: " + str(message))
    if message.content.startswith(PREFIX):
        #Does not respond if the sender is a bot
        if client.user != message.author:
            print(message.content)

            splited_message = message.content.split() #Divide by space
            splited_message.pop(0) #The beginning is"mecab"So unnecessary
            content = splited_message.pop() #Treat the end as a character string to be parsed
            option = ' '.join(splited_message) # "mecab "From"{Target character string}"Concatenate strings between
            mecab = MeCab.Tagger(option)
            m = "```" + mecab.parse(content) + "```"
            print(m)

            #Send a message to the channel to which the message was sent
            await message.channel.send(m)

client.run(TOKEN)

Deploy to heroku

heroku container:push web --app discord-bot-sample-app
heroku container:release web --app discord-bot-sample-app

If the deployment is successful, check the ** SCOPES ** on the OAuth2 page of the Discord developer page to access the URL displayed at the bottom and connect the bot to the server.

This should make the bot work (should).

How to use

mecab The operating environment is reflected in this public repository. When you message

This noun,Pronoun,General,*,*,*,Here,Click here,Click here
Particles,Attributive,*,*,*,*,of,No,No
Public noun,Change connection,*,*,*,*,Release,Kokai,Kokai
Repository noun,General,*,*,*,*,*
Particles,Case particles,General,*,*,*,To,D,D
Action noun,Change connection,*,*,*,*,motion,Dousa,Dosa
Environmental noun,General,*,*,*,*,environment,Kankyo,Kankyo
Particles,Case particles,General,*,*,*,To,Wo,Wo
Reflection noun,Change connection,*,*,*,*,Reflect,Hanei,Hanei
Verb,Independence,*,*,Sahen Suru,Continuous form,To do,Shi,Shi
Particles,Connection particle,*,*,*,*,hand,Te,Te
Yes verb,Non-independent,*,*,Five steps, La line,Continuous form,is there,Ants,Ants
Auxiliary verb,*,*,*,Special / mass,Uninflected word,Masu,trout,trout
.. symbol,Kuten,*,*,*,*,。,。,。
EOS

I get a reply like this.

mecab -d / usr / share / mecab / dic / mecab-ipadic-neologd / First, let's prepare the target character string. If you specify a NEologd dictionary like ,

This noun,Pronoun,General,*,*,*,Here,Click here,Click here
Particles,Attributive,*,*,*,*,of,No,No
Public noun,Change connection,*,*,*,*,Release,Kokai,Kokai
Repository noun,Proper noun,General,*,*,*,Repository,Repository,Repository
Particles,Case particles,General,*,*,*,To,D,D
Operating environment noun,Proper noun,General,*,*,*,Operating environment,Dousakankyo,Dosa Kankyo
Particles,Case particles,General,*,*,*,To,Wo,Wo
Reflection noun,Change connection,*,*,*,*,Reflect,Hanei,Hanei
Verb,Independence,*,*,Sahen Suru,Continuous form,To do,Shi,Shi
Particles,Connection particle,*,*,*,*,hand,Te,Te
Yes verb,Non-independent,*,*,Five steps, La line,Continuous form,is there,Ants,Ants
Auxiliary verb,*,*,*,Special / mass,Uninflected word,Masu,trout,trout
.. symbol,Kuten,*,*,*,*,。,。,。
EOS

Only the operating environment has changed, but it seems that the NEologd dictionary is used properly.

problem

With this implementation, it will receive all the messages of the server to which the bot is connected and check if the mecab string exists (I think, maybe). That is wasteful because it costs money to process most irrelevant messages.

If you implement the command, you will only be able to receive the message if the prefix and command strings are present (should, maybe).

Command version implementation

discord_command_bot.py


import os
import MeCab
import discord
from discord.ext import commands

TOKEN = os.environ["TOKEN"]

bot = commands.Bot(command_prefix='!', description='Output to results of morphological analysis.')

@bot.event
async def on_ready():
    print('Logged in as')
    print(bot.user.name)
    print(bot.user.id)
    print('------')

@bot.command()
async def mecab(ctx, *args):
    print("received message: " + str(args))
    if bot.user != ctx.message.author:
        l = list(args)
        content = l.pop() #Treat the end as a character string to be parsed
        print(content)

        option = ' '.join(l)
        mecab = MeCab.Tagger(option)
        m = "```" + mecab.parse(content) + "```"
        print(m)

        #Send a message to the channel to which the message was sent
        await ctx.send(m)

bot.run(TOKEN)

The difference from the non-command version is

Rewrite Dockerfile and deploy

Rewrite the Dockerfile to execute with the command version.

CMD ["python", "discord_commmand_bot.py"]

Deploy to heroku.

heroku container:push web --app discord-bot-sample-app
heroku container:release web --app discord-bot-sample-app

The ! Mecab command should now be valid.

Experiment

`! mecab The operating environment is reflected in this public repository. ``

This noun,Pronoun,General,*,*,*,Here,Click here,Click here
Particles,Attributive,*,*,*,*,of,No,No
Public noun,Change connection,*,*,*,*,Release,Kokai,Kokai
Repository noun,General,*,*,*,*,*
Particles,Case particles,General,*,*,*,To,D,D
Action noun,Change connection,*,*,*,*,motion,Dousa,Dosa
Environmental noun,General,*,*,*,*,environment,Kankyo,Kankyo
Particles,Case particles,General,*,*,*,To,Wo,Wo
Reflection noun,Change connection,*,*,*,*,Reflect,Hanei,Hanei
Verb,Independence,*,*,Sahen Suru,Continuous form,To do,Shi,Shi
Particles,Connection particle,*,*,*,*,hand,Te,Te
Yes verb,Non-independent,*,*,Five steps, La line,Continuous form,is there,Ants,Ants
Auxiliary verb,*,*,*,Special / mass,Uninflected word,Masu,trout,trout
.. symbol,Kuten,*,*,*,*,。,。,。
EOS

`mecab The operating environment is reflected in this public repository. ``

No reaction.

success.

Postscript

The bot goes offline soon

It works as a bot for a few minutes after deploying, but soon goes offline. Also, if you deploy or turn dyno on / off, it will return, but I want to keep it running all the time.

https://teratail.com/questions/242975

When I looked it up, it seems that it was not good to push the container as web at the time of deployment.

heroku container:push web --app discord-bot-sample-app
heroku container:release web --app discord-bot-sample-app

Redeploy as worker.

heroku container:push worker --app discord-bot-sample-app
heroku container:release worker --app discord-bot-sample-app

Certainly this didn't stop.

Recommended Posts

Create a bot that only returns the result of morphological analysis with MeCab on Discord
Output the result of morphological analysis with Mecab to a WEB browser compatible with Sakura server / UTF-8
Make a BOT that shortens the URL of Discord
Create a discord bot that notifies unilaterally with python (use only requests and json)
Let's execute the command on time with the bot of discord
Create a BOT that can call images registered with Discord like pictograms
I wrote a corpus reader that reads the results of MeCab analysis
Create a BOT that displays the number of infected people in the new corona
Make a morphological analysis bot loosely with LINE + Flask
# Function that returns the character code of a string
Create a shape on the trajectory of an object
A server that returns the number of people in front of the camera with bottle.py and OpenCV
Create a new csv with pandas based on the local csv
[Python] Morphological analysis with MeCab
I made a LINE BOT that returns parrots with Go
An example of a mechanism that returns a prediction by HTTP from the result of machine learning
I made a class to get the analysis result by MeCab in ndarray with python
Create a Twitter BOT with the GoogleAppEngine SDK for Python
[Completed] bot that posts the start notification of Nico Nico Live Broadcasting to Discord on discord.py
I created a Discord bot on Docker that reports the number of corona infected people in Tokyo at a specified time.
Tornado-Let's create a Web API that easily returns JSON with JSON
[Concept] bot that posts the start notification of Nico Nico Live Broadcasting to Discord on discord.py
The story of making a question box bot with discord.py
Yield in a class that inherits unittest.TestCase didn't work with nose (depending on the version of nose?)
The story of creating a bot that displays active members in a specific channel of slack with python
Save the result of the life game as a gif with python
Feature extraction by TF method using the result of morphological analysis
Create a word cloud with only positive / negative words on Twitter
Create REST API that returns the current time with Python3 + Falcon
[LINE Messaging API] Create a BOT that connects with someone with Python
I made a slack bot that notifies me of the temperature
From the introduction of JUMAN ++ to morphological analysis of Japanese with Python
The story of making a module that skips mail with python
Create a compatibility judgment program with the random module of python.
I played with Mecab (morphological analysis)!
Create a bot that posts the number of people positive for the new coronavirus in Tokyo to Slack
A story that visualizes the present of Qiita with Qiita API + Elasticsearch + Kibana
The story of making a university 100 yen breakfast LINE bot with Python
The story of developing a web application that automatically generates catchphrases [MeCab]
How to create a wrapper that preserves the signature of the function to wrap
The result of making the first thing that works with Python (image recognition)
Tweet the weather forecast with a bot
I want to create an API that returns a model with a recursive relationship in the Django REST Framework
The story of creating Botonyan that returns the contents of Google Docs in response to a specific keyword on Slack
Create a bot that boosts Twitter trends
I made a LINE BOT that returns a terrorist image using the Flickr API
Create a bot with AWS Lambda that automatically starts / stops Instances with specific tags
[pyqtgraph] Understand SignalProxy and create a crosshair that follows the cursor on the graph
How to quickly create a morphological analysis environment using Elasticsearch on macOS Sierra
Around the authentication of PyDrive2, a package that operates Google Drive with Python
[kotlin] Create an app that recognizes photos taken with a camera on android
The story of making a web application that records extensive reading with Django
The story of the learning method that acquired LinuC Level 1 with only ping -t
I tried to make a translation BOT that works on Discord using googletrans
[Discode Bot] I created a bot that tells me the race value of Pokemon
The story of making a Line Bot that tells us the schedule of competitive programming
I tried to create a model with the sample of Amazon SageMaker Autopilot
A model that identifies the guitar with fast.ai
Tweet the weather forecast with a bot Part 2
Create a LINE BOT with Minette for Python
Create a page that loads infinitely with python