Merge pull request #2047 from albertsun/update-google-api-client

Update google-api-client and Google agents
This commit is contained in:
Akinori MUSHA 2017-08-01 22:46:43 +09:00 committed by GitHub
commit cec6ce1a56
11 changed files with 481 additions and 829 deletions

View file

@ -2,6 +2,7 @@
| DateOfChange | Changes |
|----------------|--------------------------------------------------------------------------------------------------------------|
| Jul 10, 2017 | Update Google API Client. May break backwards compatibility for GoogleCalendarPublishAgent. [2047](https://github.com/huginn/huginn/pull/2047) |
| Oct 17, 2016 | Normalize URL in `to_uri` and `uri_expand` liquid filters. |
| Oct 06, 2016 | `RssAgent` is reimplemented migrating its underlying feed parser from FeedNormalizer to Feedjira. [1564](https://github.com/cantino/huginn/pull/1564) |
| Oct 05, 2016 | Migrate to Rails 5. [1688](https://github.com/cantino/huginn/pull/1688) |

12
Gemfile
View file

@ -44,11 +44,12 @@ gem 'slack-notifier', '~> 1.0.0' # SlackAgent
gem 'hypdf', '~> 1.0.10' # PDFInfoAgent
# Weibo Agents
# FIXME needs to loosen omniauth dependency
gem 'weibo_2', github: 'dsander/weibo_2', branch: 'master'
# FIXME needs to loosen omniauth dependency, add rest-client
gem 'weibo_2', github: 'albertsun/weibo_2', branch: 'master'
# GoogleCalendarPublishAgent and GoogleTranslateAgent
gem 'google-api-client', '~> 0.7.1', require: 'google/api_client'
gem 'google-api-client', '~> 0.13'
gem 'google-cloud-translate', '~> 1.0.0', require: 'google/cloud/translate'
# Twitter Agents
gem 'twitter', github: 'sferik/twitter' # Must to be loaded before cantino-twitter-stream.
@ -56,7 +57,8 @@ gem 'twitter-stream', github: 'cantino/twitter-stream', branch: 'huginn'
gem 'omniauth-twitter', '~> 1.3.0'
# Tumblr Agents
gem 'tumblr_client', github: 'tumblr/tumblr_client', branch: 'master', ref: '0c59b04e49f2a8c89860613b18cf4e8f978d8dc7' # '>= 0.8.5'
# until merge of https://github.com/tumblr/tumblr_client/pull/61
gem 'tumblr_client', github: 'albertsun/tumblr_client', branch: 'master', ref: 'e046fe6e39291c173add0a49081630c7b60a36c7'
gem 'omniauth-tumblr', '~> 1.2'
# Dropbox Agents
@ -147,7 +149,7 @@ group :development do
end
group :test do
gem 'coveralls', '~> 0.7.4', require: false
gem 'coveralls', '~> 0.8.12', require: false
gem 'capybara', '~> 2.13.0'
gem 'capybara-screenshot'
gem 'capybara-select2', require: false

View file

@ -1,3 +1,28 @@
GIT
remote: https://github.com/albertsun/tumblr_client.git
revision: e046fe6e39291c173add0a49081630c7b60a36c7
ref: e046fe6e39291c173add0a49081630c7b60a36c7
branch: master
specs:
tumblr_client (0.8.5)
faraday (<= 1.0.0)
faraday_middleware (<= 1.0.0)
json
mime-types
oauth
simple_oauth
GIT
remote: https://github.com/albertsun/weibo_2.git
revision: ac38d04434747c4b88e86c5337cd436d00c34349
branch: master
specs:
weibo_2 (0.1.7)
hashie (~> 3)
multi_json (~> 1)
oauth2 (~> 1)
rest-client (>= 2.0)
GIT
remote: https://github.com/amatsuda/kaminari.git
revision: abbf93d557208ee1d0b612c612cd079f86ed54f4
@ -35,17 +60,6 @@ GIT
activerecord (>= 3.0, < 5.2)
delayed_job (>= 3.0, < 5)
GIT
remote: https://github.com/dsander/weibo_2.git
revision: e5b77f21a7e9a666b582c48e16b1e96fca198cf8
branch: master
specs:
weibo_2 (0.1.7)
hashie (~> 3)
multi_json (~> 1)
oauth2 (~> 1)
rest-client (~> 1.8)
GIT
remote: https://github.com/lostisland/faraday_middleware.git
revision: 59088da02940d0ee2010b2e3156343346767c31e
@ -70,20 +84,6 @@ GIT
naught (~> 1.0)
simple_oauth (~> 0.3.0)
GIT
remote: https://github.com/tumblr/tumblr_client.git
revision: 0c59b04e49f2a8c89860613b18cf4e8f978d8dc7
ref: 0c59b04e49f2a8c89860613b18cf4e8f978d8dc7
branch: master
specs:
tumblr_client (0.8.5)
faraday (~> 0.9.0)
faraday_middleware (~> 0.9)
json
mime-types
oauth
simple_oauth
PATH
remote: vendor/gems/dotenv-2.0.1
specs:
@ -135,10 +135,6 @@ GEM
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
arel (8.0.0)
autoparse (0.3.3)
addressable (>= 2.3.1)
extlib (>= 0.9.15)
multi_json (>= 1.0.0)
aws-sdk-core (2.2.15)
jmespath (~> 1.0)
bcrypt (3.1.11)
@ -189,16 +185,18 @@ GEM
colorize (0.7.7)
concurrent-ruby (1.0.5)
cookiejar (0.3.2)
coveralls (0.7.12)
multi_json (~> 1.10)
rest-client (>= 1.6.8, < 2)
simplecov (~> 0.9.1)
coveralls (0.8.21)
json (>= 1.8, < 3)
simplecov (~> 0.14.1)
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
thor (~> 0.19.4)
tins (~> 1.6)
crack (0.4.3)
safe_yaml (~> 1.0.0)
daemons (1.1.9)
debug_inspector (0.0.2)
declarative (0.0.9)
declarative-option (0.1.0)
delorean (2.1.0)
chronic
devise (4.3.0)
@ -209,7 +207,7 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.3)
docile (1.1.5)
domain_name (0.5.24)
domain_name (0.5.20170404)
unf (>= 0.0.5, < 1.0.0)
dropbox-api (0.4.2)
hashie
@ -239,8 +237,7 @@ GEM
evernote-thrift
oauth (>= 0.4.1)
execjs (2.6.0)
extlib (0.9.16)
faraday (0.9.2)
faraday (0.12.1)
multipart-post (>= 1.2, < 3)
feedjira (2.1.0)
faraday (>= 0.9)
@ -265,17 +262,29 @@ GEM
rails (>= 3.0)
globalid (0.4.0)
activesupport (>= 4.2.0)
google-api-client (0.7.1)
addressable (>= 2.3.2)
autoparse (>= 0.3.3)
extlib (>= 0.9.15)
faraday (>= 0.9.0)
jwt (>= 0.1.5)
launchy (>= 2.1.1)
multi_json (>= 1.0.0)
retriable (>= 1.4)
signet (>= 0.5.0)
uuidtools (>= 2.1.0)
google-api-client (0.13.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.5)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
google-cloud-core (1.0.0)
google-cloud-env (~> 1.0)
googleauth (~> 0.5.1)
google-cloud-env (1.0.0)
faraday (~> 0.11)
google-cloud-translate (1.0.0)
google-cloud-core (~> 1.0)
googleauth (~> 0.5.1)
googleauth (0.5.1)
faraday (~> 0.9)
jwt (~> 1.4)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
guard (2.13.0)
formatador (>= 0.2.4)
listen (>= 2.7, <= 4.0)
@ -296,7 +305,7 @@ GEM
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
hashdiff (0.3.2)
hashie (3.4.6)
hashie (3.5.5)
haversine (0.3.0)
hipchat (1.2.0)
httparty
@ -309,12 +318,13 @@ GEM
http-cookie (~> 1.0)
http-form_data (~> 1.0.1)
http_parser.rb (~> 0.6.0)
http-cookie (1.0.2)
http-cookie (1.0.3)
domain_name (~> 0.5)
http-form_data (1.0.1)
http_parser.rb (0.6.0)
httparty (0.14.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
huginn_agent (0.4.0)
thor
hypdf (1.0.10)
@ -329,7 +339,7 @@ GEM
json (1.8.6)
jsonpath (0.8.3)
multi_json
jwt (1.4.1)
jwt (1.5.6)
kgio (2.10.0)
kramdown (1.3.3)
launchy (2.4.2)
@ -345,6 +355,10 @@ GEM
listen (3.0.5)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
loofah (2.0.3)
nokogiri (>= 1.5.9)
lumberjack (1.0.10)
@ -352,17 +366,20 @@ GEM
systemu (~> 2.6.2)
mail (2.6.5)
mime-types (>= 1.16, < 4)
memoist (0.16.0)
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
method_source (0.8.2)
mime-types (2.99.3)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mimemagic (0.3.1)
mini_magick (4.2.3)
mini_portile2 (2.1.0)
minitest (5.10.2)
mqtt (0.3.1)
multi_json (1.12.1)
multi_xml (0.5.5)
multi_xml (0.6.0)
multipart-post (2.0.0)
mysql2 (0.4.8)
naught (1.1.0)
@ -371,7 +388,7 @@ GEM
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (3.0.2)
netrc (0.10.3)
netrc (0.11.0)
nio4r (2.0.0)
nokogiri (1.7.2)
mini_portile2 (~> 2.1.0)
@ -379,8 +396,8 @@ GEM
nenv (~> 0.1)
shellany (~> 0.0)
oauth (0.4.7)
oauth2 (1.2.0)
faraday (>= 0.8, < 0.10)
oauth2 (1.4.0)
faraday (>= 0.8, < 0.13)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
@ -413,6 +430,7 @@ GEM
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
orm_adapter (0.5.0)
os (0.9.6)
pg (0.18.3)
poltergeist (1.8.1)
capybara (~> 2.1)
@ -430,7 +448,7 @@ GEM
pry-rails (0.3.4)
pry (>= 0.9.10)
public_suffix (2.0.5)
rack (2.0.2)
rack (2.0.3)
rack-livereload (0.3.16)
rack
rack-test (0.6.3)
@ -470,14 +488,18 @@ GEM
rb-kqueue (0.2.4)
ffi (>= 0.5.0)
ref (2.0.0)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rest-client (1.8.0)
rest-client (2.0.2)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
retriable (2.0.2)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.0.2)
rr (1.1.2)
rspec (3.5.0)
rspec-core (~> 3.5.0)
@ -527,17 +549,17 @@ GEM
shellany (0.0.1)
shoulda-matchers (3.0.0)
activesupport (>= 4.0.0)
signet (0.5.1)
addressable (>= 2.2.3)
faraday (>= 0.9.0.rc5)
jwt (>= 0.1.5)
multi_json (>= 1.0.0)
signet (0.7.3)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
simple_oauth (0.3.1)
simplecov (0.9.2)
simplecov (0.14.1)
docile (~> 1.1.0)
multi_json (~> 1.0)
simplecov-html (~> 0.9.0)
simplecov-html (0.9.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.1)
slack-notifier (1.0.0)
slop (3.6.0)
spectrum-rails (1.3.4)
@ -560,7 +582,7 @@ GEM
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
systemu (2.6.4)
term-ansicolor (1.3.2)
term-ansicolor (1.6.0)
tins (~> 1.0)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
@ -568,7 +590,7 @@ GEM
thor (0.19.4)
thread_safe (0.3.6)
tilt (2.0.7)
tins (1.10.1)
tins (1.15.0)
treetop (1.5.3)
polyglot (~> 0.3)
twilio-ruby (3.11.6)
@ -579,18 +601,18 @@ GEM
ethon (>= 0.7.1)
tzinfo (1.2.3)
thread_safe (~> 0.1)
uber (0.1.0)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.3)
unf_ext (0.0.7.4)
unicorn (5.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uuid (2.3.7)
macaddr (~> 1.0)
uuidtools (2.1.5)
vcr (3.0.3)
warden (1.2.7)
rack (>= 1.0)
@ -631,7 +653,7 @@ DEPENDENCIES
capybara-screenshot
capybara-select2
coffee-rails (~> 4.2)
coveralls (~> 0.7.4)
coveralls (~> 0.8.12)
daemons (~> 1.1.9)
delayed_job!
delayed_job_active_record!
@ -651,7 +673,8 @@ DEPENDENCIES
foreman (~> 0.63.0)
geokit (~> 1.8.4)
geokit-rails (~> 2.2.0)
google-api-client (~> 0.7.1)
google-api-client (~> 0.13)
google-cloud-translate (~> 1.0.0)
guard (~> 2.13.0)
guard-livereload (~> 2.5.1)
guard-rspec (~> 4.6.4)

View file

@ -33,6 +33,7 @@ class ApplicationController < ActionController::Base
twitter_oauth_check
basecamp_auth_check
outdated_docker_image_namespace_check
outdated_google_auth_check
end
def filtered_agent_return_link(options = {})
@ -70,6 +71,12 @@ class ApplicationController < ActionController::Base
@outdated_docker_image_namespace = ENV['OUTDATED_DOCKER_IMAGE_NAMESPACE'] == 'true'
end
def outdated_google_auth_check
@outdated_google_cal_agents = current_user.agents.of_type('Agents::GoogleCalendarPublishAgent').select do |agent|
agent.options['google']['key_secret'].present?
end
end
def agent_params
return {} unless params[:agent]
@agent_params ||= begin

View file

@ -1,11 +1,12 @@
require 'json'
require 'google/apis/calendar_v3'
module Agents
class GoogleCalendarPublishAgent < Agent
cannot_be_scheduled!
no_bulk_receive!
gem_dependency_check { defined?(Google) && defined?(Google::APIClient) }
gem_dependency_check { defined?(Google) && defined?(Google::Apis::CalendarV3) }
description <<-MD
The Google Calendar Publish Agent creates events on your Google Calendar.
@ -20,9 +21,23 @@ module Agents
2. New project -> Huginn
3. APIs & Auth -> Enable google calendar
4. Credentials -> Create new Client ID -> Service Account
5. Persist the generated private key to a path, ie: `/home/huginn/a822ccdefac89fac6330f95039c492dfa3ce6843.p12`
5. Download the JSON keyfile and save it to a path, ie: `/home/huginn/Huginn-5d12345678cd.json`. Or open that file and copy the `private_key`.
6. Grant access via google calendar UI to the service account email address for each calendar you wish to manage. For a whole google apps domain, you can [delegate authority](https://developers.google.com/+/domains/authentication/delegation)
An earlier version of Huginn used PKCS12 key files to authenticate. This will no longer work, you should generate a new JSON format keyfile, that will look something like:
<pre><code>{
"type": "service_account",
"project_id": "huginn-123123",
"private_key_id": "6d6b476fc6ccdb31e0f171991e5528bb396ffbe4",
"private_key": "-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n",
"client_email": "huginn-calendar@huginn-123123.iam.gserviceaccount.com",
"client_id": "123123...123123",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/huginn-calendar%40huginn-123123.iam.gserviceaccount.com"
}</code></pre>
Agent Configuration:
@ -30,12 +45,9 @@ module Agents
`google` A hash of configuration options for the agent.
`google` `service_account_email` - The authorised service account.
`google` `key_file` OR `google` `key` - The path to the key file or the key itself. [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) formatting is supported if you want to use a Credential. (E.g., `{% credential google_key %}`)
`google` `key_secret` - The secret for the key, typically 'notasecret'
`google` `service_account_email` - The authorised service account email address.
`google` `key_file` OR `google` `key` - The path to the JSON key file above, or the key itself (the value of `private_key`). [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) formatting is supported if you want to use a Credential. (E.g., `{% credential google_key %}`)
Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
@ -43,6 +55,8 @@ module Agents
A hash of event details. See the [Google Calendar API docs](https://developers.google.com/google-apps/calendar/v3/reference/events/insert)
The prior version Google's API expected keys like `dateTime` but in the latest version they expect snake case keys like `date_time`.
Example payload for trigger agent:
<pre><code>{
"message": {
@ -50,10 +64,10 @@ module Agents
"summary": "Awesome event",
"description": "An example event with text. Pro tip: DateTimes are in RFC3339",
"start": {
"dateTime": "2014-10-02T10:00:00-05:00"
"date_time": "2017-06-30T17:00:00-05:00"
},
"end": {
"dateTime": "2014-10-02T11:00:00-05:00"
"date_time": "2017-06-30T18:00:00-05:00"
}
}
}</code></pre>
@ -84,7 +98,7 @@ module Agents
'calendar_id' => 'you@email.com',
'google' => {
'key_file' => '/path/to/private.key',
'key_secret' => 'notasecret',
'key' => '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
'service_account_email' => ''
}
}
@ -93,16 +107,28 @@ module Agents
def receive(incoming_events)
require 'google_calendar'
incoming_events.each do |event|
calendar = GoogleCalendar.new(interpolate_options(options, event), Rails.logger)
GoogleCalendar.open(interpolate_options(options, event), Rails.logger) do |calendar|
calendar_event = JSON.parse(calendar.publish_as(interpolated(event)['calendar_id'], event.payload["message"]).response.body)
cal_message = event.payload["message"]
if cal_message["start"].present? && cal_message["start"]["dateTime"].present? && !cal_message["start"]["date_time"].present?
cal_message["start"]["date_time"] = cal_message["start"].delete "dateTime"
end
if cal_message["end"].present? && cal_message["end"]["dateTime"].present? && !cal_message["end"]["date_time"].present?
cal_message["end"]["date_time"] = cal_message["end"].delete "dateTime"
end
create_event :payload => {
'success' => true,
'published_calendar_event' => calendar_event,
'agent_id' => event.agent_id,
'event_id' => event.id
}
calendar_event = calendar.publish_as(
interpolated(event)['calendar_id'],
cal_message
)
create_event :payload => {
'success' => true,
'published_calendar_event' => calendar_event,
'agent_id' => event.agent_id,
'event_id' => event.id
}
end
end
end
end

View file

@ -2,7 +2,7 @@ module Agents
class GoogleTranslationAgent < Agent
cannot_be_scheduled!
gem_dependency_check { defined?(Google) && defined?(Google::APIClient) }
gem_dependency_check { defined?(Google) && defined?(Google::Cloud::Translate) }
description <<-MD
The Translation Agent will attempt to translate text between natural languages.
@ -12,6 +12,8 @@ module Agents
Services are provided using Google Translate. You can [sign up](https://cloud.google.com/translate/) to get `google_api_key` which is required to use this agent.
The service is **not free**.
To use credentials for the `google_api_key` use the liquid `credential` tag like so `{% credential google-api-key %}`
`to` must be filled with a [translator language code](https://cloud.google.com/translate/docs/languages).
`from` is the language translated from. If it's not specified, the API will attempt to detect the source language automatically and return it within the response.
@ -56,7 +58,7 @@ module Agents
opts = interpolated(event)
opts['content'].each_pair do |key, value|
result = translate(value)
translated_event[key] = result.data.translations.last.translated_text
translated_event[key] = result.text
end
create_event payload: translated_event
end
@ -77,16 +79,22 @@ module Agents
@translate_service ||= google_client.discovered_api('translate','v2')
end
def cloud_translate_service
# https://github.com/GoogleCloudPlatform/google-cloud-ruby/blob/master/google-cloud-translate/lib/google-cloud-translate.rb#L130
@google_client ||= Google::Cloud::Translate.new(key: interpolated['google_api_key'])
end
def translate(value)
google_client.execute(
api_method: translate_service.translations.list,
parameters: {
format: 'text',
source: translate_from,
target: options["to"],
q: value
}
)
# google_client.execute(
# api_method: translate_service.translations.list,
# parameters: {
# format: 'text',
# source: translate_from,
# target: options["to"],
# q: value
# }
# )
cloud_translate_service.translate(value, to: interpolated["to"], from: translate_from, format: "text")
end
end
end

View file

@ -24,6 +24,27 @@ TWITTER_OAUTH_SECRET=<%= @twitter_oauth_secret %>
<% end %>
</div>
<% end -%>
<% if @outdated_google_cal_agents && @outdated_google_cal_agents.length > 0 %>
<dir class="container">
<div class="alert alert-danger" role="alert">
<p>
<b>Warning!</b> Your <b>Google Calendar Publish Agents</b> are using an outdated version of Google Auth. You need to update the agent configuration, possibly with a new keyfile from Google for it to continue to work.
<br/>
PKCS12 key files (`.p12`) are no longer supported. Instead use RSA private keys. Edit the agents to see the updated instructions. The `google.key_secret` option is no longer needed, please remove it.
<br/>
The format of parameters in events passed to the agent have also changed. Parameters now are expected in underscore_case instead of camelCase (to match Ruby convention). Please update upstream agents that send events to the calendar agent.
</p>
<p>
Outdated agents:
<ul>
<% @outdated_google_cal_agents.each do |agent| -%>
<li><%= link_to(agent.name, edit_agent_path(agent)) %></li>
<% end -%>
</ul>
</p>
</div>
</dir>
<% end -%>
<% if @outdated_docker_image_namespace %>
<dir class="container">
<div class="alert alert-danger" role="alert">

View file

@ -1,33 +1,44 @@
require 'googleauth'
require 'google/apis/calendar_v3'
class GoogleCalendar
def initialize(config, logger)
@config = config
if @config['google']['key'].present?
@key = OpenSSL::PKCS12.new(@config['google']['key'], @config['google']['key_secret']).key
else
@key = Google::APIClient::PKCS12.load_key(@config['google']['key_file'], @config['google']['key_secret'])
# https://github.com/google/google-auth-library-ruby/issues/65
# https://github.com/google/google-api-ruby-client/issues/370
ENV['GOOGLE_PRIVATE_KEY'] = @config['google']['key']
ENV['GOOGLE_CLIENT_EMAIL'] = @config['google']['service_account_email']
ENV['GOOGLE_ACCOUNT_TYPE'] = 'service_account'
elsif @config['google']['key_file'].present?
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = @config['google']['key_file']
end
@client = Google::APIClient.new(application_name: "Huginn", application_version: "0.0.1")
@client.retries = 2
@logger ||= logger
@calendar = @client.discovered_api('calendar','v3')
# https://github.com/google/google-api-ruby-client/blob/master/MIGRATING.md
@calendar = Google::Apis::CalendarV3::CalendarService.new
# https://developers.google.com/api-client-library/ruby/auth/service-accounts
# https://developers.google.com/identity/protocols/application-default-credentials
scopes = [Google::Apis::CalendarV3::AUTH_CALENDAR]
@authorization = Google::Auth.get_application_default(scopes)
@logger.info("Setup")
@logger.debug @calendar.inspect
end
def auth_as
@client.authorization = Signet::OAuth2::Client.new({
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
audience: 'https://accounts.google.com/o/oauth2/token',
scope: 'https://www.googleapis.com/auth/calendar',
issuer: @config['google']['service_account_email'],
signing_key: @key
});
def self.open(*args, &block)
instance = new(*args)
block.call(instance)
ensure
instance.cleanup!
end
@client.authorization.fetch_access_token!
def auth_as
@authorization.fetch_access_token!
@calendar.authorization = @authorization
end
# who - String: email of user to add event
@ -38,14 +49,15 @@ class GoogleCalendar
@logger.info("Attempting to create event for " + who)
@logger.debug details.to_yaml
ret = @client.execute(
api_method: @calendar.events.insert,
parameters: {'calendarId' => who, 'sendNotifications' => true},
body: details.to_json,
headers: {'Content-Type' => 'application/json'}
)
event = Google::Apis::CalendarV3::Event.new(details.deep_symbolize_keys)
ret = @calendar.insert_event(
who,
event,
send_notifications: true
)
@logger.debug ret.to_yaml
ret
ret.to_h
end
def events_as(who, date)
@ -56,14 +68,18 @@ class GoogleCalendar
@logger.info("Attempting to receive events for "+who)
@logger.debug details.to_yaml
ret = @client.execute(
api_method: @calendar.events.list,
parameters: {'calendarId' => who, 'sendNotifications' => true},
body: details.to_json,
headers: {'Content-Type' => 'application/json'}
)
ret = @calendar.list_events(
who
)
@logger.debug ret.to_yaml
ret
ret.to_h
end
def cleanup!
ENV.delete('GOOGLE_PRIVATE_KEY')
ENV.delete('GOOGLE_CLIENT_EMAIL')
ENV.delete('GOOGLE_ACCOUNT_TYPE')
ENV.delete('GOOGLE_APPLICATION_CREDENTIALS')
end
end

View file

@ -1,435 +0,0 @@
---
http_interactions:
- request:
method: get
uri: https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Linux/3.13.0-29-generic
(gzip)
Accept-Encoding:
- gzip
Content-Type:
- ''
Accept:
- "*/*"
response:
status:
code: 200
message: OK
headers:
Expires:
- Sat, 28 Jun 2014 17:21:12 GMT
Date:
- Sat, 28 Jun 2014 17:16:12 GMT
Etag:
- '"C11OM5Qtr9122-scy_WeqND9D3o/icy_kevyvyjgCKjN6s1gb_9TUZs"'
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Xss-Protection:
- 1; mode=block
Content-Length:
- '11266'
Server:
- GSE
Age:
- '195'
Cache-Control:
- public, max-age=300, must-revalidate, no-transform
Alternate-Protocol:
- 443:quic
body:
encoding: ASCII-8BIT
string: !binary |-
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
4Rn8/2/P/j8y14+toGwBAA==
http_version:
recorded_at: Sat, 28 Jun 2014 17:19:27 GMT
- request:
method: post
uri: https://accounts.google.com/o/oauth2/token
body:
encoding: ASCII-8BIT
string: grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIxMDI5OTM2OTY2MzI2LW5jamQ3Nzc2cGNzcGM5OGhzZzgyZ3NiNTZ0MzIxN2VmQGRldmVsb3Blci5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2NhbGVuZGFyIiwiYXVkIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL28vb2F1dGgyL3Rva2VuIiwiZXhwIjoxNDAzOTc2MDI3LCJpYXQiOjE0MDM5NzU5MDd9.G2t_IqQofzzXKJAySGu4MulAybOp3BjptAk_tra7-ALy2pWu0jKw8XblP4T0YPgyMcbhcSJ_OhYl7Inmkxc3xhWsN-ZQDtacIyLv9roIRbvm5zCFKceJRISu2nZuIUTGTeoVuotPh6KRRvXIk1RW_Rc7L0eLeGTWn1USqdNwlfU
headers:
Cache-Control:
- no-store
Content-Type:
- application/x-www-form-urlencoded
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
User-Agent:
- Ruby
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=utf-8
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Date:
- Sat, 28 Jun 2014 17:19:28 GMT
Content-Disposition:
- attachment; filename="json.txt"; filename*=UTF-8''json.txt
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
Alternate-Protocol:
- 443:quic
Transfer-Encoding:
- chunked
body:
encoding: UTF-8
string: |-
{
"access_token" : "ya29.MgBhhNLHjzGOZBoAAADoyvaDO5G6GHmaxIYqa5EGZ5t8kL-unXKywIRYoYgQxw",
"token_type" : "Bearer",
"expires_in" : 3600
}
http_version:
recorded_at: Sat, 28 Jun 2014 17:19:28 GMT
- request:
method: post
uri: https://www.googleapis.com/calendar/v3/calendars/sqv39gj35tc837gdns1g4d81cg@group.calendar.google.com/events?sendNotifications=true
body:
encoding: UTF-8
string: '{"visibility":"default","summary":"Awesome event","description":"An
example event with text. Pro tip: DateTimes are in RFC3339","end":{"dateTime":"2014-10-02T11:00:00-05:00"},"start":{"dateTime":"2014-10-02T10:00:00-05:00"}}'
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Linux/3.13.0-29-generic
(gzip)
Content-Type:
- application/json
Accept-Encoding:
- gzip
Authorization:
- Bearer ya29.MgBhhNLHjzGOZBoAAADoyvaDO5G6GHmaxIYqa5EGZ5t8kL-unXKywIRYoYgQxw
Cache-Control:
- no-store
Accept:
- "*/*"
response:
status:
code: 200
message: OK
headers:
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Date:
- Sat, 28 Jun 2014 17:19:31 GMT
Etag:
- '"BZUCgRsJHN1b3Y4VmmLXiJzEzGI/MjgwNzk1MTk0MTk3MjAwMA"'
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
Alternate-Protocol:
- 443:quic
Transfer-Encoding:
- chunked
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAAH1T0U7bMBR971dY3ePW1IlLmlSaRkdXRkWqCZUxKl6Mfeu6
iZ1gOw0E8e9LAh2btvFgKc49Pufce+zHHuqnUvP+BPUZzUBzat7BHrTrf2hK
4KhoSzf9z+vLE3FhF1+X/i25Hn1X6vyHXNRf6tOzYbIT1bJO/WSV4maRZDet
kulNv6OQHbfd850RocF7mpa3dp9FjJfW5zLtQNZRV9rORK430ijg3f+tU9m5
1Glb2TpX2MlwWFWVJ/JcZOCxXA0Proed608g+UdG1inVC73UZxVXc8OvFjVX
1eg6uPBZPU/plRWMzIOkzjTdJT4/TUZJzfX69KhOrhhez8T9dcCn66ozwQxQ
B10bAfZHAxwOgmjljyd+PAliD2O87nBlwf+LI9iLo/AZZ0ulqHlocdMKbK4A
vU6cg2VGFk7mugNoBPdUFdkLBlXSbZGDe+ehbyZHThYTNGtkV1KBRdQAkhpd
zE8IIfGr+9w0ZI891CSqqMxaZh8HcUzCOAxJEA402/HxeBwWzBYsjrZWRIGw
t0ehI4E/hs0xb+SzvADjCQtmLxlQxvJSuzaEfg89tVq5EVTLGv5Ws3d7Eosd
OXIsImPBtfXFiEc+E8fC5GXhHWL8LdrWfjMQaYuMPiypgpboaymk1ug8Z7Sd
UfMhnnEWsk0DcKaEFzfNpTLu4IS/zOhXOj4eYLLCuIlmgvF73GZ06AO6B/Hm
Of9f5+QJzS7PZm9f+OM/O2yM35WgWauA270B1TxIMPZgobQwgw0tM/faX++p
9xPxx2cruwMAAA==
http_version:
recorded_at: Sat, 28 Jun 2014 17:19:31 GMT
recorded_with: VCR 2.9.2

View file

@ -1,20 +1,22 @@
---
http_interactions:
- request:
method: get
uri: https://www.googleapis.com/discovery/v1/apis/translate/v2/rest?key=some_api_key
method: post
uri: https://translation.googleapis.com/language/translate/v2?key=some_api_key
body:
encoding: UTF-8
string: ''
string: '{"q":["hey what are you doing"],"target":"sv","source":"en","format":"text"}'
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Mac OS X/10.11.6
(gzip)
Accept-Encoding:
- gzip
- gcloud-ruby/1.0.0
Google-Cloud-Resource-Prefix:
- projects/
Content-Type:
- ''
- application/json
X-Goog-Api-Client:
- gl-ruby/2.3.4 gccl/1.0.0
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
response:
@ -22,154 +24,53 @@ http_interactions:
code: 200
message: OK
headers:
Expires:
- Tue, 25 Apr 2017 10:49:56 GMT
Date:
- Tue, 25 Apr 2017 10:44:56 GMT
Etag:
- '"YWOzh2SDasdU84ArJnpYek-OMdg/6s__cFeA5l1i01rONlu3TmUQEHs"'
Vary:
- Origin
- X-Origin
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Xss-Protection:
- 1; mode=block
Content-Length:
- '1870'
Server:
- GSE
Cache-Control:
- public, max-age=300, must-revalidate, no-transform
Age:
- '0'
Alt-Svc:
- quic=":443"; ma=2592000; v="37,36,35"
body:
encoding: ASCII-8BIT
string: !binary |-
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
ftEe3bRzPG9nVZiwDp4O/gfEQdY3CBwAAA==
http_version:
recorded_at: Tue, 25 Apr 2017 10:44:56 GMT
- request:
method: get
uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=hey%20what%20are%20you%20doing&source=en&target=sv
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Mac OS X/10.11.6
(gzip)
Accept-Encoding:
- gzip
Content-Type:
- ''
Accept:
- "*/*"
response:
status:
code: 200
message: OK
headers:
Expires:
- Tue, 25 Apr 2017 10:44:56 GMT
Date:
- Tue, 25 Apr 2017 10:44:56 GMT
Cache-Control:
- private, max-age=0, must-revalidate, no-transform
Etag:
- '"0Etagq2wejMpn1NuD3Ltqh3qHnw/XGWNxMh7tDHIjrW_w-Ffgk19QCg"'
Vary:
- Origin
- Referer
- X-Origin
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
Date:
- Fri, 30 Jun 2017 14:54:18 GMT
Server:
- ESF
Cache-Control:
- private
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
X-Frame-Options:
- SAMEORIGIN
X-Content-Type-Options:
- nosniff
Alt-Svc:
- quic=":443"; ma=2592000; v="37,36,35"
- quic=":443"; ma=2592000; v="39,38,37,36,35"
Transfer-Encoding:
- chunked
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAAKvmUlBKSSxJVLJSqOZSUFAqKUrMK85JLMnMzysGikUDxcAS
SFKpKSGpFSVASSWP1CyFssQUhfTD24oUUkqVQOpqgUQsF5Cq5QIA9kBPzVwA
AAA=
http_version:
recorded_at: Tue, 25 Apr 2017 10:44:56 GMT
ewogICJkYXRhIjogewogICAgInRyYW5zbGF0aW9ucyI6IFsKICAgICAgewog
ICAgICAgICJ0cmFuc2xhdGVkVGV4dCI6ICJIZWogdmFkIGfDtnIgZHUiCiAg
ICAgIH0KICAgIF0KICB9Cn0K
http_version:
recorded_at: Fri, 30 Jun 2017 14:54:18 GMT
- request:
method: get
uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=do%20tell%20more&source=en&target=sv
method: post
uri: https://translation.googleapis.com/language/translate/v2?key=some_api_key
body:
encoding: UTF-8
string: ''
string: '{"q":["do tell more"],"target":"sv","source":"en","format":"text"}'
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Mac OS X/10.11.6
(gzip)
Accept-Encoding:
- gzip
- gcloud-ruby/1.0.0
Google-Cloud-Resource-Prefix:
- projects/
Content-Type:
- ''
- application/json
X-Goog-Api-Client:
- gl-ruby/2.3.4 gccl/1.0.0
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
response:
@ -177,55 +78,53 @@ http_interactions:
code: 200
message: OK
headers:
Expires:
- Tue, 25 Apr 2017 10:44:56 GMT
Date:
- Tue, 25 Apr 2017 10:44:56 GMT
Cache-Control:
- private, max-age=0, must-revalidate, no-transform
Etag:
- '"0Etagq2wejMpn1NuD3Ltqh3qHnw/ojPXc7YpC7RgGxSvk9qvHc7p0bM"'
Vary:
- Origin
- X-Origin
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
Vary:
- Origin
- Referer
- X-Origin
Date:
- Fri, 30 Jun 2017 14:54:19 GMT
Server:
- ESF
Cache-Control:
- private
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
X-Frame-Options:
- SAMEORIGIN
X-Content-Type-Options:
- nosniff
Alt-Svc:
- quic=":443"; ma=2592000; v="37,36,35"
- quic=":443"; ma=2592000; v="39,38,37,36,35"
Transfer-Encoding:
- chunked
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAAKvmUlBKSSxJVLJSqOZSUFAqKUrMK85JLMnMzysGikUDxcAS
SFKpKSGpFSVASaWk1KLDS0pKEhVyU4uUQIpqgUQsF5Cq5QIAoYw0jVkAAAA=
http_version:
recorded_at: Tue, 25 Apr 2017 10:44:56 GMT
ewogICJkYXRhIjogewogICAgInRyYW5zbGF0aW9ucyI6IFsKICAgICAgewog
ICAgICAgICJ0cmFuc2xhdGVkVGV4dCI6ICJCZXLDpHR0YSBtZXIiCiAgICAg
IH0KICAgIF0KICB9Cn0K
http_version:
recorded_at: Fri, 30 Jun 2017 14:54:19 GMT
- request:
method: get
uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=value2&source=en&target=sv
method: post
uri: https://translation.googleapis.com/language/translate/v2?key=some_api_key
body:
encoding: UTF-8
string: ''
string: '{"q":["value2"],"target":"sv","source":"en","format":"text"}'
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Mac OS X/10.11.6
(gzip)
Accept-Encoding:
- gzip
- gcloud-ruby/1.0.0
Google-Cloud-Resource-Prefix:
- projects/
Content-Type:
- ''
- application/json
X-Goog-Api-Client:
- gl-ruby/2.3.4 gccl/1.0.0
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
response:
@ -233,55 +132,53 @@ http_interactions:
code: 200
message: OK
headers:
Expires:
- Tue, 25 Apr 2017 10:44:56 GMT
Date:
- Tue, 25 Apr 2017 10:44:56 GMT
Cache-Control:
- private, max-age=0, must-revalidate, no-transform
Etag:
- '"0Etagq2wejMpn1NuD3Ltqh3qHnw/2iNW9phusbWGkf6jtxwOLwZpsUA"'
Vary:
- Origin
- X-Origin
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
Vary:
- Origin
- Referer
- X-Origin
Date:
- Fri, 30 Jun 2017 14:54:19 GMT
Server:
- ESF
Cache-Control:
- private
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
X-Frame-Options:
- SAMEORIGIN
X-Content-Type-Options:
- nosniff
Alt-Svc:
- quic=":443"; ma=2592000; v="37,36,35"
- quic=":443"; ma=2592000; v="39,38,37,36,35"
Transfer-Encoding:
- chunked
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAAKvmUlBKSSxJVLJSqOZSUFAqKUrMK85JLMnMzysGikUDxcAS
SFKpKSGpFSVASaWyw0uKUlKNlEDytUAilgtI1XIBACGegeVUAAAA
http_version:
recorded_at: Tue, 25 Apr 2017 10:44:56 GMT
ewogICJkYXRhIjogewogICAgInRyYW5zbGF0aW9ucyI6IFsKICAgICAgewog
ICAgICAgICJ0cmFuc2xhdGVkVGV4dCI6ICJ2w6RyZGUyIgogICAgICB9CiAg
ICBdCiAgfQp9Cg==
http_version:
recorded_at: Fri, 30 Jun 2017 14:54:19 GMT
- request:
method: get
uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=value1&source=en&target=sv
method: post
uri: https://translation.googleapis.com/language/translate/v2?key=some_api_key
body:
encoding: UTF-8
string: ''
string: '{"q":["value1"],"target":"sv","source":"en","format":"text"}'
headers:
User-Agent:
- |-
Huginn/0.0.1 google-api-ruby-client/0.7.1 Mac OS X/10.11.6
(gzip)
Accept-Encoding:
- gzip
- gcloud-ruby/1.0.0
Google-Cloud-Resource-Prefix:
- projects/
Content-Type:
- ''
- application/json
X-Goog-Api-Client:
- gl-ruby/2.3.4 gccl/1.0.0
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
response:
@ -289,38 +186,40 @@ http_interactions:
code: 200
message: OK
headers:
Expires:
- Tue, 25 Apr 2017 10:44:56 GMT
Date:
- Tue, 25 Apr 2017 10:44:56 GMT
Cache-Control:
- private, max-age=0, must-revalidate, no-transform
Etag:
- '"0Etagq2wejMpn1NuD3Ltqh3qHnw/nFM5Az6_LFcl8SfedeFzG_gVr5Y"'
Vary:
- Origin
- X-Origin
Content-Type:
- application/json; charset=UTF-8
Content-Encoding:
- gzip
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
Vary:
- Origin
- Referer
- X-Origin
Date:
- Fri, 30 Jun 2017 14:54:19 GMT
Server:
- ESF
Cache-Control:
- private
X-Xss-Protection:
- 1; mode=block
Server:
- GSE
X-Frame-Options:
- SAMEORIGIN
X-Content-Type-Options:
- nosniff
Alt-Svc:
- quic=":443"; ma=2592000; v="37,36,35"
- quic=":443"; ma=2592000; v="39,38,37,36,35"
Transfer-Encoding:
- chunked
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAAKvmUlBKSSxJVLJSqOZSUFAqKUrMK85JLMnMzysGikUDxcAS
SFKpKSGpFSVASaWyxJzSVEMlkHQtkIjlAlK1XAC9QY+aUwAAAA==
http_version:
recorded_at: Tue, 25 Apr 2017 10:44:56 GMT
recorded_with: VCR 2.9.2
string: |
{
"data": {
"translations": [
{
"translatedText": "value1"
}
]
}
}
http_version:
recorded_at: Fri, 30 Jun 2017 14:54:19 GMT
recorded_with: VCR 3.0.3

View file

@ -1,6 +1,6 @@
require 'rails_helper'
describe Agents::GoogleCalendarPublishAgent, :vcr do
describe Agents::GoogleCalendarPublishAgent do
let(:valid_params) do
{
'expected_update_period_in_days' => "10",
@ -21,6 +21,20 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
end
describe '#receive' do
let(:message) do
{
'visibility' => 'default',
'summary' => "Awesome event",
'description' => "An example event with text. Pro tip: DateTimes are in RFC3339",
'end' => {
'date_time' => '2014-10-02T11:00:00-05:00'
},
'start' => {
'date_time' => '2014-10-02T10:00:00-05:00'
}
}
end
let(:event) do
_event = Event.new
_event.agent = agents(:bob_manual_event_agent)
@ -30,25 +44,13 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
end
let(:calendar_id) { 'sqv39gj35tc837gdns1g4d81cg@group.calendar.google.com' }
let(:message) do
{
'visibility' => 'default',
'summary' => "Awesome event",
'description' => "An example event with text. Pro tip: DateTimes are in RFC3339",
'end' => {
'dateTime' => '2014-10-02T11:00:00-05:00'
},
'start' => {
'dateTime' => '2014-10-02T10:00:00-05:00'
}
}
end
let(:response_body) do
let(:response_hash) do
{"kind"=>"calendar#event",
"etag"=>"\"2908684044040000\"",
"id"=>"baz",
"status"=>"confirmed",
"htmlLink"=>
"html_link"=>
"https://calendar.google.com/calendar/event?eid=foobar",
"created"=>"2016-02-01T15:53:41.000Z",
"updated"=>"2016-02-01T15:53:42.020Z",
@ -60,20 +62,21 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
"blah-foobar@developer.gserviceaccount.com"},
"organizer"=>
{"email"=>calendar_id,
"displayName"=>"Huginn Location Log",
"display_name"=>"Huginn Location Log",
"self"=>true},
"start"=>{"dateTime"=>"2014-10-03T00:30:00+09:30"},
"end"=>{"dateTime"=>"2014-10-03T01:30:00+09:30"},
"iCalUID"=>"blah@google.com",
"start"=>{"date_time"=>"2014-10-03T00:30:00+09:30"},
"end"=>{"date_time"=>"2014-10-03T01:30:00+09:30"},
"i_cal_uid"=>"blah@google.com",
"sequence"=>0,
"reminders"=>{"useDefault"=>true}
}.to_json
"reminders"=>{"use_default"=>true}
}
end
def setup_mock!
fake_interface = Object.new
mock(GoogleCalendar).new(agent.interpolate_options(agent.options), Rails.logger) { fake_interface }
mock(fake_interface).publish_as(calendar_id, message) { stub!.response.stub!.body { response_body } }
mock(fake_interface).publish_as(calendar_id, message) { response_hash }
mock(fake_interface).cleanup!
end
describe 'when the calendar_id is in the options' do
@ -84,7 +87,7 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
agent.receive([event])
}.to change { agent.events.count }.by(1)
expect(agent.events.last.payload).to eq({ "success" => true, "published_calendar_event" => JSON.parse(response_body), "agent_id" => event.agent_id, "event_id" => event.id })
expect(agent.events.last.payload).to eq({ "success" => true, "published_calendar_event" => response_hash, "agent_id" => event.agent_id, "event_id" => event.id })
end
end
@ -101,7 +104,7 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
agent.receive([event])
expect(agent.events.count).to eq(1)
expect(agent.events.last.payload).to eq({ "success" => true, "published_calendar_event" => JSON.parse(response_body), "agent_id" => event.agent_id, "event_id" => event.id })
expect(agent.events.last.payload).to eq({ "success" => true, "published_calendar_event" => response_hash, "agent_id" => event.agent_id, "event_id" => event.id })
end
it 'should allow Liquid in the key' do
@ -121,4 +124,85 @@ describe Agents::GoogleCalendarPublishAgent, :vcr do
end
end
end
describe '#receive old style event' do
let(:event) do
_event = Event.new
_event.agent = agents(:bob_manual_event_agent)
_event.payload = { 'message' => {
'visibility' => 'default',
'summary' => "Awesome event",
'description' => "An example event with text. Pro tip: DateTimes are in RFC3339",
'end' => {
'dateTime' => '2014-10-02T11:00:00-05:00'
},
'start' => {
'dateTime' => '2014-10-02T10:00:00-05:00'
}
} }
_event.save!
_event
end
let(:calendar_id) { 'sqv39gj35tc837gdns1g4d81cg@group.calendar.google.com' }
let(:message) do
{
'visibility' => 'default',
'summary' => "Awesome event",
'description' => "An example event with text. Pro tip: DateTimes are in RFC3339",
'end' => {
'date_time' => '2014-10-02T11:00:00-05:00'
},
'start' => {
'date_time' => '2014-10-02T10:00:00-05:00'
}
}
end
let(:response_hash) do
{"kind"=>"calendar#event",
"etag"=>"\"2908684044040000\"",
"id"=>"baz",
"status"=>"confirmed",
"html_link"=>
"https://calendar.google.com/calendar/event?eid=foobar",
"created"=>"2016-02-01T15:53:41.000Z",
"updated"=>"2016-02-01T15:53:42.020Z",
"summary"=>"Awesome event",
"description"=>
"An example event with text. Pro tip: DateTimes are in RFC3339",
"creator"=>
{"email"=>
"blah-foobar@developer.gserviceaccount.com"},
"organizer"=>
{"email"=>calendar_id,
"display_name"=>"Huginn Location Log",
"self"=>true},
"start"=>{"date_time"=>"2014-10-03T00:30:00+09:30"},
"end"=>{"date_time"=>"2014-10-03T01:30:00+09:30"},
"i_cal_uid"=>"blah@google.com",
"sequence"=>0,
"reminders"=>{"use_default"=>true}
}
end
def setup_mock!
fake_interface = Object.new
mock(GoogleCalendar).new(agent.interpolate_options(agent.options), Rails.logger) { fake_interface }
mock(fake_interface).publish_as(calendar_id, message) { response_hash }
mock(fake_interface).cleanup!
end
describe 'when the calendar_id is in the options' do
it 'should publish old style payload it receives' do
setup_mock!
expect {
agent.receive([event])
}.to change { agent.events.count }.by(1)
expect(agent.events.last.payload).to eq({ "success" => true, "published_calendar_event" => response_hash, "agent_id" => event.agent_id, "event_id" => event.id })
end
end
end
end