diff --git a/Gemfile b/Gemfile index 76ac492775..99f7971410 100644 --- a/Gemfile +++ b/Gemfile @@ -47,8 +47,8 @@ gem 'hypdf', '~> 1.0.10' # PDFInfoAgent # FIXME needs to loosen omniauth dependency gem 'weibo_2', github: 'dsander/weibo_2', branch: 'master' -# GoogleCalendarPublishAgent -gem "google-api-client", require: 'google/api_client' +# GoogleCalendarPublishAgent and GoogleTranslateAgent +gem 'google-api-client', '~> 0.7.1', require: 'google/api_client' # Twitter Agents gem 'twitter', '~> 5.14.0' # Must to be loaded before cantino-twitter-stream. diff --git a/Gemfile.lock b/Gemfile.lock index 421a7bdf9b..ae62f56189 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -628,7 +628,7 @@ DEPENDENCIES foreman (~> 0.63.0) geokit (~> 1.8.4) geokit-rails (~> 2.2.0) - google-api-client + google-api-client (~> 0.7.1) guard (~> 2.13.0) guard-livereload (~> 2.5.1) guard-rspec (~> 4.6.4) diff --git a/app/models/agents/google_translation_agent.rb b/app/models/agents/google_translation_agent.rb new file mode 100644 index 0000000000..c54ebe9c3b --- /dev/null +++ b/app/models/agents/google_translation_agent.rb @@ -0,0 +1,92 @@ +module Agents + class GoogleTranslationAgent < Agent + cannot_be_scheduled! + + gem_dependency_check { defined?(Google) && defined?(Google::APIClient) } + + description <<-MD + The Translation Agent will attempt to translate text between natural languages. + + #{'## Include `google-api-client` in your Gemfile to use this Agent!' if dependencies_missing?} + + 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` 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. + + Specify what you would like to translate in `content` field, you can use [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) specify which part of the payload you want to translate. + + `expected_receive_period_in_days` is the maximum number of days you would allow to pass between events. + MD + + event_description "User defined" + + def default_options + { + 'to' => "sv", + 'from' => 'en', + 'google_api_key' => '', + 'expected_receive_period_in_days' => 1, + 'content' => { + 'text' => "{{message}}", + 'moretext' => "{{another message}}" + } + } + end + + def working? + last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs? + end + + def validate_options + unless options['google_api_key'].present? && options['to'].present? && options['content'].present? && options['expected_receive_period_in_days'].present? + errors.add :base, "google_api_key, to, content and expected_receive_period_in_days are all required" + end + end + + def translate_from + interpolated["from"].presence || 'en' + end + + def receive(incoming_events) + incoming_events.each do |event| + translated_event = {} + opts = interpolated(event) + opts['content'].each_pair do |key, value| + result = translate(value) + translated_event[key] = result.data.translations.last.translated_text + end + create_event payload: translated_event + end + end + + def google_client + @google_client ||= Google::APIClient.new( + { + application_name: "Huginn", + application_version: "0.0.1", + key: options['google_api_key'], + authorization: nil + } + ) + end + + def translate_service + @translate_service ||= google_client.discovered_api('translate','v2') + end + + def translate(value) + google_client.execute( + api_method: translate_service.translations.list, + parameters: { + format: 'text', + source: translate_from, + target: options["to"], + q: value + } + ) + end + end +end diff --git a/app/models/agents/translation_agent.rb b/app/models/agents/translation_agent.rb deleted file mode 100644 index 515fa39ff9..0000000000 --- a/app/models/agents/translation_agent.rb +++ /dev/null @@ -1,79 +0,0 @@ -module Agents - class TranslationAgent < Agent - cannot_be_scheduled! - - description <<-MD - The Translation Agent will attempt to translate text between natural languages. - - Services are provided using Microsoft Translator. You can [sign up](https://datamarket.azure.com/dataset/bing/microsofttranslator) and [register your application](https://datamarket.azure.com/developer/applications/register) to get `client_id` and `client_secret` which are required to use this agent. - - `to` must be filled with a [translator language code](https://msdn.microsoft.com/en-us/library/hh456380.aspx). - - Specify what you would like to translate in `content` field, you can use [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) specify which part of the payload you want to translate. - - `expected_receive_period_in_days` is the maximum number of days you would allow to pass between events. - MD - - event_description "User defined" - - def default_options - { - 'client_id' => "xxxxxx", - 'client_secret' => "xxxxxx", - 'to' => "fi", - 'expected_receive_period_in_days' => 1, - 'content' => { - 'text' => "{{message.text}}", - 'content' => "{{xyz}}" - } - } - end - - def working? - last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs? - end - - def translate(text, to, access_token) - translate_uri = URI 'https://api.microsofttranslator.com/v2/Ajax.svc/Translate' - params = { - 'text' => text, - 'to' => to - } - translate_uri.query = URI.encode_www_form params - request = Net::HTTP::Get.new translate_uri.request_uri - request['Authorization'] = "Bearer" + " " + access_token - http = Net::HTTP.new translate_uri.hostname, translate_uri.port - response = http.request request - YAML.load response.body - end - - def validate_options - unless options['client_id'].present? && options['client_secret'].present? && options['to'].present? && options['content'].present? && options['expected_receive_period_in_days'].present? - errors.add :base, "client_id,client_secret,to,expected_receive_period_in_days and content are all required" - end - end - - def postform(uri, params) - req = Net::HTTP::Post.new(uri.request_uri) - req.form_data = params - Net::HTTP.start(uri.hostname, uri.port, :use_ssl => true) { |http| http.request(req) } - end - - def receive(incoming_events) - auth_uri = URI "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13" - response = postform auth_uri, :client_id => interpolated['client_id'], - :client_secret => interpolated['client_secret'], - :scope => "https://api.microsofttranslator.com", - :grant_type => "client_credentials" - access_token = JSON.parse(response.body)["access_token"] - incoming_events.each do |event| - translated_event = {} - opts = interpolated(event) - opts['content'].each_pair do |key, value| - translated_event[key] = translate(value.first, opts['to'], access_token) - end - create_event :payload => translated_event - end - end - end -end diff --git a/spec/cassettes/Agents_GoogleTranslationAgent/_receive/checks_if_it_can_handle_multiple_events.yml b/spec/cassettes/Agents_GoogleTranslationAgent/_receive/checks_if_it_can_handle_multiple_events.yml new file mode 100644 index 0000000000..df6e68e5b1 --- /dev/null +++ b/spec/cassettes/Agents_GoogleTranslationAgent/_receive/checks_if_it_can_handle_multiple_events.yml @@ -0,0 +1,326 @@ +--- +http_interactions: +- request: + method: get + uri: https://www.googleapis.com/discovery/v1/apis/translate/v2/rest?key=some_api_key + 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: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 + - 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 + Server: + - GSE + Alt-Svc: + - quic=":443"; ma=2592000; v="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 +- 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 + 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/ojPXc7YpC7RgGxSvk9qvHc7p0bM"' + 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 + Server: + - GSE + Alt-Svc: + - quic=":443"; ma=2592000; v="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 +- request: + method: get + uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=value2&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/2iNW9phusbWGkf6jtxwOLwZpsUA"' + 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 + Server: + - GSE + Alt-Svc: + - quic=":443"; ma=2592000; v="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 +- request: + method: get + uri: https://www.googleapis.com/language/translate/v2?format=text&key=some_api_key&q=value1&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/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 + X-Xss-Protection: + - 1; mode=block + Server: + - GSE + Alt-Svc: + - quic=":443"; ma=2592000; v="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 diff --git a/spec/models/agents/google_translation_agent_spec.rb b/spec/models/agents/google_translation_agent_spec.rb new file mode 100644 index 0000000000..87af38c1e5 --- /dev/null +++ b/spec/models/agents/google_translation_agent_spec.rb @@ -0,0 +1,83 @@ +require 'rails_helper' + +describe Agents::GoogleTranslationAgent, :vcr do + before do + @valid_params = { + name: "somename", + options: { + to: "sv", + from: "en", + google_api_key: 'some_api_key', + expected_receive_period_in_days: 1, + content: { + text: "{{message}}", + content: "{{xyz}}" + } + } + } + + @checker = Agents::GoogleTranslationAgent.new(@valid_params) + @checker.user = users(:jane) + @checker.save! + + @event = Event.new + @event.agent = agents(:jane_weather_agent) + @event.payload = { + message: "hey what are you doing", + xyz: "do tell more" + } + + end + + describe "#receive" do + it "checks if it can handle multiple events" do + event1 = Event.new + event1.agent = agents(:bob_weather_agent) + event1.payload = { + xyz: "value1", + message: "value2" + } + + expect { + @checker.receive([@event,event1]) + }.to change { Event.count }.by(2) + end + end + + describe "#working?" do + it "checks if events have been received within expected receive period" do + expect(@checker).not_to be_working + Agents::GoogleTranslationAgent.async_receive @checker.id, [@event.id] + expect(@checker.reload).to be_working + two_days_from_now = 2.days.from_now + stub(Time).now { two_days_from_now } + expect(@checker.reload).not_to be_working + end + end + + describe "validation" do + before do + expect(@checker).to be_valid + end + + it "should validate presence of content key" do + @checker.options[:content] = nil + expect(@checker).not_to be_valid + end + + it "should validate presence of expected_receive_period_in_days key" do + @checker.options[:expected_receive_period_in_days] = nil + expect(@checker).not_to be_valid + end + + it "should validate presence of google_api_key" do + @checker.options[:google_api_key] = nil + expect(@checker).not_to be_valid + end + + it "should validate presence of 'to' key" do + @checker.options[:to] = "" + expect(@checker).not_to be_valid + end + end +end diff --git a/spec/models/agents/translation_agent_spec.rb b/spec/models/agents/translation_agent_spec.rb deleted file mode 100644 index 2e9ccfd855..0000000000 --- a/spec/models/agents/translation_agent_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require 'rails_helper' - -describe Agents::TranslationAgent do - before do - @valid_params = { - :name => "somename", - :options => { - :client_id => "xxxxxx", - :client_secret => "xxxxxx" , - :to => "fi", - :expected_receive_period_in_days => 1, - :content => { - :text => "{{message}}", - :content => "{{xyz}}" - } - } - } - - @checker = Agents::TranslationAgent.new(@valid_params) - @checker.user = users(:jane) - @checker.save! - - @event = Event.new - @event.agent = agents(:jane_weather_agent) - @event.payload = { - :message => "somevalue", - :xyz => "someothervalue" - } - - stub_request(:any, /microsoft/).to_return(:body => "response", :status => 200) - stub_request(:any, /windows/).to_return(:body => JSON.dump({ - :access_token => 'xxx'}), :status => 200) - - end - - describe "#receive" do - it "checks if it can handle multiple events" do - event1 = Event.new - event1.agent = agents(:bob_weather_agent) - event1.payload = { - :xyz => "value1", - :message => "value2" - } - - expect { - @checker.receive([@event,event1]) - }.to change { Event.count }.by(2) - end - end - - describe "#working?" do - it "checks if events have been received within expected receive period" do - expect(@checker).not_to be_working - Agents::TranslationAgent.async_receive @checker.id, [@event.id] - expect(@checker.reload).to be_working - two_days_from_now = 2.days.from_now - stub(Time).now { two_days_from_now } - expect(@checker.reload).not_to be_working - end - end - - describe "validation" do - before do - expect(@checker).to be_valid - end - - it "should validate presence of content key" do - @checker.options[:content] = nil - expect(@checker).not_to be_valid - end - - it "should validate presence of expected_receive_period_in_days key" do - @checker.options[:expected_receive_period_in_days] = nil - expect(@checker).not_to be_valid - end - - it "should validate presence of client_id key" do - @checker.options[:client_id] = "" - expect(@checker).not_to be_valid - end - - it "should validate presence of client_secret key" do - @checker.options[:client_secret] = "" - expect(@checker).not_to be_valid - end - - it "should validate presence of 'to' key" do - @checker.options[:to] = "" - expect(@checker).not_to be_valid - end - end -end