Skip to content

Instantly share code, notes, and snippets.

@smallmake
Last active June 13, 2019 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smallmake/af44ae48d918af909d156eb0af8e722c to your computer and use it in GitHub Desktop.
Save smallmake/af44ae48d918af909d156eb0af8e722c to your computer and use it in GitHub Desktop.
NHKの番組情報APIを使って番組情報を取得しキーワードで検索して通知します
#! /usr/bin/env ruby
require "faraday"
require "json"
require "time"
require "csv"
require "mail"
require "active_support/all"
NHK_API_KEY = ENV['NHK_API_KEY']
# メール送信用アカウントと送信先
GMAIL_APP_USERNAME = ENV['GMAIL_APP_USERNAME']
GMAIL_APP_PASSWORD = ENV['GMAIL_APP_PASSWORD']
GMAIL_ADDRESS = ENV['GMAIL_ADDRESS']
# 居住地(属するNHK地方局地域)
REGION_CODE = "260" #京都
# 興味対象のジャンルとキーワード "0000": "ニュース/報道(定時・総合)","0205": "情報/ワイドショー(グルメ・料理)","0800": "ドキュメンタリー/教養(社会・時事)" など
GENRE_CODES = %w(00 02 08)
# 検索キーワード(英数字も全角にすること)
KEYWORDS = %w(UFO 超能力 超常現象 光琳 若冲 宗達 応挙 其一 探幽 琳派 狩野派 アールヌーボー アール・ヌーボー)
# その他
LOG_FILE = "nhkkw.log" # 既に取得済みの番組は2回目以降除外するためのログファイルのファイル名です
NHK_CHANNELS = {"g1": "NHK総合", "e1": "NHK教育", "s1": "BS1", "s3": "BSプレミアム"}
# 値があるかチェック
REQUIREMENTS = %w(NHK_API_KEY REGION_CODE KEYWORDS LOG_FILE)
no_values = []
REQUIREMENTS.each do | requirement |
eval("no_values << %(#{requirement}) if #{requirement}.blank?")
end
unless no_values.empty?
puts "以下の変数に値がありません。\n" + no_values.join("\n")
exit
end
if !File.exist?(LOG_FILE)
File.write(LOG_FILE, '')
end
logs = CSV.read(LOG_FILE) # <id>,<start time>
# 1週間分の日付の配列をつくる
target_dates = []
target_date = Time.new()
7.times do
target_dates << target_date.strftime("%Y-%m-%d")
target_date = Time.new(target_date.year, target_date.month, target_date.day + 1, 0, 0, 0)
end
# コネクションを準備
conn = Faraday::Connection.new(:url => 'https://api.nhk.or.jp') do |builder|
builder.use Faraday::Request::UrlEncoded # リクエストパラメータを URL エンコードする
#builder.use Faraday::Response::Logger # デバグ用:リクエストを標準出力に出力する
builder.use Faraday::Adapter::NetHttp # Net/HTTP をアダプターに使う
end
# 指定チャンネルの番組情報を取得してキーワードを検索
result_message = ""
target_dates.each do |target_date|
NHK_CHANNELS.each do |channel_id, channel_name|
response = conn.get("/v2/pg/list/#{REGION_CODE}/#{channel_id}/#{target_date}.json?key=#{NHK_API_KEY}")
body = JSON.parse(response.body)
program_list = body["list"]["#{channel_id}"]
program_list.each do |program|
# 情報をバッファに取っておく
program_id = program["id"]
start_time = Time.parse(program["start_time"]).strftime("%Y/%m/%d %H:%M") if program["start_time"] != ''
end_time = Time.parse(program["end_time"]).strftime("%H:%M") if program["end_time"] != ''
title = program["title"]
subtitle = program["subtitle"]
content = program["content"]
act = program["act"]
genres = program["genres"]
# このうちtitle + subtitle + content + actにキーワードがあるか検査
words = title + subtitle + content + act
hit_flag = false
hit_words = []
KEYWORDS.each do |keyword|
if words.match(keyword)
hit_flag = true
hit_words << keyword
end
end
# 設定ジャンルに含まれているか検査(最初の2桁で検査します)
if GENRE_CODES.present?
genres.map! {|genre| genre[0,2] }
hit_flag &= !(genres & GENRE_CODES).empty?
end
# 既に送信しているかチェック
logs.each do |log|
log_program_id, log_start_time = log
hit_flag = false if log_program_id == program_id # 既にあれば除外
end
if hit_flag
result_message << "#{start_time}-#{end_time}:#{channel_name}:#{title}【#{hit_words.join(',')}】\n"
result_message << "#{subtitle}\n" if !"#{subtitle}".empty?
result_message << "#{content}\n" if !"#{content}".empty?
result_message << "----------\n"
logs << [program_id, program["start_time"]] # ログに追加
end
end
end
end
# メール送信せず表示するだけなら
puts result_message
# メールで送信
if !result_message.empty? && (GMAIL_APP_USERNAME || GMAIL_APP_USERNAME || GMAIL_APP_PASSWORD)
puts "-------- mail send --------"
mail = Mail.new do
from "#{GMAIL_ADDRESS}"
to "#{GMAIL_ADDRESS}"
subject "NKH番組キーワード監視通知"
end
mail.text_part do
body result_message
content_type 'text/plain; charset=UTF-8'
end
mail.delivery_method :smtp, { address: 'smtp.gmail.com',
port: 587,
domain: "#{GMAIL_ADDRESS}".split('@').last,
user_name: "#{GMAIL_APP_USERNAME}",
password: "#{GMAIL_APP_PASSWORD}" }
mail.deliver!
end
# logのクリーンアップ(終わったものは削除)
yesterday_date = Time.new().yesterday
CSV.open(LOG_FILE, "wb") do |csv|
logs.each do |log|
log_program_id, log_start_time = log
if Time.parse(log_start_time) > yesterday_date
csv << log
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment