embulk-input-google_adwords 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 65cd09fea336300d023ad6c3dea7a395c988a05c7aeabc956e65f43a2215d104
4
+ data.tar.gz: 22637169c16dfafd9fcc7e3364b5f089a2705f68e322080c1bd9230e4012f781
5
+ SHA512:
6
+ metadata.gz: db84b6a0f5f49f2a5a1d5b69b2bccab96487ba5e58df35a652cb50c53fd528c4694000602eed9764646733ce71476214c2f100b8bb5ee36039bf8aee1ac09a23
7
+ data.tar.gz: 06f6b69c63d5c73322890e3795630f73540cf1686d3b1c4a8d75633bac5eb1963042392bd653c1ccbc23b1563c76cbaa8170f19a57c04eb8791061b174f8e98f
@@ -0,0 +1,6 @@
1
+ *~
2
+ /pkg/
3
+ /tmp/
4
+ /.bundle/
5
+ /Gemfile.lock
6
+ config.yml
@@ -0,0 +1 @@
1
+ jruby-9.1.5.0
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org/'
2
+ gemspec
@@ -0,0 +1,21 @@
1
+
2
+ MIT License
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Google AdWords input plugin for Embulk
2
+
3
+ Embulk input plugin for Google AdWords reports.
4
+
5
+ ## Configuration
6
+ ### Authentication
7
+
8
+ - **auth_method**: OAuth2 (Authentication method must be OAuth2 for AdWords API access.)
9
+ - **auth_oauth2_client_id**: OAuth2 client ID
10
+ - **auth_oauth2_client_secret**: OAuth2 client secret
11
+ - **auth_developer_token**: Developer token for AdWords API access
12
+ - **auth_client_customer_id**: Account number of the AdWords client account, e.g. 123-456-7890
13
+ - **auth_user_agent**: User agent string, e.g. Embulk plugin for Google Adwords
14
+ - **oauth2_access_token**: OAuth2 access token
15
+ - **oauth2_refresh_token**: OAuth2 refresh token
16
+ - **oauth2_issued_at**: The date and time when the OAuth2 access token has been issued
17
+ - **oauth2_expires_in**: Expiration duration of OAuth2 access token
18
+ ### Query
19
+ - **report_type**: Report type to query, e.g. CAMPAIGN_PERFORMANCE_REPORT
20
+ - **fields**: Field list to query
21
+ - **conditions**: Condition list of the query
22
+ - **daterange**: Date range of the query
23
+ ### How to get configuration values
24
+ You can check `config.yml.example` file.<br/>
25
+ There are links in there.
26
+
27
+ ## Build
28
+
29
+ ```
30
+ $ rake
31
+ ```
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task default: :build
@@ -0,0 +1,59 @@
1
+ in:
2
+ type: google_adwords
3
+
4
+ #######################################################################################################
5
+ # authentication informations #
6
+ # for the details, refer to https://developers.google.com/adwords/api/docs/guides/first-api-call #
7
+ #######################################################################################################
8
+ auth_method: OAuth2 # authentication method should be OAuth2
9
+
10
+ # OAuth2 client ID and client secret
11
+ # refer to https://developers.google.com/adwords/api/docs/guides/first-api-call#set_up_oauth2_authentication
12
+ auth_oauth2_client_id: OAUTH2_CLIENT_ID
13
+ auth_oauth2_client_secret: OAUTH2_CLIENT_SECRET
14
+
15
+ # developer token for AdWords API access
16
+ # refer to https://developers.google.com/adwords/api/docs/guides/first-api-call#request_a_developer_token
17
+ auth_developer_token: DEVELOPER_TOKEN
18
+
19
+ # account number of the AdWords client account, e.g. 123-456-7890
20
+ auth_client_customer_id: CLIENT_CUSTOMER_ID
21
+
22
+ auth_user_agent: Embulk plugin for Google Adwords
23
+
24
+ # OAuth2 tokens
25
+ # refer to https://developers.google.com/adwords/api/docs/guides/first-api-call#get_an_oauth2_refresh_token_and_configure_your_client
26
+ oauth2_access_token: ACCESS_TOKEN
27
+ oauth2_refresh_token: REFRESH_TOKEN
28
+ oauth2_issued_at: ISSUED_DATE_TIME
29
+ oauth2_expires_in: 3600
30
+
31
+ #######################################################################################################
32
+ # query informations #
33
+ #######################################################################################################
34
+
35
+ # report type, required
36
+ # for available report types, refer to https://developers.google.com/adwords/api/docs/appendix/reports
37
+ report_type: REPORT_TYPE # e.g. CAMPAIGN_PERFORMANCE_REPORT
38
+
39
+ # field list to query, required
40
+ # fields must not contain 'Date' and 'Week' fields if you omit date range
41
+ # for the available fields per report type, refer to the following link.
42
+ # https://developers.google.com/adwords/api/docs/appendix/reports/all-reports
43
+ fields:
44
+ - FIELD to query # e.g. Amount
45
+ - FIELD to query # e.g. Clicks
46
+ - ...
47
+
48
+ # query condition list, optional
49
+ # for the details, refer to https://developers.google.com/adwords/api/docs/guides/awql#formal_grammar
50
+ conditions:
51
+ - CONDITION # e.g. CampaignStatus = PAUSED
52
+ - CONDITION # e.g. CampaignStatus IN [ENABLED, PAUSED]
53
+ - ...
54
+
55
+ # date range, optional, get data for all dates if omitted
56
+ daterange: DATE_RANGE # e.g. LAST_7_DAYS, e.g. 20170101,20170625
57
+
58
+ out:
59
+ type: stdout
@@ -0,0 +1,21 @@
1
+
2
+ Gem::Specification.new do |spec|
3
+ spec.name = "embulk-input-google_adwords"
4
+ spec.version = "0.1.0"
5
+ spec.authors = ["topdeveloper"]
6
+ spec.summary = "Google Adwords input plugin for Embulk"
7
+ spec.description = "Loads records from Google Adwords."
8
+ # TODO set this: spec.email = [""]
9
+ spec.licenses = ["MIT"]
10
+ # TODO set this: spec.homepage = ""
11
+
12
+ spec.files = `git ls-files`.split("\n") + Dir["classpath/*.jar"]
13
+ spec.test_files = spec.files.grep(%r{^(test|spec)/})
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_dependency 'google-adwords-api', ['>= 0.25.0']
17
+
18
+ spec.add_development_dependency 'embulk', ['>= 0.8.25']
19
+ spec.add_development_dependency 'bundler', ['>= 1.10.6']
20
+ spec.add_development_dependency 'rake', ['>= 10.0']
21
+ end
Binary file
@@ -0,0 +1,130 @@
1
+ require 'adwords_api'
2
+
3
+ module Embulk
4
+ module Input
5
+
6
+ class GoogleAdwords < InputPlugin
7
+ Plugin.register_input("google_adwords", self)
8
+
9
+ def self.transaction(config, &control)
10
+ # configuration code:
11
+ task = {
12
+ "adwords_api_options" => {
13
+ "authentication" => {
14
+ "method" => config.param("auth_method", :string),
15
+ "oauth2_client_id" => config.param("auth_oauth2_client_id", :string),
16
+ "oauth2_client_secret" => config.param("auth_oauth2_client_secret", :string),
17
+ "developer_token" => config.param("auth_developer_token", :string),
18
+ "client_customer_id" => config.param("auth_client_customer_id", :string),
19
+ "user_agent" => config.param("auth_user_agent", :string),
20
+ "oauth2_token" => {
21
+ "access_token" => config.param("oauth2_access_token", :string),
22
+ "refresh_token" => config.param("oauth2_refresh_token", :string),
23
+ "issued_at" => config.param("oauth2_issued_at", :string),
24
+ "expires_in" => config.param("oauth2_expires_in", :string),
25
+ "id_token" => ""
26
+ }
27
+ },
28
+ "service" => {
29
+ "environment" => "PRODUCTION"
30
+ },
31
+ "connection" => {
32
+ "enable_gzip" => false
33
+ },
34
+ "library" => {
35
+ "log_level" => "INFO",
36
+ "skip_report_header" => true,
37
+ "skip_column_header" => true,
38
+ "skip_report_summary" => true
39
+ }
40
+ },
41
+ "report_type" => config.param("report_type", :string),
42
+ "fields" => config.param("fields", :array),
43
+ "conditions" => config.param("conditions", :array, default: []),
44
+ "daterange" => config.param("daterange", :string, default: "")
45
+ }
46
+
47
+ raise ConfigError.new("The parameter report_type must not be empty.") if task["report_type"].empty?
48
+ raise ConfigError.new("The parameter fields must not be empty array.") if task["fields"].empty?
49
+
50
+ columns = task["fields"].map do |col_name|
51
+ Column.new(nil, col_name, :string)
52
+ end
53
+
54
+ resume(task, columns, 1, &control)
55
+ end
56
+
57
+ def self.resume(task, columns, count, &control)
58
+ task_reports = yield(task, columns, count)
59
+
60
+ next_config_diff = {}
61
+ return next_config_diff
62
+ end
63
+
64
+ # TODO
65
+ # def self.guess(config)
66
+ # sample_records = [
67
+ # {"example"=>"a", "column"=>1, "value"=>0.1},
68
+ # {"example"=>"a", "column"=>2, "value"=>0.2},
69
+ # ]
70
+ # columns = Guess::SchemaGuess.from_hash_records(sample_records)
71
+ # return {"columns" => columns}
72
+ # end
73
+
74
+ def init
75
+ # initialization code:
76
+ end
77
+
78
+ def run
79
+ selectors = task["fields"].join(", ")
80
+ conditions = task["conditions"].join(" AND ")
81
+
82
+ query = "SELECT " + selectors + " FROM " + task["report_type"]
83
+ query << " WHERE " + conditions unless conditions.empty?
84
+ query << " DURING " + task["daterange"] unless task["daterange"].empty?
85
+
86
+ begin
87
+ query_report_results(query) do |row|
88
+ page_builder.add row
89
+ end
90
+
91
+ # Authorization error.
92
+ rescue AdsCommon::Errors::OAuth2VerificationRequired => e
93
+ raise ConfigError.new(e.message)
94
+
95
+ # HTTP errors.
96
+ rescue AdsCommon::Errors::HttpError => e
97
+ raise ConfigError.new(e.message)
98
+
99
+ # API errors.
100
+ rescue AdwordsApi::Errors::ReportError => e
101
+ raise ConfigError.new(e.message)
102
+ end
103
+
104
+ page_builder.finish
105
+
106
+ task_report = {}
107
+ return task_report
108
+ end
109
+
110
+ API_VERSION = :v201705
111
+
112
+ def query_report_results(query, &block)
113
+ # AdwordsApi::Api
114
+ adwords = AdwordsApi::Api.new(task["adwords_api_options"])
115
+
116
+ # Get report utilities for the version.
117
+ report_utils = adwords.report_utils(API_VERSION)
118
+
119
+ # Allowing rows with zero impressions to show is not supported with AWQL.
120
+ adwords.include_zero_impressions = false
121
+
122
+ report_utils.get_stream_helper_with_awql(query, 'CSV').each_line do |line|
123
+ row = line.split(",")
124
+ block.call row
125
+ end
126
+ end
127
+ end
128
+
129
+ end
130
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: embulk-input-google_adwords
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - topdeveloper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-adwords-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.25.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.25.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: embulk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.25
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.8.25
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.10.6
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.10.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Loads records from Google Adwords.
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".ruby-version"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - config.yml.example
82
+ - embulk-input-google_adwords.gemspec
83
+ - lib/.DS_Store
84
+ - lib/embulk/input/google_adwords.rb
85
+ homepage:
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 3.0.3
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Google Adwords input plugin for Embulk
108
+ test_files: []