Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Pythonとrepl.itを使って無料でDiscord Botを運用してみた ~💩をつけまくってみる~

経緯

最近TRPGをDiscord上でやっているからか、かなりの頻度でDiscordでチャットをするようになりました。
そこで今回は、チャット内で多発する「うんこ」に自動的にうんこの絵文字を付けるようなBOTを開発しました。
今回のようにあまり難しいBotでなければ小一時間(経験なし)で実際に運用できることが分かりました。
是非みなさんも僕のように生活を豊かにする(意味のない)BOT開発を楽しみましょう!

こちらの記事では、Pythonの基礎知識がある方を対象に書いています。
また、「うんこ」という言葉が数え切れないほど出てきますが、ご容赦ください。

実際に開発したもの

UnkoMan
スクリーンショット 2020-06-25 23.12.54.png
スクリーンショット 2020-06-25 23.13.19.png

開発環境

Repl.it について

  • オンラインコーディングプラットフォームです
  • ブラウザに表示されたIDEからコードを実行できます
  • ウェブ上でアプリやウェブサイトの開発ができます

Uptime Robot について

  • ネットワークを(50まで)無料で監視できるサービス

Botアカウントの作成

  1. Discord Developer PortalへアクセスしてDiscordのアカウントを使ってログインします
  2. New Applicationボタンを押して、名前を付けてください
    • 私の場合はUnkoとしました スクリーンショット 2020-06-25 22.27.56.png
  3. 作成したApplicationの中に入り、Botのタブに入ります。
  4. Add Botボタンを押します

    • Botが作成された後にBotのUsernameを変更することができます
    • 私はここでUnkoManという名前を授けました。 (Save Changesを押すのを忘れないように)
    • ここでプロファイル写真の変更も可能です
    • PUBLIC BOTがオンになっているのを確認します
    • TOKENをコピーしておきます スクリーンショット 2020-06-25 22.31.54.png
  5. Guild(discord APIではGuild == Serverらしい)を作成します。Discord内(アプリの方)で"+"ボタンを押してサーバーを作成します
    スクリーンショット 2020-06-25 22.33.07.png

  6. Botをサーバーへ登録します

    • OAuth2のタブに入りSCOPES内のbotをチェックします
    • スクリーンショット 2020-06-25 22.37.20.png
    • 下にあるBOT PERMISSIONSからBOTの必要な権限もチェックします
      • 今回はテキストに対する権限だけが必要なのでSend MessagesAdd Reactionsのみをチェックしました スクリーンショット 2020-06-25 22.37.48.png
    • すると認証URLが生成されるので、コピーしてブラウザで開きます
      • ちなみに他の人が保有しているサーバーにBotを追加したい場合もこの認証URLを使います
    • 先ほど作成したサーバーを選択して認証ボタンを押します スクリーンショット 2020-06-25 22.39.03.png
  7. Botが自分のサーバーにいることを確認!
    スクリーンショット 2020-06-25 22.41.01.png

ウェブサーバー

  1. Repl.itに行き、Python replを作成します
  2. Packageタブを開きdependencyをインストールしていきます。下記を検索してインストールしてください
    • discord.py
    • Flask

スクリーンショット 2020-06-25 22.42.53.png

  1. server.pyという新規ファイルを作成します

スクリーンショット 2020-06-25 22.43.47.png

  • FlaskとThreadを使ってサーバーを作ります
  • 後でサーバーをUptime robotにpingしてもらいます
server.py
from flask import Flask
from threading import Thread

app = Flask("")

@app.route("/")
def main():
  return "UnkoMan is alive!"

def run():
  app.run("0.0.0.0", port=8080)

def keep_alive():
  t = Thread(target=run)
  t.start()

Bot

  1. .envファイルを作成します
TOKEN=先ほどコピーしておいたTOKEN
  1. main.pyにどのようなBotにしたいかを書きます。以下コードにコメントを付けて説明します

仕様

  • UNNKO_LISTに入っている言葉にうんこの絵文字を付ける
  • メンション(または、”お腹すいた”と言われたら)されたら、何かしらの返事をする
  • 新しい人が入ってきたときに自己紹介をする
main.py
import os
import discord
from server import keep_alive


# うんこに関する言葉のリスト
UNKO_LIST = ["うん", "うんこ", "poop", "うんち", "unnko", "unko", "くそ", "クソ", "糞", "大便", "排泄物", "ばば", "糞便", "crap", "feces", "manure", "shit"]


# .envからTOKENを取ってくる
TOKEN = os.getenv("TOKEN")
# 接続するためのオブジェクト
client = discord.Client()


# 起動時にログする
# @デコレーターを使ってイベントをハンドルします
@client.event
async def on_ready():
    print('UnkoMan is here')


@client.event
async def on_message(message):
    message.content = message.content.lower()

    # メッセージの送信者がBot自身だった場合は無視
    if message.author == client.user:
        return

    # メンションされたら返信
    if client.user in message.mentions:
        await reply_unko(message)

    # メッセージ自体または、メッセージの中にうんこ(うん以外)が入ってたら、うんこの絵文字
    if message.content in UNKO_LIST or any(s in message.content for s in UNKO_LIST[1:]):
        await react_unko(message)

    # 隠しコマンド:お腹すいたら、特別メッセージを送るよ
    if "お腹すいた" in message.content:
        await reply_unko(message, "お腹すいた")


async def reply_unko(message, special=""):
    if special == "お腹すいた":
        reply = "とりあえずうんこでも食っておけ(辛辣)"
    else:
        reply = f'{message.author.mention} 呼んだ?え?うんこ?あーそれは一理あるね'

    # メッセージの送信と送信したメッセージにうんこを
    sent_msg = await message.channel.send(reply)
    await react_unko(message)
    await react_unko(sent_msg)


# うんこの絵文字をメッセージに付ける
async def react_unko(message):
    await message.add_reaction("💩")


# 新しい人が入ってきたとき
@client.event
async def on_member_join(member):
    # guildはdiscord内のserverのこと
    for channel in member.guild.channels:
        # generalチャンネルでの自己紹介
        if str(channel) == "general":
            await channel.send_message(f"""初めまして {member.mention}さん うんこマンです!""")

# ウェブサーバーを起動する
keep_alive()

# Discordへ接続
client.run(TOKEN)

Repl.it内のrunボタンを押して実行!

これでDiscord上のサーバーであなたのBotが動いているはずです!

気をつけなければいけないのは、repl.itではアクティビティがない状況が1時間続くとreplがオフラインになるとこです。
対策としてUptime Robotを使いBotを365日24時間稼働させる方法を説明します

Uptime Robot

  1. Uptime Robotにてアカウントを作成します
  2. + Add New Monitorボタンを押します
    スクリーンショット 2020-06-25 22.47.38.png

  3. Monitor TypeHTTP(S)Friendly Nameに好きな名前、URLをrepl.itで表示されていたものに、Monitoring Intervalevery 30 minutesに設定してreplがオフラインにならないように設定します

    • エラーが起きたときようにAlert Contacts To Notifyをチェックしておきます
  4. Create Monitorボタンを押して完成です!
    スクリーンショット 2020-06-25 22.50.01.png

 追記

  • "Repl it being just another host, won't be able to host it 24/7 so it will have a downtime of a few minutes within every 24 hours" なので365日24時間は稼働できないようです。24時間中数分はダウンタイムがあるようですが、この際目を瞑りましょう...

終わりに

いかがでしたでしょうか?納得のいくBotが作れましたか?
もし、より機能を充実させてたいのであれば、ドキュメントを読むことをお勧めします。

関連記事にQiitaの記事を載せているのですが、どうやらHerokuでもBotなら無料でホスティングができるようです。Herokuは、ウェブアプリでの開発でしか使ったことがなかったので、勘違いをしていましたが、どうやら"Heroku の無料プランでは30分動作しないWebアプリケーションはスリープしますが、 紹介した手順ではwebプロセスを使用していないため、問題なく常時稼働します。"とのことです。
まあ、Procfileやらなんやら他にもファイルを作らなければならないので、repl.itで実装した方が面倒くさくないなぁ...笑

今回作成したBotですが、どなたか実用されたい方がいればどうぞ UnkoMan を是非よろしくお願いします。

また、UnkoMan最高など、何かコメント・質問があれば是非お知らせください!

関連記事・参考にしたもの

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away