Last active
June 13, 2019 03:06
-
-
Save smallmake/af44ae48d918af909d156eb0af8e722c to your computer and use it in GitHub Desktop.
NHKの番組情報APIを使って番組情報を取得しキーワードで検索して通知します
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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