2コメント

【Discord.py】Pythonでdiscordのbotを作ってみた【ついでにデータベース(SQLite)】

新年、明けまして・・・まだ明けてない(12/31 22:15)けど、botを紹介してみようかなと。


スクリーンショット 2021-12-31 221829.png
スクリーンショット 2021-12-31 221850.png

こちらがヘルプ。

そもそも、私が作ったこのbotはナンのために作ったのか?というと、基礎ゼミの友達があるbotで「ユーザー別にゲームのフレンドIDを蓄積しておいて、後から閲覧することが出来る」というbotを自分で作りたいと。

で、興味を持ったので私も作ってみたという感じになる。

ちなみに現時点では、「サーバー別にDBが用意できるワケじゃない」ので、複数サーバー同時にbotを動作させるのは難しい。データの蓄積だけは出来るが、権限者であるか否かという情報もDBに蓄積させているので、セキュリティ上の問題もあるし。(サーバー自分で作ってbot突っ込んで自分を権限者として設定したらそれで全サーバーで権限者扱いになる。むちゃくちゃ☆)

あ、でも権限者識別用のカラムにサーバーID入れたら1サーバー分は設定できるか・・・

おっと、先走った。とりあえずチュートリアル説明も載せて、それからヘルプを見つつ動作の解説でもしていこう

スクリーンショット 2021-12-31 221914.png

最初に説明したとおり、このbotは「ユーザーが自身のデータをbot(を通じてサーバーのDB)に登録して、周りの人がその人のデータをbotに照会することが出来るというシステム。

これの利点は、グループでよく「一緒にゲームしましょう 募集@2」・・・といったようなシチュエーションで、絡んだことの無いような人の募集にも参加したい・・・というとき、毎回その人のフレンドID的な物を本人に聞く必要がある。しかし、botに照会することで本人が何度もIDを言う、場合によっては毎回自分のIDを調べてコピペして・・・なんて、面倒くさい。

というわけで、botに参照した方が手間が省けるという魂胆だ。

では、このbotがどういう仕組みになっているのかというと、データベースへの蓄積である。

Pythonにはsqlite3のライブラリが存在するため、Pythonで

DBに接続→カーソルを宣言する→カーソルを開き、sql文をexecute(実行)する→DBにコミットする(DBに影響を与えるSQL文であれば)→DBをクローズする

という流れになる。

そもそもデータベース(DB)とは、「データの組織的な集合」のこと。そのデータを操作する言語が「SQL」となる。

SQLと一概にいっても、DCL(Data Control Language/権限の付与、剥奪)、DDL(Data Denifition Language/テーブル作成、削除、変更)、そして主によく使われるDML(Data Manipulation Language/データの検索、追加、更新、削除)がある。今回Pythonで実行するのは、初期設定でデータを管理する大元である「テーブル」を宣言はするが、ほとんどはデータを操作するDMLだ。今回記述したsql文はDMLが大半ということ。

(このタイミングで年越した。あけおめ。)


あれ?botを紹介する記事だよねこれ。

チュートリアルを見れば使い方はある程度は把握できるだろうとは思っているが、とにかくDBに最初に自身のレコード(自分のデータを挿入する行)を追加(INSERT)して、そこから自身のカラム(自分のどのデータの情報か)にデータを更新する(UPDATE)。

具体例を挙げると、「自分はApexというゲームのIDで「example01」という名前で登録したい」なら、
その追加したいユーザーが自分のデータを入れる箱を用意(INSERT)し、自身のApexという列の情報を「example01」で更新(UPDATE)する。
で、データを追加することが出来る。

この表は「test」というテーブルApexminecraftoverwatch
「ここのデータをexample01にしたい」
・・・・・・
you・・・・・・・・・

SQLで表すと、
UPDATE test SET Apex = example01 WHERE user_name = 俺
となる。

「botにsqlを実行させて、データを追加させるワケね。でも、俺sql一切知らないよ?↑のSQLで表すと、といわれてもピンとこないし、難しい。使えないよこのbot!」

って声が聞こえてきそうだが、それを簡略化するためにPythonでかいたわけだ。

まず、INSERTがチュートリアルの①にあたる。
>adduser
と実行するだけ。これで自身のデータを入れる箱(レコード)を勝手に作ってくれる。

②がさっきのUPDATEうんぬん。
これは >mycolumnedit 追加先 追加するデータ
例えば、さっきの「俺のApexの項目(フィールド)をexample01にしたい」なら、上記のSQL文を書かずとも
>mycolumnedit Apex example01
で終わる。

・・・「比較的」、簡単にはなっているでしょう?

③はデータ参照。
SQLで言えば
SELECT * FROM items WHERE user_name = 俺
これで「俺」に登録されている全項目を取得できる。これをこのbotでやるなら、
>info ユーザ名
だけでいい。ユーザ名を入力しても、ユーザをメンションしてそのまま引数として送信してもちゃんと表示できる。ちなみに、データに登録されていないユーザである場合はエラーを返すが、botが止まるとかそういうことは起きない。
(メンションの場合は気にしないでいいが、非メンションの場合は末尾4桁のID迄入力してください。 俺#0000 等)

データベースをパッとbot利用者に理解しろと言っても無理難題が過ぎる。なので、超簡略化して目的を決め(このbotはユーザーのデータ蓄積の目的)、簡略化することで身近にDBのメリットを有効活用できるようにした。というのがこのbotとなる。

あと、ちょっと出てきた「俺のApexの項目にexample01と設定する・・・」っていうのの「Apex」は権限者に追加してもらう必要があるので注意。

例えば、「タイタンフォール2のIDも蓄積できるようにしたいな・・・」なら、
SQL:ALTER TABLE test ADD COLUMN Titanfall2 STRING ※これはDMLではなくDDLの文
・・・めんどいね。
このbotなら
>addcolumn Titanfall2
でok。

こう考えるとかなり簡略化できていることが分かるだろう。

一応、このbotはまだ未稼働という状態にしてある。
この記事で機能の大部分は紹介したが、先述したとおりDBを全サーバー統一で管理するため管理者権限的な問題もあるし、オマケ機能でSQL 文を実行する機能もある。これも実際に動かすならセキュリティの問題もあるから消す必要がある(じゃあ何で実装した)

蛇足だが、ユーザーidでちゃんと識別できるようにしてあるので、同一名でデータが競合してしまうと言うことはない。


このbotは正直、ちゃんと整備してちゃんとしたサーバー用意したら稼働してもいいんじゃないかなって思ってるので、改善したらまた記事にまとめるかも知れない。乞うご期待!

ていうか結局データベースの話大半になった、カテゴリどうしよ。。。

この記事へのコメント

  • さすらいの駆け出しエンジニア

    DB設計として、
    ユーザーTBL:純粋にユーザーを管理するだけのテーブル
    ゲームTBL:ゲームのタイトルが登録されたTBL
    IDTBL:ユーザーテーブルの情報とゲームテーブルの情報を持つ中間TBLでここにゲームIDが入ってるイメージ
    管理者TBL:管理者のIDが入ったTBL(ここで管理者の権限を判定)

    という設計はいかがでしょう?
    こうすればSQL内で管理者かどうか判定でき、
    やるゲームが増えた際にもすぐに対応ができます!
    2023年08月19日 15:41
  • 猫山さん。



    >さすらいの駆け出しエンジニアさん
    >
    >DB設計として、
    >ユーザーTBL:純粋にユーザーを管理するだけのテーブル
    >ゲームTBL:ゲームのタイトルが登録されたTBL
    >IDTBL:ユーザーテーブルの情報とゲームテーブルの情報を持つ中間TBLでここにゲームIDが入ってるイメージ
    >管理者TBL:管理者のIDが入ったTBL(ここで管理者の権限を判定)
    >
    >という設計はいかがでしょう?
    >こうすればSQL内で管理者かどうか判定でき、
    >やるゲームが増えた際にもすぐに対応ができます!

    ありがとうございます!確かにその設計の方が柔軟性があり管理しやすくて良さそうです!
    2023年11月14日 16:51