Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

受講生(現役生または研修生)が入会したときに分報チャンネルを自動で作成する #6185

Merged
merged 4 commits into from
Mar 11, 2023

Conversation

maeda-m
Copy link
Contributor

@maeda-m maeda-m commented Feb 8, 2023

Issue

概要

Discord周りで最終的にやりたい状態としては下記があります。

  1. 入会時に自動で分報チャンネルを作る
  2. 退会時に自動で分報チャンネルを消す
  3. 退会時に自動でkickする

このプルリクエストでは 1 の入会時に自動で分報チャンネルを作成し、
2 の動作に向けて分報チャンネルのIDをDB( users.times_id )に保存するまでの範囲となります。
つまり、2から3の動作はこのプルリクエストの範囲外です。

また分報チャンネルの作成方針としては次の規則があります。

  • 分報チャンネル名はフィヨルドブートキャンプアカウントだけにする
  • 分報チャンネルのカテゴリーはIDを環境変数で指定できること
    • 技術的にはカテゴリー名で指定可能ですが、カテゴリー名が変更された場合を考慮しています

変更確認方法

  1. feature/auto-create-of-times-channel-when-joined をローカルに取り込みます
  2. bundle exec rails db:drop を実行します
  3. bin/setup を実行します
  4. 後述の「注意・伝達事項」にある3つの環境変数を設定します
  5. bin/rails s でサーバーを立ち上げます
  6. http://localhost:3000 にアクセスして未ログインであることを確認します
  7. http://localhost:3000/users/new にアクセスし現役生として会員登録をします
  8. http://localhost:3000/users/new?company_id=636488896&role=trainee&token=token にアクセスし研修生として会員登録をします
  9. http://localhost:3000/users/new?company_id=636488896&role=adviser&token=token にアクセスしアドバイザー登録をします
  10. 7 と 8 で会員登録したアカウント名の分報チャンネルが作成されていることを確認します

discord-times

Screenshot

画面上の変更はありません。

注意・伝達事項

Discord Bot を参加させる Discord サーバーのIDを取得する

Note

確認用の Discord サーバーを作成する場合は #5454 ようにサーバーを新規作成してください(webhookURLの取得は不要です)。

アイコンを右クリックして、コンテキストメニュー「IDをコピー」をクリックして控えます。

discord_001

分報チャンネルのカテゴリーのIDを取得する

Note

確認用の カテゴリーを作成する場合は、Discord サーバー名の右側にあるボタン「∨」をクリックすると作成メニューが表示されます。

ユーザー設定 > 詳細設定 > 開発者モード をONにしてから
カテゴリーを右クリックして、コンテキストメニュー「IDをコピー」をクリックして控えます。

discord-dev-mode

Discord Bot のトークン情報を取得する

https://discord.com/developers/applications にアクセスして右上のボタン「New Application」からアプリケーションを登録し、ボットを使えるように設定します。

  1. 次の項目を入力・チェックしてアプリケーションを作成します
    • NAME: Bootcamp
    • By clicking Create, you agree to the Discord Developer Terms of Service and Developer Policy(利用規約や開発者ポリシーへの同意): チェックを入れる
  2. 左のメニューからBotをクリックし、ボタン「Add Bot」からボットを追加します
  3. Bot のトークン情報の更新と各種設定をします
    • ボタン「Copy」をクリックし、トークンをコピーして控えます
    • Authorization Flow > PUBLIC BOT のトグルボタンを OFF にします
    • Privileged Gateway Intents > SERVER MEMBERS INTENT のトグルボタンを ON にします
    • ボタン「Save Changes」をクリックします

discord_002

  1. OAuth2 > URL Generator をクリックし、Discord サーバーへ参加させるためのリンクを発行します
    • SCOPES
      • bot: チェックを入れる
    • BOT PERMISSIONS
      • Manage Channels: チェックを入れる
      • Kick Members: チェックを入れる
    • GENERATED URL
      • ボタン「Copy」をクリックし、コピーして控えます

discord_003

  1. 4でコピーしたリンクを開いて Bot を Discord サーバーへ参加させます

ボタン「認証」をクリックして画面の指示に従えばOKです。

Bot を 参加させる Discord サーバーを選びます チャンネルの管理とメンバーをキックにチェックが入っていることを確認します
discord_004 discord_005

3つの環境変数を設定する

