junohm410 / fjord-flea-market

A closed flea market app for FjordBootCamp members to easily buy and sell items within the community, featuring automated buyer selection and Discord notifications.
0 stars 0 forks source link

Discord経由で通知させる方法を調べる #16

Closed junohm410 closed 5 months ago

junohm410 commented 5 months ago

📝まず作ったBotが正常に作動するか確認。

discordrbにサンプルのBotプログラムがあるので、それが動くかで検証。 rakeファイルに書いてみる。

namespace 'discordbot' do
  desc 'sample bot'
  task ping: :environment do
    bot = Discordrb::Bot.new token: ENV['DISCORD_BOT_TOKEN']

    bot.message(with_text: '勉強してます') do |event|
      event.respond 'お疲れ様です〜'
    end

    bot.run
  end
end

rake discordbot:pingを実行。

Image

注意: Botの設定で以下を有効にする必要あり Privileged Gateway IntentsMESSAGE CONTENT INTENTPRESENCE INTENT https://eatplaynap329.hatenablog.jp/entry/2022/02/11/172908

junohm410 commented 5 months ago

HTTP API でBot経由で指定のチャンネルにメッセージを送る際のエンドポイントは/channels/{channel.id}/messageshttps://discord.com/developers/docs/resources/channel#create-message ラッパーgemであるDiscordrbで対応するメソッドはDiscordrb::API::Channel.create_messagehttps://www.rubydoc.info/gems/discordrb/Discordrb/API/Channel#create_message-class_method

このメソッドの第五引数(embeds)に設定用のオブジェクト(ハッシュを入れた配列)を渡すことで、メッセージに装飾されたメッセージを埋め込むことができる。 設定オブジェクトの形式は下記を参照。 https://discord.com/developers/docs/resources/channel#embed-object またそれを簡単にシミュレーションができるサイトがある。 https://leovoel.github.io/embed-visualizer/

例として商品登録時にチャンネルにメッセージを送ってみる。

# ItemsContoroller

  def create
    @item = Item.new(item_params)

    if @item.save
      Discordrb::API::Channel.create_message(
        "Bot #{ENV['DISCORD_BOT_TOKEN']}",
        ENV['DISCORD_CHANNEL_ID'],
        "#{@item.name}が出品されました!",
        false, #第四引数はメッセージがtts(text-to-speech)かどうか
        [{
          title: @item.name,
          description: "#{@item.description}\n価格: #{@item.price}円",
          color: 16_083_556,
          timestamp: @item.created_at,
          url: item_url(@item)
        }]
      )

Image

検証なのでとりあえずコントローラーに処理を書いたが、実際はメッセージを送るための状態と処理を持つクラスを作り、いろいろな通知シナリオに対応できるようにする。

プロトタイプでの実装: https://github.com/junohm410/fbc-flema-prototype/pull/5

junohm410 commented 3 months ago

📝Webhooksでメッセージを送る方法

上記はBotを介したメッセージ送信方法だが、特定のチャンネルにメッセージを送るだけであればWebhooksが便利。Botや認証が不要。

Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use.

https://discord.com/developers/docs/resources/webhook https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks

WebhookのURLの取得方法 https://qiita.com/Yukiha_2019/items/35a3f4a8e521652f3473

discordrbはwebhooksのためのラッパーも用意してくれている。 https://github.com/shardlab/discordrb?tab=readme-ov-file#webhooks-client

      client = Discordrb::Webhooks::Client.new(url: ENV['DISCORD_WEBHOOK_URL'])
      client.execute do |builder|
        builder.content = "#{@item.name}が出品されました!\nチェックしてみてね"
        builder.username = '出品通知'
        builder.add_embed do |embed|
          embed.title = @item.name
          embed.description = "#{@item.description}\n価格: #{@item.price}円"
          embed.color = 16_083_556
          embed.timestamp = @item.created_at
          embed.url = item_url(@item)
        end

Image

usernameはWebhookを作成するときに作った名前をオーバーライドして、そのメッセージの投稿者の名前として使われる。

POSTで送れるパラメータ一覧 https://discord.com/developers/docs/resources/webhook#execute-webhook 上記に対応するbuilderクラスのリファレンス https://drb.shardlab.dev/v3.4.0/Discordrb/Webhooks/Builder.html

executeメソッドのリファレンス https://drb.shardlab.dev/v3.4.0/Discordrb/Webhooks/Client.html#execute-instance_method

embedクラスのリファレンス https://drb.shardlab.dev/v3.4.0/Discordrb/Webhooks/Embed.html