今日の最強カードは『舞い戻った死神』 pic.twitter.com/zbvIWjQFkf
— 遊戯王OCG 今日の最強カードbot (@YuGiOh_Draw) June 14, 2022
このようにランダムにカードを画像付きで一枚つぶやくTwitter botをRubyで作成します。コードは以下です。Twitterの投稿部分については特に説明を記述しません。このRubyスクリプトをcronで12:00 JSTに実行しています。
require "twitter" require "net/http" require "open-uri" require "nokogiri" def post(client) begin uri = URI.parse("https://db.ygoprodeck.com/api/v7/randomcard.php") https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true res = https.start { https.get(uri.request_uri) } card = JSON.parse res.body uri = URI.parse(card["card_images"][0]["image_url"]) img = uri.open name = card["name"].gsub(" ", "_") card_uri = "https://yugioh.fandom.com/wiki/#{name}" html = URI.open(card_uri).read # 取得したhtmlをNokogiriでパースする doc = Nokogiri::HTML.parse(html) name_ja = doc.xpath("//th[contains(., '(base)')]")[0].parent.children[1].children[1].text client.update_with_media("今日の最強カードは『#{name_ja}』", img) rescue false end end client = Twitter::REST::Client.new do |config| config.consumer_key = "" config.consumer_secret = "" config.access_token = "" config.access_token_secret = "" end while true break if post(client) end
カード画像を取得する
GET https://db.ygoprodeck.com/api/v7/randomcard.php
はランダムでカードを一枚返却してくれるJSON APIです。Net::HTTP
を使用してリクエストして、返却されたJSONをparseしています。["card_images"][0]["image_url"]
にカード画像のuriがあるので、それをopen
します。
uri = URI.parse("https://db.ygoprodeck.com/api/v7/randomcard.php") https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true res = https.start { https.get(uri.request_uri) } card = JSON.parse res.body uri = URI.parse(card["card_images"][0]["image_url"]) img = uri.open
カード名の日本語名を取得する
GET https://db.ygoprodeck.com/api/v7/randomcard.php
で取得するカード名は英語です。そのため下記のコードが、カード名を日本語に翻訳します。まずカード名のスペースを_
(アンダースコア)に変換します。https://yugioh.fandom.com/wiki/[変換後の英語カード名]
で日本語のカード名を取得することができます。カード情報のHTMLを取得した後にNokogiriを用いてパースします。カードの日本語名は<th>
タグのJapanese (base)
が値のとき、それのいとこの要素に日本語のカード名を持っています。そのためコードはdoc.xpath("//th[contains(., '(base)')]")[0].parent.children[1].children[1].text
のように魔術的な書き方をしています。ここはもっと良い書き方があると思います。興味があれば、該当HPのdomの構造を見てみてください。
name = card["name"].gsub(" ", "_") card_uri = "https://yugioh.fandom.com/wiki/#{name}" html = URI.open(card_uri).read # 取得したhtmlをNokogiriでパースする doc = Nokogiri::HTML.parse(html) name_ja = doc.xpath("//th[contains(., '(base)')]")[0].parent.children[1].children[1].text
例外処理
下記のコードでは、Twitterに画像を投稿するpostメソッドがtrueになるまでwhileで繰り返しています。理由はGET https://db.ygoprodeck.com/api/v7/randomcard.php
がトークンカードやラッシュデュエルのカードの情報を返却するためです。https://yugioh.fandom.com/wiki/[英語のカード名]
は、TCG、OCGのformatのカードのみ対応していると推測されるため、404が返却されて例外が発生します。したがってpostメソッドで例外処理を行います。postメソッドが正常実行できるまで繰り返し実行します。
while true break if post(client) end
今後の開発予定
メンションをしてくれたアカウントにランダムに1枚、カード画像をリプライしたいと考えます。