前述の手順で発行された各キーを環境変数を設定する必要があります。

  1. DISCORD_GUILD_ID
    • 前述の「Discord Bot を参加させる Discord サーバーのIDを取得する」で控えた値です
  2. DISCORD_TIMES_CHANNEL_CATEGORY_ID
    • 前述の「分報チャンネルのカテゴリーのIDを取得する」で控えた値です
  3. DISCORD_BOT_TOKEN
    • 前述の「Discord Bot のトークン情報を取得する」の3.で控えた値です

開発環境での例として次のコマンドをターミナルで実行します:

export DISCORD_GUILD_ID=nnnnnnnnnnnnnnnnnnn
export DISCORD_TIMES_CHANNEL_CATEGORY_ID=mmmmmmmmmmmmmmmmmmm
export DISCORD_BOT_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

参考情報

@maeda-m maeda-m self-assigned this Feb 8, 2023
@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch 2 times, most recently from 514c017 to 0dbc389 Compare February 12, 2023 04:03
@maeda-m maeda-m changed the title 受講生(現役生および研修生)が入会したときに分報チャンネルを自動で作成する 受講生(現役生または研修生)が入会したときに分報チャンネルを自動で作成する Feb 12, 2023
@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch 3 times, most recently from 4f4e0f9 to 07bb779 Compare February 12, 2023 12:58
@maeda-m maeda-m marked this pull request as ready for review February 13, 2023 07:16
Gemfile Outdated
@@ -28,6 +28,7 @@ gem 'commonmarker'
gem 'data_migrate'
gem 'diffy'
gem 'discord-notifier'
gem 'discordrb', github: 'shardlab/discordrb'
Copy link
Contributor Author

@maeda-m maeda-m Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discordrb の最新リリースは v3.4.0 です。しかし、使用している Discord Web API の Version が古いです。
Discord としては v9 または v10 が利用可能となっていますが、discordrb の v3.4.0 は Discord Web API v6 が使われています。
しかしながら、GitHub の main では Discord Web API v9 が使われているため、開発版ではありますが使用しています。

@@ -83,6 +83,7 @@ def create_free_user!
UserMailer.welcome(@user).deliver_now
notify_to_mentors(@user)
notify_to_chat(@user)
Newspaper.publish(:student_or_trainee_create, @user) if @user.trainee?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#6103 (comment) にて現役生と研修生が対象となりました。

module Discord
class Server
class << self
class_attribute :guild_id, :authorize_token, instance_reader: false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テストがしやすいように外部から値を設定できるようにしています。

class_attribute :guild_id, :authorize_token, instance_reader: false

def create_text_channel(name:, parent: nil)
guild = Discord::Server.find_by(id: guild_id, token: authorize_token)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

名前が紛らわしいのですが、内部的にサーバーのことをギルドと呼んでいます。
これは Discord の開発者向けドキュメントでギルドと呼ばれているためです。


class << self
def to_channel_name(username)
username.downcase
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テキストチャンネル名には大文字の英字が使えないため、小文字に変換しています。

end

def category_id
@category_id || ENV['DISCORD_TIMES_CHANNEL_CATEGORY_ID'].presence
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テキストチャンネルのカテゴリを指定する際に、空文字を指定すると shardlab/discordrb にて 0 に変換されるため
環境変数においては presence を使用しています。

config/boot.rb Outdated

# NOTE: ボイス機能を使用しない設定です。
# https://github.com/shardlab/discordrb/wiki/Installing-libopus
ENV['DISCORDRB_NONACL'] = 'true'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

環境変数を設定しないと メッセージ が表示されるため、あらかじめ設定しています。

なお boot.rb に記述している理由は bin/rails コマンドや config/application.rb で読み込まれ、必ず Bundler.require の前に環境変数を設定するためです。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maeda-m これって他に困っている人いないんですかね?
その辺りちょっと調べてみるといい気がしました。

@@ -0,0 +1,6 @@
class AddTimesIdToUsers < ActiveRecord::Migration[6.1]
def change
# NOTE: Snowflake ID
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snowflakes という書式の ID になります。
整数のオーバーフローを防止するために、HTTP API では常に文字列で扱われるため、DBにおいても文字列で扱うようにしています。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

migrationからでもDBのカラムのコメントを付けられた気がするのでそれを利用するといいかもと思いました〜

