ZReviewTender 1.2.8 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8bcc9b0eab8e7b7c5aacfbc1add9a591e860222656d4097b3184011e41f8d93b
4
- data.tar.gz: cf092f42c2d81f62394713040fea08748810c283e4f0540f019b381042cf305b
3
+ metadata.gz: 3dc43afcea3785d378d46682df93c79bae9691220b34ba2ae54d49fff50656bf
4
+ data.tar.gz: e3b85166bb82c721b3e63579cf5be846e70078648a603d215d8cd8f1bb48e89d
5
5
  SHA512:
6
- metadata.gz: 7ddf0c24a5120da15392ca8c2b5053d39b6ae48853ed85e16fb8e445ca76ec3039ff2c97ee02e6015d20641ae697245de715951015397c44de4002d3456494f8
7
- data.tar.gz: 03afbee02b7543121a52a645258845780e0fbadf42b7b8ab65f8f9553317447500ee004df953c62735ba82cc584c0e1e3193a07b98f396913ce1217db40eb56b
6
+ metadata.gz: 6d545478dd32184762bb5666c1808af1cd4e98faeb609bd1593be39a34e52e54e0872580661b8de1d57560e918a2f8a42513799086c3bfac83a326f68d721be0
7
+ data.tar.gz: c9d68afd189f689e65a83295eb8fe7c685ac4d3980fac0127cff5708375503223174acaa031c69d93784801ebb76cd5f06a83b5ccab8b4b32fd36a586dbb08ca
data/.version CHANGED
@@ -1 +1 @@
1
- 1.2.8
1
+ 1.3.0
@@ -1,6 +1,6 @@
1
1
  platform: 'android'
2
2
  packageName: '' # Android App Package Name
3
- keyFilePath: '' # Google Android Publisher API Credential .json File Path
3
+ keyFilePath: '' # Google Android Publisher API Service Account Credential .json File Path
4
4
  playConsoleDeveloperAccountID: '' # Google Console Developer Account ID
5
5
  playConsoleAppID: '' # Google Console App ID
6
6
  processors:
@@ -13,7 +13,7 @@ processors:
13
13
  - GoogleTranslateProcessor: # Google Translate Processor, will translate review text to your language, you can remove whole block if you don't needed it.
14
14
  class: "GoogleTranslateProcessor"
15
15
  enable: false # enable
16
- googleTranslateAPIKeyFilePath: '' # Google Translate API Credential .json File Path
16
+ googleTranslateAPIKeyFilePath: '' # Google Translate API Service Account Credential .json File Path
17
17
  googleTranslateTargetLang: 'zh-TW' # Translate to what Language
18
18
  googleTranslateTerritoriesExclude: ["zh-Hant","zh-Hans"] # Review origin Territory (language) that you don't want to translate. (language for android e.g. zh-Hant, en)
19
19
  - SlackProcessor: # Slack Processor, resend App Review to Slack.
@@ -24,3 +24,25 @@ processors:
24
24
  slackBotToken: "" # Slack Bot Token, send slack message throught Slack Bot.
25
25
  slackBotTargetChannel: "" # Slack Bot Token, send slack message throught Slack Bot. (recommended, first priority)
26
26
  slackInCommingWebHookURL: "" # Slack In-Comming WebHook URL, Send slack message throught In-Comming WebHook, not recommended, deprecated.
27
+ - GoogleSheetProcessor: # Google Sheet Processor, log review to google sheet
28
+ class: "GoogleSheetProcessor"
29
+ enable: false # enable
30
+ googleSheetAPIKeyFilePath: "" # Google Translate API Service Account Credential .json File Path
31
+ googleSheetTimeZoneOffset: "+08:00" # Review Created Date TimeZone
32
+ googleSheetID: "" # Google Sheet ID, you can get it on google sheet url: e.g. https://docs.google.com/spreadsheets/d/googleSheetID/
33
+ googleSheetName: "Sheet1" # Sheet Name
34
+ values: ["%RATING%","%TITLE%\n%BODY%","%APPVERSION%","%CREATEDDATE%"] # Columns Data, you can uses magic variable below to compose string.
35
+ # %TITLE% for review's title
36
+ # %BODY% for review's content
37
+ # %RATING% for review's rating 1~5
38
+ # %PLATFORM% for review's platform Apple or Android
39
+ # %ID% for review's ID
40
+ # %USERNAME% for review's reviewer username
41
+ # %URL% for link to review
42
+ # %TERRITORY% for review's territory (language for android e.g. zh-Hant, en)
43
+ # %APPVERSION% for review's reviewer app version
44
+ # %CREATEDDATE% for review's created date
45
+
46
+ keywordsInclude: [] # keywords you want to filter out
47
+ ratingsInclude: [] # ratings you want to filter out
48
+ territoriesInclude: [] # territories you want to filter out(language for android e.g. zh-Hant, en)
@@ -9,13 +9,13 @@ processors:
9
9
  enable: true # enable
10
10
  keywordsInclude: [] # keywords you want to filter out
11
11
  ratingsInclude: [] # ratings you want to filter out
12
- territoriesInclude: [] # territories you want to filter out
12
+ territoriesInclude: [] # territories you want to filter out (territory for Apple e.g. TWN)
13
13
  - GoogleTranslateProcessor: # Google Translate Processor, will translate review text to your language, you can remove whole block if you don't needed it.
14
14
  class: "GoogleTranslateProcessor"
15
15
  enable: false # enable
16
- googleTranslateAPIKeyFilePath: '' # Google Translate API Credential .json File Path
16
+ googleTranslateAPIKeyFilePath: '' # Google Translate API Service Account Credential .json File Path
17
17
  googleTranslateTargetLang: 'zh-TW' # Translate to what Language
18
- googleTranslateTerritoriesExclude: ["TWN","CHN"] # Review origin Territory that you don't want to translate.
18
+ googleTranslateTerritoriesExclude: ["TWN","CHN"] # Review origin Territory that you don't want to translate. (territory for Apple e.g. TWN)
19
19
  - SlackProcessor: # Slack Processor, resend App Review to Slack.
20
20
  class: "SlackProcessor"
21
21
  enable: true # enable
@@ -24,3 +24,25 @@ processors:
24
24
  slackBotToken: "" # Slack Bot Token, send slack message throught Slack Bot.
25
25
  slackBotTargetChannel: "" # Slack Bot Token, send slack message throught Slack Bot. (recommended, first priority)
26
26
  slackInCommingWebHookURL: "" # Slack In-Comming WebHook URL, Send slack message throught In-Comming WebHook, not recommended, deprecated.
27
+ - GoogleSheetProcessor: # Google Sheet Processor, log review to google sheet
28
+ class: "GoogleSheetProcessor"
29
+ enable: false # enable
30
+ googleSheetAPIKeyFilePath: "" # Google Translate API Service Account Credential .json File Path
31
+ googleSheetTimeZoneOffset: "+08:00" # Review Created Date TimeZone
32
+ googleSheetID: "" # Google Sheet ID, you can get it on google sheet url: e.g. https://docs.google.com/spreadsheets/d/googleSheetID/
33
+ googleSheetName: "Sheet1" # Sheet Name
34
+ values: ["%RATING%","%TITLE%\n%BODY%","%APPVERSION%","%CREATEDDATE%"] # Columns Data, you can uses magic variable below to compose string.
35
+ # %TITLE% for review's title
36
+ # %BODY% for review's content
37
+ # %RATING% for review's rating 1~5
38
+ # %PLATFORM% for review's platform Apple or Android
39
+ # %ID% for review's ID
40
+ # %USERNAME% for review's reviewer username
41
+ # %URL% for link to review
42
+ # %TERRITORY% for review's territory (territory for Apple e.g. TWN)
43
+ # %APPVERSION% for review's reviewer app version
44
+ # %CREATEDDATE% for review's created date
45
+
46
+ keywordsInclude: [] # keywords you want to filter out
47
+ ratingsInclude: [] # ratings you want to filter out
48
+ territoriesInclude: [] # territories you want to filter out (territory for Apple e.g. TWN)
@@ -1,21 +1,20 @@
1
1
  $lib = File.expand_path('../lib', File.dirname(__FILE__))
2
2
 
3
- require "Models/Review"
4
3
  require "Helper"
4
+ require "GoogleAPI"
5
+ require "Models/Review"
5
6
  require "Models/ReviewFetcher"
6
- require "jwt"
7
- require "time"
8
7
 
9
8
  class AndroidFetcher < ReviewFetcher
10
9
 
11
- attr_accessor :token
10
+ attr_accessor :token, :googleAPI
12
11
 
13
12
  def initialize(config)
14
13
  @processors = []
15
14
  @config = config
16
15
  @platform = 'Android'
17
16
  @logger = ZLogger.new(config.baseExecutePath)
18
- @token = generateJWT()
17
+ @googleAPI = GoogleAPI.new(config.keyFilePath, config.baseExecutePath, ["https://www.googleapis.com/auth/androidpublisher"])
19
18
 
20
19
  puts "[AndroidFetcher] Init Success."
21
20
  end
@@ -36,7 +35,7 @@ class AndroidFetcher < ReviewFetcher
36
35
  puts "[AndroidFetcher] Fetch reviews in #{config.packageName}"
37
36
 
38
37
  loop do
39
- reviewsInfo = request(reviewsInfoLink)
38
+ reviewsInfo = googleAPI.request(reviewsInfoLink)
40
39
  reviewsInfoLink = reviewsInfo&.dig("tokenPagination", "nextPageToken")
41
40
 
42
41
  customerReviews = reviewsInfo["reviews"]
@@ -96,7 +95,7 @@ class AndroidFetcher < ReviewFetcher
96
95
  end
97
96
 
98
97
  if deviceInfo.length > 0
99
- customerReviewTitle = "#{deviceInfo.join("/")}"
98
+ customerReviewReviewerNickname = "#{customerReviewReviewerNickname} - #{deviceInfo.join("/")}"
100
99
  end
101
100
  end
102
101
 
@@ -138,58 +137,4 @@ class AndroidFetcher < ReviewFetcher
138
137
  processReviews(reviews, platform)
139
138
  end
140
139
  end
141
-
142
- private
143
- def generateJWT()
144
- payload = {
145
- iss: config.clientEmail,
146
- sub: config.clientEmail,
147
- scope: "https://www.googleapis.com/auth/androidpublisher",
148
- aud: config.tokenURI,
149
- iat: Time.now.to_i,
150
- exp: Time.now.to_i + 60*20
151
- }
152
-
153
- rsa_private = OpenSSL::PKey::RSA.new(config.keyContent)
154
- token = JWT.encode payload, rsa_private, 'RS256', header_fields = {kid:config.keyID, typ:"JWT"}
155
-
156
- uri = URI(config.tokenURI)
157
- https = Net::HTTP.new(uri.host, uri.port)
158
- https.use_ssl = true
159
- request = Net::HTTP::Post.new(uri)
160
- request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=#{token}"
161
-
162
- response = https.request(request).read_body
163
- result = JSON.parse(response)
164
-
165
- return result["access_token"]
166
- end
167
-
168
- private
169
- def request(url, retryCount = 0)
170
- uri = URI(url)
171
- https = Net::HTTP.new(uri.host, uri.port)
172
- https.use_ssl = true
173
-
174
- request = Net::HTTP::Get.new(uri)
175
- request['Authorization'] = "Bearer #{token}";
176
-
177
- response = https.request(request).read_body
178
-
179
- result = JSON.parse(response)
180
- if result["reviews"].nil?
181
- if retryCount >= 10
182
- raise "Could not connect to androidpublisher.googleapis.com, error message: #{response}"
183
- else
184
- @token = generateJWT()
185
- message = "JWT Expired, refresh a new one. (#{retryCount + 1})"
186
- logger.logWarn(message)
187
- puts "[AndroidFetcher] #{message}"
188
- return request(url, retryCount + 1)
189
- end
190
- else
191
- return result
192
- end
193
-
194
- end
195
140
  end
data/lib/GoogleAPI.rb ADDED
@@ -0,0 +1,99 @@
1
+ $lib = File.expand_path('../lib', File.dirname(__FILE__))
2
+
3
+ require "jwt"
4
+ require "time"
5
+
6
+ class GoogleAPI < Processor
7
+
8
+ attr_accessor :keyContent, :keyID, :tokenURI, :clientEmail, :logger, :scopes, :token
9
+
10
+ def initialize(keyFilePath, baseExecutePath, scopes = [])
11
+
12
+ @logger = ZLogger.new(baseExecutePath)
13
+
14
+ keyFileContent = JSON.parse(File.read(keyFilePath))
15
+
16
+ @keyContent = Helper.unwrapRequiredParameter(keyFileContent,"private_key")
17
+ @keyID = Helper.unwrapRequiredParameter(keyFileContent,"private_key_id")
18
+ @clientEmail = Helper.unwrapRequiredParameter(keyFileContent,"client_email")
19
+ @tokenURI = Helper.unwrapRequiredParameter(keyFileContent,"token_uri")
20
+
21
+ @scopes = scopes
22
+
23
+ @token = generateJWT()
24
+
25
+ puts "[GoogleAPI] Init Success."
26
+ end
27
+
28
+ def request(url, method = "GET", data = nil, retryCount = 0)
29
+ uri = URI(url)
30
+ https = Net::HTTP.new(uri.host, uri.port)
31
+ https.use_ssl = true
32
+
33
+ request = Net::HTTP::Get.new(uri)
34
+ if method.upcase == "POST"
35
+ request = Net::HTTP::Post.new(uri)
36
+ if !data.nil?
37
+ request['Content-Type'] = 'application/json'
38
+ request.body = JSON.dump(data)
39
+ end
40
+ end
41
+
42
+ request['Authorization'] = "Bearer #{token}";
43
+
44
+ response = https.request(request).read_body
45
+ result = JSON.parse(response)
46
+
47
+ if !result["error"].nil?
48
+ if retryCount >= 10
49
+ raise "Could not connect to #{tokenURI}, key id: #{keyID}, error message: #{response}"
50
+ else
51
+ @token = generateJWT()
52
+ message = "JWT Invalid, retry. (#{retryCount + 1})"
53
+ logger.logWarn(message)
54
+ puts "[GoogleAPI] #{message}"
55
+ return request(url, method, data, retryCount + 1)
56
+ end
57
+ else
58
+ return result
59
+ end
60
+
61
+ end
62
+
63
+ private
64
+ def generateJWT(retryCount = 0)
65
+ payload = {
66
+ iss: clientEmail,
67
+ sub: clientEmail,
68
+ scope: scopes.join(' '),
69
+ aud: tokenURI,
70
+ iat: Time.now.to_i,
71
+ exp: Time.now.to_i + 60*20
72
+ }
73
+
74
+ rsa_private = OpenSSL::PKey::RSA.new(keyContent)
75
+ token = JWT.encode payload, rsa_private, 'RS256', header_fields = {kid:keyID, typ:"JWT"}
76
+
77
+ uri = URI(tokenURI)
78
+ https = Net::HTTP.new(uri.host, uri.port)
79
+ https.use_ssl = true
80
+ request = Net::HTTP::Post.new(uri)
81
+ request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=#{token}"
82
+
83
+ response = https.request(request).read_body
84
+ result = JSON.parse(response)
85
+
86
+ if result["access_token"].nil?
87
+ if retryCount >= 10
88
+ raise "Could not generate google api JWT, key id: #{keyID}, error message: #{response}"
89
+ else
90
+ message = "Could not generate google api JWT, retry. (#{retryCount + 1})"
91
+ logger.logWarn(message)
92
+ puts "[GoogleAPI] #{message}"
93
+ return generateJWT(retryCount + 1)
94
+ end
95
+ else
96
+ return result["access_token"]
97
+ end
98
+ end
99
+ end
@@ -5,23 +5,17 @@ require "Helper"
5
5
  require "time"
6
6
 
7
7
  class AndroidConfig
8
- attr_accessor :keyContent, :keyID, :tokenURI, :clientEmail, :packageName, :accountID, :appID, :baseExecutePath
8
+ attr_accessor :keyFilePath, :packageName, :accountID, :appID, :baseExecutePath
9
9
  def initialize(configYMLObj, configFilePath, baseExecutePath)
10
- keyFilePath = Helper.unwrapRequiredParameter(configYMLObj,"keyFilePath")
10
+ @keyFilePath = Helper.unwrapRequiredParameter(configYMLObj,"keyFilePath")
11
11
 
12
12
  if Pathname.new(keyFilePath).absolute?
13
13
  configDir = File.dirname(configFilePath)
14
- keyFilePath = "#{configDir}#{keyFilePath}"
14
+ @keyFilePath = "#{configDir}#{keyFilePath}"
15
15
  end
16
16
 
17
- keyFileContent = JSON.parse(File.read(keyFilePath))
18
-
19
17
  @accountID = configYMLObj["playConsoleDeveloperAccountID"]
20
18
  @appID = configYMLObj["playConsoleAppID"]
21
- @keyContent = Helper.unwrapRequiredParameter(keyFileContent,"private_key")
22
- @keyID = Helper.unwrapRequiredParameter(keyFileContent,"private_key_id")
23
- @clientEmail = Helper.unwrapRequiredParameter(keyFileContent,"client_email")
24
- @tokenURI = Helper.unwrapRequiredParameter(keyFileContent,"token_uri")
25
19
  @baseExecutePath = baseExecutePath
26
20
  @packageName = Helper.unwrapRequiredParameter(configYMLObj,"packageName")
27
21
  end
@@ -0,0 +1,100 @@
1
+ $lib = File.expand_path('../lib', File.dirname(__FILE__))
2
+
3
+ require "Models/Review"
4
+ require "Models/Processor"
5
+ require "Helper"
6
+ require "pathname"
7
+ require "GoogleAPI"
8
+
9
+ class GoogleSheetProcessor < Processor
10
+
11
+ attr_accessor :keywordsInclude, :ratingsInclude, :territoriesInclude, :logger, :googleAPI, :sheetID, :sheetName, :formatValues, :timeZoneOffset
12
+
13
+ def initialize(config, configFilePath, baseExecutePath)
14
+ @config = config
15
+ @configFilePath = configFilePath
16
+ @baseExecutePath = baseExecutePath
17
+ @logger = ZLogger.new(baseExecutePath)
18
+
19
+ keyFilePath = Helper.unwrapRequiredParameter(config, "googleSheetAPIKeyFilePath")
20
+
21
+ if Pathname.new(keyFilePath).absolute?
22
+ configDir = File.dirname(configFilePath)
23
+ keyFilePath = "#{configDir}#{keyFilePath}"
24
+ end
25
+
26
+ @googleAPI = GoogleAPI.new(keyFilePath, baseExecutePath, ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/spreadsheets"])
27
+
28
+ @keywordsInclude = []
29
+ if !config["keywordsInclude"].nil?
30
+ @keywordsInclude = config["keywordsInclude"]
31
+ end
32
+
33
+ @ratingsInclude = []
34
+ if !config["ratingsInclude"].nil?
35
+ @ratingsInclude = config["ratingsInclude"]
36
+ end
37
+
38
+ @territoriesInclude = []
39
+ if !config["territoriesInclude"].nil?
40
+ @territoriesInclude = config["territoriesInclude"]
41
+ end
42
+
43
+ @timeZoneOffset = Helper.unwrapRequiredParameter(config, "googleSheetTimeZoneOffset")
44
+ @sheetID = Helper.unwrapRequiredParameter(config, "googleSheetID")
45
+ @sheetName = Helper.unwrapRequiredParameter(config, "googleSheetName")
46
+ @formatValues = []
47
+ if !config["values"].nil?
48
+ @formatValues = config["values"]
49
+ end
50
+
51
+ puts "[GoogleSheetProcessor] Init Success."
52
+ end
53
+
54
+ def processReviews(reviews, platform)
55
+
56
+ if reviews.length < 1
57
+ return reviews
58
+ end
59
+
60
+ filterReviews = reviews
61
+
62
+ if ratingsInclude.length > 0
63
+ filterReviews = filterReviews.select{ |review| ratingsInclude.map{ |rating| rating.to_i }.include? review.rating }
64
+ end
65
+
66
+ if territoriesInclude.length > 0
67
+ filterReviews = filterReviews.select{ |review| territoriesInclude.map{ |territory| territory.upcase }.include? review.territory.upcase }
68
+ end
69
+
70
+ if keywordsInclude.length > 0
71
+ keywordsInclude.select{ |keywordsInclude| keywordsInclude != "" }.each do |keywordInclude|
72
+ filterReviews = filterReviews.select{ |review| review.body.include? keywordInclude }
73
+ end
74
+ end
75
+
76
+ filterReviews.each do |review|
77
+ cols = []
78
+ formatValues.each do |formatValue|
79
+ formatValue = formatValue.gsub("%TITLE%", review.title || "")
80
+ formatValue = formatValue.gsub("%BODY%", review.body || "")
81
+ formatValue = formatValue.gsub("%RATING%", review.rating.nil? ? "" :review.rating.to_s)
82
+ formatValue = formatValue.gsub("%PLATFORM%", review.platform || "")
83
+ formatValue = formatValue.gsub("%ID%", review.id || "")
84
+ formatValue = formatValue.gsub("%USERNAME%", review.userName || "")
85
+ formatValue = formatValue.gsub("%URL%", review.url || "")
86
+ formatValue = formatValue.gsub("%TERRITORY%", review.territory || "")
87
+ formatValue = formatValue.gsub("%APPVERSION%", review.appVersion || "")
88
+ formatValue = formatValue.gsub("%CREATEDDATE%", review.createdDateTimestamp.nil? ? "" : Time.at(review.createdDateTimestamp).getlocal(timeZoneOffset).to_s)
89
+
90
+ cols.append(formatValue)
91
+ end
92
+
93
+ puts "[GoogleSheetProcessor] insert #{cols} to #{sheetID}-#{sheetName}"
94
+
95
+ googleAPI.request("https://sheets.googleapis.com/v4/spreadsheets/#{sheetID}/values/#{sheetName}:append?valueInputOption=RAW", "POST", {:values => [cols]})
96
+ end
97
+
98
+ return reviews
99
+ end
100
+ end
@@ -4,12 +4,11 @@ require "Models/Review"
4
4
  require "Models/Processor"
5
5
  require "Helper"
6
6
  require "pathname"
7
- require "jwt"
8
- require "time"
7
+ require "GoogleAPI"
9
8
 
10
9
  class GoogleTranslateProcessor < Processor
11
10
 
12
- attr_accessor :keyContent, :keyID, :tokenURI, :clientEmail, :targetLang, :territoriesExclude, :token, :logger
11
+ attr_accessor :targetLang, :territoriesExclude, :token, :logger, :googleAPI
13
12
 
14
13
  def initialize(config, configFilePath, baseExecutePath)
15
14
  @config = config
@@ -24,12 +23,7 @@ class GoogleTranslateProcessor < Processor
24
23
  keyFilePath = "#{configDir}#{keyFilePath}"
25
24
  end
26
25
 
27
- keyFileContent = JSON.parse(File.read(keyFilePath))
28
-
29
- @keyContent = Helper.unwrapRequiredParameter(keyFileContent,"private_key")
30
- @keyID = Helper.unwrapRequiredParameter(keyFileContent,"private_key_id")
31
- @clientEmail = Helper.unwrapRequiredParameter(keyFileContent,"client_email")
32
- @tokenURI = Helper.unwrapRequiredParameter(keyFileContent,"token_uri")
26
+ @googleAPI = GoogleAPI.new(keyFilePath, baseExecutePath, ["https://www.googleapis.com/auth/cloud-translation","https://www.googleapis.com/auth/cloud-platform"])
33
27
 
34
28
  @targetLang = Helper.unwrapRequiredParameter(config, "googleTranslateTargetLang")
35
29
  @territoriesExclude = []
@@ -37,8 +31,6 @@ class GoogleTranslateProcessor < Processor
37
31
  @territoriesExclude = config['googleTranslateTerritoriesExclude']
38
32
  end
39
33
 
40
- @token = generateJWT()
41
-
42
34
  puts "[GoogleTranslateProcessor] Init Success."
43
35
  end
44
36
 
@@ -55,14 +47,16 @@ class GoogleTranslateProcessor < Processor
55
47
  puts "[GoogleTranslateProcessor] translate #{reviews[index].body} from #{reviews[index].territory} to #{targetLang}"
56
48
 
57
49
  if !reviews[index].title.nil?
58
- translateTitle = translate(reviews[index].title)
50
+ translateTitle = googleAPI.request("https://translation.googleapis.com/language/translate/v2", "POST", {:q => reviews[index].title, :target => targetLang})
51
+ translateTitle = translateTitle&.dig("data", "translations", 0, "translatedText")
59
52
  if !translateTitle.nil? && translateTitle != reviews[index].title
60
53
  reviews[index].title = "#{translateTitle} (#{reviews[index].title})"
61
54
  end
62
55
  end
63
56
 
64
57
  if !reviews[index].body.nil?
65
- translateBody = translate(reviews[index].body)
58
+ translateBody = googleAPI.request("https://translation.googleapis.com/language/translate/v2", "POST", {:q => reviews[index].body, :target => targetLang})
59
+ translateBody = translateBody&.dig("data", "translations", 0, "translatedText")
66
60
  if !translateBody.nil? && translateBody != reviews[index].body
67
61
  body = "#{translateBody}"
68
62
  body += "\r\n===== Translate by Google =====\r\n"
@@ -74,60 +68,4 @@ class GoogleTranslateProcessor < Processor
74
68
 
75
69
  return reviews
76
70
  end
77
-
78
- private
79
- def generateJWT()
80
- payload = {
81
- iss: clientEmail,
82
- sub: clientEmail,
83
- scope: ["https://www.googleapis.com/auth/cloud-translation","https://www.googleapis.com/auth/cloud-platform"].join(' '),
84
- aud: tokenURI,
85
- iat: Time.now.to_i,
86
- exp: Time.now.to_i + 60*20
87
- }
88
-
89
- rsa_private = OpenSSL::PKey::RSA.new(keyContent)
90
- token = JWT.encode payload, rsa_private, 'RS256', header_fields = {kid:keyID, typ:"JWT"}
91
-
92
- uri = URI(tokenURI)
93
- https = Net::HTTP.new(uri.host, uri.port)
94
- https.use_ssl = true
95
- request = Net::HTTP::Post.new(uri)
96
- request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=#{token}"
97
-
98
- response = https.request(request).read_body
99
- result = JSON.parse(response)
100
-
101
- return result["access_token"]
102
- end
103
-
104
- private
105
- def translate(text, retryCount = 0)
106
- uri = URI("https://translation.googleapis.com/language/translate/v2")
107
- https = Net::HTTP.new(uri.host, uri.port)
108
- https.use_ssl = true
109
-
110
- request = Net::HTTP::Post.new(uri)
111
- request.body = "q=#{text}&target=#{targetLang}"
112
- request['Authorization'] = "Bearer #{token}";
113
-
114
- response = https.request(request).read_body
115
-
116
- result = JSON.parse(response)
117
- translate = result&.dig("data", "translations", 0, "translatedText")
118
- if translate.nil?
119
- if retryCount >= 10
120
- raise "Could not connect to translation.googleapis.com, error message: #{response}"
121
- else
122
- @token = generateJWT()
123
- message = "JWT Expired, refresh a new one. (#{retryCount + 1})"
124
- logger.logWarn(message)
125
- puts "[GoogleTranslateProcessor] #{message}"
126
- return request(text, retryCount + 1)
127
- end
128
- else
129
- return translate
130
- end
131
-
132
- end
133
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ZReviewTender
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.8
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ZhgChgLi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-19 00:00:00.000000000 Z
11
+ date: 2022-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http
@@ -79,6 +79,7 @@ files:
79
79
  - config/apple.example.yml
80
80
  - lib/AndroidFetcher.rb
81
81
  - lib/AppleFetcher.rb
82
+ - lib/GoogleAPI.rb
82
83
  - lib/Helper.rb
83
84
  - lib/Models/AndroidConfig.rb
84
85
  - lib/Models/AppleConfig.rb
@@ -87,6 +88,7 @@ files:
87
88
  - lib/Models/ReviewFetcher.rb
88
89
  - lib/Models/Version.rb
89
90
  - lib/Processors/FilterProcessor.rb
91
+ - lib/Processors/GoogleSheetProcessor.rb
90
92
  - lib/Processors/GoogleTranslateProcessor.rb
91
93
  - lib/Processors/ProcessorTemplate.rb
92
94
  - lib/Processors/SlackProcessor.rb