https://kingyo-bachi.blogspot.jp/2017/04/line-bot-apiline-messaging-api.html
LINEに電車遅延情報を送ってみるに続き、Google Calendarの情報を送ってみます。
Google Calendarの情報を取得するには、
rubyでGoogle Calendarをいじる
を参考にしていただけたらと思います。
google-api-clientを利用するのですが、今回は古いバージョンの0.6.4を利用します。
最新バージョンでは結構使い方が変わっているようです。
そして情報を取得したいユーザのoauth情報を取得した「.google-api.yaml」を作成しておいて以下のプログラムと同じ場所に置いておきます。
以下は明日の予定をチェックして予定があればLINEに通知するものになります。
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
# coding: utf-8 | |
require 'rest-client' | |
require 'json' | |
require 'date' | |
require 'gmail' | |
require 'yaml' | |
#google-api-clientはv0.6.4が必要です | |
require "google/api_client" | |
class MyMail | |
#GMail関連の設定 | |
ID = "GMail address" | |
PW = "GMail password" | |
TO = "mail send to address" | |
def self.send(sbj,msg) | |
gmail = Gmail.new(ID, PW) | |
message = | |
gmail.generate_message do | |
to TO | |
subject sbj | |
body msg | |
end | |
gmail.deliver(message) | |
gmail.logout | |
end | |
end | |
class LineBot | |
#LINE関連の設定 | |
ID = "Channel ID" | |
SECRET = "Channel Secret" | |
MID = "MID" | |
TO = "送信先のID" | |
def self.send(msg) | |
headers = { | |
"Content-Type" => "application/json; charser=UTF-8", | |
"X-Line-ChannelID" => ID, | |
"X-Line-ChannelSecret" => SECRET, | |
"X-Line-Trusted-User-With-ACL" => MID | |
} | |
params = { | |
to: [TO], | |
toChannel: "1383378250", | |
eventType: "138311608800106203", | |
content: { | |
contentType: 1, | |
toType: 1, | |
text: msg, | |
} | |
} | |
RestClient.post "https://trialbot-api.line.me/v1/events", params.to_json, headers | |
end | |
end | |
class GCal | |
def initialize(list) | |
@g_list = list | |
yaml_path = File.expand_path(".google-api.yaml",File.dirname(__FILE__)) | |
oauth = YAML.load_file(yaml_path) | |
@client = Google::APIClient.new({:application_name => "line_bot_gcal",:application_version => "1.0"}) | |
@client.authorization.client_id = oauth["client_id"] | |
@client.authorization.client_secret = oauth["client_secret"] | |
@client.authorization.scope = oauth["scope"] | |
@client.authorization.refresh_token = oauth["refresh_token"] | |
@client.authorization.access_token = oauth["access_token"] | |
if @client.authorization.refresh_token && @client.authorization.expired? | |
@client.authorization.fetch_access_token! | |
end | |
@service = @client.discovered_api('calendar', 'v3') | |
end | |
def get_gids | |
gcal_list = @client.execute(:api_method => @service.calendar_list.list) | |
gcal_ids = [] | |
gcal_list.data.items.each do |c| | |
gcal_ids.push [c["summary"],c["id"]] if @g_list.include? c["summary"] | |
end | |
gcal_ids | |
end | |
def get_event(day) | |
@day = day | |
gcal_ids = get_gids | |
params = {} | |
params['timeMin'] = Time.utc(day.year, day.month, day.day, 0).iso8601 | |
params['timeMax'] = Time.utc(day.year, day.month, day.day, 23, 59, 60).iso8601 | |
@event = {} | |
gcal_ids.each do |gcal| | |
params['calendarId'] = gcal[1] | |
params.delete("pageToken") unless params["pageToken"].nil? | |
events = @client.execute(:api_method => @service.events.list,:parameters => params) | |
while true | |
events.data.items.each do |e| | |
@event[gcal[0]] = [] if @event[gcal[0]].nil? | |
@event[gcal[0]].push e | |
end | |
break if !(page_token = events.data.next_page_token) | |
params["pageToken"] = page_token | |
events = @client.execute(:api_method => @service.events.list,:parameters => params) | |
end | |
end | |
end | |
def make_msg | |
d = {} | |
d[:at] = {} | |
d[:from] = {} | |
d[:to] = {} | |
day = @day.strftime("%Y-%m-%d") | |
nday = (@day + 1).strftime("%Y-%m-%d") | |
@event.each do |k,v| | |
v.each do |e| | |
next if e.status == "cancelled" | |
if e.start.date.nil? | |
if e.recurrence.size == 0 | |
next unless e.start.date_time.strftime("%Y-%m-%d") == day | |
end | |
d[:at][k] = [] if d[:at][k].nil? | |
msg = e.start.date_time.strftime("%H:%M") | |
msg = msg + " - " | |
if e.recurrence.size == 0 | |
msg = msg + e.end.date_time.strftime("%m/%d ") unless e.end.date_time.strftime("%Y-%m-%d") == day | |
end | |
msg = msg + e.end.date_time.strftime("%H:%M") | |
msg = msg + " " + e.summary | |
d[:at][k].push msg | |
else | |
type = nil | |
case | |
when ((e.start.date == day) and (e.end.date == nday)) | |
type = :at | |
when e.start.date == day | |
type = :from | |
when e.end.date == nday | |
type = :to | |
end | |
next if type.nil? | |
d[type][k] = [] if d[type][k].nil? | |
d[type][k].push e.summary | |
end | |
end | |
end | |
ret = nil | |
s = {:at => "",:from => "から",:to => "まで"} | |
["at" , "from" , "to"].each do |t| | |
t = t.to_sym | |
unless d[t].size == 0 | |
ret = ret.nil? ? "" : ret + "\n" | |
ret = ret + day + s[t] + "の予定" | |
d[t].each do |k,v| | |
ret = ret + "\n [" + k + "]" | |
v.sort.each do |e| | |
ret = ret + "\n " + e | |
end | |
end | |
end | |
end | |
ret | |
end | |
end | |
#送信したいカレンダー名を列挙する | |
GCAL_LIST = [ | |
"お仕事", | |
"記念日", | |
"遊び", | |
] | |
g = GCal.new(GCAL_LIST) | |
tmr = Date.today + 1 | |
g.get_event(tmr) | |
msg = g.make_msg | |
unless msg.nil? | |
begin | |
LineBot.send(msg) | |
rescue => e | |
print "#{Time.now.to_s} line bot error raise!\n" | |
MyMail.send "line bot error raise",e.response | |
exit | |
end | |
print "#{Time.now.to_s} send event!\n" | |
else | |
print "#{Time.now.to_s} no event.\n" | |
end |
ローカル環境で利用することを前提にしています。 送信先IDはcallbackを設定してなんとか事前に取得しておく必要があります。
これを以下のような感じでcron設定して毎日23:10に動作するようにしました。
10 23 * * * /usr/bin/ruby /home/hogehoge/ruby/line_bot/gcal_chk.rb >> /home/hogehoge/ruby/line_bot/gcal_chk.log
Google Nowを使っていれば不要な気がするけれど、いずれLINE BOT APIでグループチャットにもメッセージが送れるようになると信じて、その時はグループチャットにグループの予定を送るものとして使いたいなぁと思ってみたりしています。
0 件のコメント:
コメントを投稿