db/schema.rb Outdated
@@ -655,6 +655,7 @@
t.string "profile_job"
t.text "profile_text"
t.string "feed_url"
t.string "times_id"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usersテーブルにあるDiscord関連のカラムを移動する提案は別議題( #6215 )として作成しています。

require 'test_helper'

module Discord
class UsersControllerTest < ActionDispatch::IntegrationTest
Copy link
Contributor Author

@maeda-m maeda-m Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test/system/sign_up_test.rb ではクレジットカード決済等の動作があるため
stub を使って機能的なテストをしやすい IntegrationTest で分報チャンネルの自動生成の挙動を確認しています。

Note
コントローラーに関するテストなので test/controllers の配下がふさわしいかと思いましたが、
意図としてはコントローラー経由で TimesChannelCreator > Discord::TimesChannel の結合を確認しているため
test/integration/discord 配下にファイルを作成しています。

@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch from 07bb779 to e8b26dc Compare February 13, 2023 09:00
# - Maximum number of server channels reached (500)
# - Maximum number of channels in category reached (50)
# - The bot doesn't have the required permission to do this!
Rails.logger.error "[Discord API] #{exception.full_message.chomp}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discord API のエラーは致命的でブートキャンプアプリ側では回復できないため、エラーログを出力しています。

@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch from e8b26dc to 7d253bb Compare February 13, 2023 12:06
app/models/discord/server.rb Outdated Show resolved Hide resolved
@maeda-m maeda-m requested a review from siso25 February 13, 2023 12:43
@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 13, 2023

@siso25 こちらのプルリクエストのレビューをお願いしたいのですが、ご都合いかがでしょうか~?

不明点や疑問点あれば遠慮なくコメントください😀

@siso25
Copy link
Contributor

siso25 commented Feb 14, 2023

@maeda-m
了解しました!
今日明日くらいで確認させていただこうと思いますが、よろしいでしょうか?

@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 14, 2023

@siso25 はい🙏 急ぎませんのでよろしくお願いします~

@siso25
Copy link
Contributor

siso25 commented Feb 15, 2023

@maeda-m
レビューの途中ではあるのですが、一点お聞きしたいことがあります。

discordrbについて、どなたか(komagataさんやmachidaさんなど)に相談された結果、開発中のバージョンを使うことになったのでしょうか?リリースされていないバージョンのgemを、稼働中のアプリケーションに入れることに不安を覚えたのでお聞きしました。

もし、相談の結果「gemに問題があったらその都度解決しよう」ということになったのであれば問題ないと思います!

@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 15, 2023

@siso25 質問ありがとうございます🙏

discordrbについて、どなたか(komagataさんやmachidaさんなど)に相談された結果、開発中のバージョンを使うことになったのでしょうか?リリースされていないバージョンのgemを、稼働中のアプリケーションに入れることに不安を覚えたのでお聞きしました。

別の調査 issue( #1996 (comment) ) で Discord については Gem や npm を使った方がいいという方針になったのですが
discordrb でよいか?については未確認でした🙋‍♂️ ありがとうございます💡

本日のふりかえり・計画ミーティングにて確認してみますね💡

@siso25
Copy link
Contributor

siso25 commented Feb 15, 2023

@maeda-m
お手数ですが、よろしくお願いします!

@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 15, 2023

@siso25 ご質問いただいている件、開発中バージョンの discordrb のままで進めることとなりました。

本日のふりかえり・計画ミーティングにて次の説明を行いました。

  1. discordrb の最新リリースは Discord が非推奨としている API v6 が使われている
  2. discordrb の開発中バージョンは Discord が利用可能としている API v9 が使われている
  3. Discord が非推奨としている API v6 は使えないことはないが、といっても非推奨である

@siso25 ご質問いただいたおかげで、確認の機会ができました。大変ありがとうございます🙏

Copy link
Contributor

@siso25 siso25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maeda-m
お手数おかけしました。承知しました!

動作とコードを確認しました。問題ないと思いますので、Approveさせていただきます。

@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 15, 2023

@siso25 確認ありがとうございました🙏

@maeda-m maeda-m requested a review from komagata February 15, 2023 22:41
@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 15, 2023

@komagata メンバーレビューで Approve いただきました~
レビューをお願いします🙏

end

def guild_id
@guild_id || ENV['DISCORD_GUILD_ID'].presence
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この辺りも環境変数は極力外部から注入するようにした方がいいかもです〜

@@ -0,0 +1,6 @@
class AddTimesIdToUsers < ActiveRecord::Migration[6.1]
def change
# NOTE: Snowflake ID
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

migrationからでもDBのカラムのコメントを付けられた気がするのでそれを利用するといいかもと思いました〜

@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch 2 times, most recently from 245bf8f to 44c4c9e Compare February 18, 2023 07:39
@@ -0,0 +1,9 @@
Rails.application.reloader.to_prepare do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rails.application.reloader.to_prepare のブロックを記述しないと
DEPRECATION WARNING: Initialization autoloaded the constants Discord::Server and Discord::TimesChannel. と非推奨である旨のメッセージと Rails.application.reloader.to_prepare のブロック内に記述するようにメッセージが出力されます。

@maeda-m
Copy link
Contributor Author

maeda-m commented Feb 18, 2023

@komagata コメントありがとうございます🙏
コメントいただいた点、次のとおり修正しましたので再度レビューをお願いしたいです🙋‍♂️

  • ActiveSupport::Configurable を利用して外部から環境変数を注入できるようにしました💡
  • DBのカラムのコメントについてはマイグレーションファイルを修正し、コメント(列「Description」)を psql で確認しました💡
$ psql -d bootcamp_development
psql (14.7 (Debian 14.7-1.pgdg110+1))
Type "help" for help.

bootcamp_development=# \d+ users
Table "public.users"
             Column              |            Type             | Collation | Nullable |              Default              | Storage  | Compression | Stats target | Description
---------------------------------+-----------------------------+-----------+----------+-----------------------------------+----------+-------------+--------------+--------------
 id                              | integer                     |           | not null | nextval('users_id_seq'::regclass) | plain    |             |              |
 login_name                      | character varying(255)      |           | not null |                                   | extended |             |              |
### 省略
 feed_url                        | character varying           |           |          |                                   | extended |             |              |
 times_id                        | character varying           |           |          |                                   | extended |             |              | Snowflake ID

module Discord
class Server
include ActiveSupport::Configurable
config_accessor :guild_id, :authorize_token, instance_accessor: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

便利ですね!

config/boot.rb Outdated

# NOTE: ボイス機能を使用しない設定です。
# https://github.com/shardlab/discordrb/wiki/Installing-libopus
ENV['DISCORDRB_NONACL'] = 'true'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maeda-m これって他に困っている人いないんですかね?
その辺りちょっと調べてみるといい気がしました。

@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch 2 times, most recently from b122e61 to 47ca9b2 Compare March 1, 2023 07:46
@@ -0,0 +1,14 @@
# NOTE: ボイス機能を使用しない設定です。
# https://github.com/shardlab/discordrb/wiki/Installing-libopus
ENV['DISCORDRB_NONACL'] = 'true'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gemfileの宣言に require: false を追記することで Bundler.require にて読み込み対象外とした。

@maeda-m
Copy link
Contributor Author

maeda-m commented Mar 1, 2023

@komagata コメントいただいていた件 、次のように修正しましたので再度レビューをお願いします🙏

config/boot.rb に書いていたGem読込み前の環境変数設定をinitializersに移動しました💡
具体的には こちらのコミット でGemfileの宣言に require: false を追記し
実際の require は initializers でおこなうことで、初期化処理としてまとまるようにしました。

@maeda-m maeda-m force-pushed the feature/auto-create-of-times-channel-when-joined branch from 47ca9b2 to 18db80d Compare March 6, 2023 06:03
Copy link
Member

@komagata komagata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確認させて頂きました。OKです〜🙆‍♂️

# NOTE: ボイス機能を使用しない設定です。
# https://github.com/shardlab/discordrb/wiki/Installing-libopus
ENV['DISCORDRB_NONACL'] = 'true'
require 'discordrb'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@komagata komagata merged commit 702b2c6 into main Mar 11, 2023
@komagata komagata deleted the feature/auto-create-of-times-channel-when-joined branch March 11, 2023 13:54
@github-actions github-actions bot mentioned this pull request Mar 11, 2023
11 tasks
@maeda-m
Copy link
Contributor Author

maeda-m commented Mar 11, 2023

確認ありがとうございました🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants