-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgoogle_calendar
executable file
·147 lines (116 loc) · 3.94 KB
/
google_calendar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env ruby
# Follow the instructions for the Google Calendar Ruby quickstart app here:
# https://developers.google.com/google-apps/calendar/quickstart/ruby
#
# Additionally I had to do this because I kept getting "certificate verify failed" errors
# export SSL_CERT_FILE="/usr/local/etc/openssl/cert.pem"
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/storage'
require 'google/api_client/auth/storages/file_store'
require 'fileutils'
APPLICATION_NAME = 'Calendar API Quickstart'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials',
"calendar-api-quickstart.json")
SCOPE = 'https://www.googleapis.com/auth/calendar.readonly'
ACTION_MAP = {
'open_next' => :open_next_meeting,
'list' => :list_upcoming
}
ONE_HOUR = 3600
class GoogleCalendar
attr_accessor :client, :calendar_api, :action
def self.default_action
"open_next_meeting"
end
def default_action
self.class.default_action
end
# Initialize the API
def initialize(action)
@action = ACTION_MAP[action] || self.default_action
@client = Google::APIClient.new(:application_name => APPLICATION_NAME)
@calendar_api = client.discovered_api('calendar', 'v3')
client.authorization = authorize
end
def execute_action
self.send(action)
end
private
##
# Ensure valid credentials, either by restoring from the saved credentials
# files or intitiating an OAuth2 authorization request via InstalledAppFlow.
# If authorization is required, the user's default browser will be launched
# to approve the request.
#
# @return [Signet::OAuth2::Client] OAuth2 credentials
def authorize
FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))
file_store = Google::APIClient::FileStore.new(CREDENTIALS_PATH)
storage = Google::APIClient::Storage.new(file_store)
auth = storage.authorize
if auth.nil? || (auth.expired? && auth.refresh_token.nil?)
app_info = Google::APIClient::ClientSecrets.load(CLIENT_SECRETS_PATH)
flow = Google::APIClient::InstalledAppFlow.new({
:client_id => app_info.client_id,
:client_secret => app_info.client_secret,
:scope => SCOPE})
auth = flow.authorize(storage)
puts "Credentials saved to #{CREDENTIALS_PATH}" unless auth.nil?
end
auth
end
def open_next_meeting
# Fetch the next event
results = fetch_results
puts "*** results.data.items = #{results.data.items}" if debug?
event = results.data.items.first
puts "*** event.inspect = #{event.inspect}" if debug?
if event && event.hangoutLink
puts "Opening hangout for #{event.summary}"
`open #{event.hangoutLink}` if !debug?
end
rescue
puts "Event #{event.summary} has no hangout link"
end
def list_upcoming(max_results=10)
# Fetch the next events for the user
results = fetch_results( { maxResults: max_results, timeMax: (Time.now + ONE_HOUR * 1).iso8601 } )
puts "Upcoming events:"
puts
puts "No upcoming events found" if results.data.items.empty?
results.data.items.each do |event|
start = event.start.date || event.start.date_time
puts "- #{event.summary} (#{start}) #{event_link(event)}"
end
end
def event_link(event)
begin
"- #{event.hangoutLink}"
rescue NoMethodError
''
end
end
def fetch_results(options={})
defaults = {
:calendarId => 'primary',
:maxResults => 1,
:singleEvents => true,
:orderBy => 'startTime',
:timeMin => Time.now.iso8601,
:timeMax => (Time.now + ONE_HOUR).iso8601
}
parameters = defaults.merge(options)
puts "*** parameters.inspect = #{parameters.inspect}" if debug?
client.execute!(
:api_method => calendar_api.events.list,
:parameters => parameters
)
end
def debug?
false
end
end
GoogleCalendar.new(ARGV[0]).execute_action