ばーろぐわにる

SIerからWEB系?インフラエンジニアにジョブチェンジした見習いの備忘録。投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。

discordbotでアナウンスページの更新を通知する

やりたいこと

ここでゲームに関するアナウンスページが更新されたとき、discordのテキストチャンネルで更新内容を告知したい

準備

gem install nokogiri

作ってみた

# encoding: utf-8
require 'discordrb'
require 'open-uri'
require 'nokogiri'

bot = Discordrb::Commands::CommandBot.new token: '[接続用トークン]', prefix: '!'

bot.message(with_text: 'Ping!') do |event|
  event.respond 'Pong!'
end

bot.run :async

loop do
  # 5分ごとにアナウンスページを確認して、差分があれば内容を通知

  # HTML解析
  doc = Nokogiri::HTML.parse(open('http://3on3.fsgames.com/en/news/announcement/ps4#'))

  # 一番新しいトピックタイトルを取得
  node = doc.xpath('//div[@class="news_content no_img"]')
  now_topic = node[0].css('strong').inner_text

  # 前回取得したトピックから更新があれば通知
  if now_topic != File.read('data/sitecheck/current.txt') then
  
    # brタグを"\n"に変換
    doc.search('br').each do |br|
      br.replace("\n")
    end

    msg = <<-EOS
アナウンスページが更新されました
「#{now_topic}」

#{doc.at_xpath(&quot;//div[@class = &#039;i_contents&#039;]&quot;).content}
http://3on3.fsgames.com/en/news/announcement/ps4# EOS bot.send_message([通知したいチャンネルID], msg) # 今回取得したトピックを保存 File.open("data/sitecheck/current.txt", "w") do |f| f.print("#{now_topic}") end end sleep(300) end

  • bot.run :asyncで以降にさらに処理を追加できる。ループなどを使って定期的な処理が可能
  • Nokogiri::HTML.parse(open('http://3on3.fsgames.com/en/news/announcement/ps4#'))URIから取得したHTMLを解析
  • doc.at_xpath("//div[@class = 'i_contents']").contentでアナウンスの内容を取得できるのだが、改行がすべて<br>で記述されている。'.content'には<br>が含まれず改行がなくて読みづらい
    • search, replaceを使って<br>\nに置換すし、'.content'でも改行が含まれるようにする
  • bot.send_messageで指定のチャンネルにメッセージを通知。事前にチャンネルIDを確認しておくか、通知チャンネルを登録するコマンドを実装する必要がある
    • チャンネルIDはテキストチャンネルで\#[チャンネル名]で分かる

あとがき

  • #everyoneにmentionしようとしたが、everyoneのmentionは特別な方法を使っているらしく実装できず
    • 通常は<@[ユーザiD]>でmentionできるが、everyone用のIDは存在してなさそう?

参考文献

https://qiita.com/mktakuya/items/5bc07b854cd253eddf3d

https://qiita.com/w650/items/e663fa2430145c456c4d