ZReviewTender 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 401f2fc6c474a7a9b49f4e09e9574ec9af12ba4e86666da4a8c51926d1f4dc8e
4
- data.tar.gz: 81bcfd837a752fa6efff0f07131d8246eedf9c3feff8b585648a5cd9ba10524c
3
+ metadata.gz: 3c3ed526dfeec33a979c0c3c5a31d269a68cabe3599ba14c2ad9df35a1667dff
4
+ data.tar.gz: cc919703c929aee31d1c0a7d59ca528734f66a776e5d530f14da27b28c97b73b
5
5
  SHA512:
6
- metadata.gz: 211bf7f2044c407689c4b96236b34801fc1c2dafe56fd23fca39accdc5e2d31345109dd2708a5aef246e5c1885542f1b549653357487b644018a8b96640f70ee
7
- data.tar.gz: aa679ef890c73f22ee8cc3a143d1c4c6714d549193f763ef5bceb20b32bc788953c92324f0b6a7422eaba8633f2bd3e0b758ca10f1111cdd27d4906168b0841e
6
+ metadata.gz: 3be31356db49a927bc7e716649e3da90d7868497ed3e5257d86b7f3480fb6591fc3e5eae1a40219988aadd45f137dd58b50bf384b47985d9f8c881c80d6b0f0a
7
+ data.tar.gz: 1de0cf6339a46f271287e747bf4449905fa4eb1bbe1682294fe9d0f4f5ea8aad95711cd96c51274720a3455152fa5567db43a4011a121e9f85cbbce9ac4eb822
data/.version ADDED
@@ -0,0 +1 @@
1
+ 1.2.0
data/bin/ZReviewTender CHANGED
@@ -7,17 +7,19 @@ $LOAD_PATH.unshift($lib)
7
7
  require "Models/AppleConfig"
8
8
  require "Models/AndroidConfig"
9
9
  require "Models/Processor"
10
+ require "Models/Version"
10
11
  require "Helper"
11
12
  require "ZLogger"
12
13
  require "AppleFetcher"
13
14
  require "AndroidFetcher"
14
15
  require "optparse"
15
16
  require "yaml"
17
+ require "fileutils"
16
18
 
17
19
  class Main
18
20
  def initialize
19
21
 
20
- ARGV << '-r' if ARGV.empty?
22
+ ARGV << '-h' if ARGV.empty?
21
23
 
22
24
  OptionParser.new do |opts|
23
25
  opts.banner = "Usage: ZReviewTender [options]"
@@ -27,30 +29,41 @@ class Main
27
29
  defaultAppleConfigFileName = "apple.yml"
28
30
  defaultAndroidConfigFileName = "android.yml"
29
31
 
30
- opts.on('-a', '--apple[=CONFIGYMLFILEPATH]', 'execute apple platform with config yml file') do |configYMLFilePath|
32
+ opts.on('-a', '--apple[=CONFIGYMLFILEPATH]', 'execute apple platform, default config yml file path: /config/apple.yml, use --apple=CONFIG_YML_FILE_PATH specify config yml file path') do |configYMLFilePath|
31
33
  if configYMLFilePath.nil?
32
34
  configYMLFilePath = "#{basePath}/#{defaultConfigDirName}/#{defaultAppleConfigFileName}"
33
35
  end
34
36
  configFileCheck(configYMLFilePath, "--apple=CONFIG_YML_FILE_PATH")
35
37
 
38
+ puts "[ZReviewTender] run -a/-apple config yml file path: #{configYMLFilePath}"
39
+
36
40
  fetcher = parseConfigYMLFile(configYMLFilePath)
37
41
  fetcher.execute()
42
+
43
+ checkLatestVersionOfZReviewTender()
38
44
  end
39
45
 
40
- opts.on('-g', '--googleAndroid[=CONFIGYMLFILEPATH]', 'execute android platform with config yml file') do |configYMLFilePath|
46
+ opts.on('-g', '--googleAndroid[=CONFIGYMLFILEPATH]', 'execute android platform, default config yml file path: /config/android.yml, use --googleAndroid=CONFIG_YML_FILE_PATH specify config yml file path') do |configYMLFilePath|
41
47
  if configYMLFilePath.nil?
42
48
  configYMLFilePath = "#{basePath}/#{defaultConfigDirName}/#{defaultAndroidConfigFileName}"
43
49
  end
44
50
  configFileCheck(configYMLFilePath, "--googleAndroid=CONFIG_YML_FILE_PATH")
45
51
 
52
+ puts "[ZReviewTender] run -g/-googleAndroid config yml file path: #{configYMLFilePath}"
53
+
46
54
  fetcher = parseConfigYMLFile(configYMLFilePath)
47
55
  fetcher.execute()
56
+
57
+ checkLatestVersionOfZReviewTender()
48
58
  end
49
59
 
50
- opts.on('-r', '--run=[=CONFIGFOLDERNAME]', 'execute both android and apple, specify an /config folder name') do |configFolderName|
60
+ opts.on('-r', '--run=[=CONFIGFOLDERNAME]', 'execute both android and apple, specify a /config folder path') do |configFolderName|
51
61
  if configFolderName.nil?
52
62
  configFolderName = defaultConfigDirName
53
63
  end
64
+
65
+ puts "[ZReviewTender] run -r/--run config folder path: #{configFolderName}"
66
+
54
67
  androidConfigFilePath = "#{basePath}/#{configFolderName}/#{defaultAndroidConfigFileName}"
55
68
  configFileCheck(androidConfigFilePath, "--googleAndroid=CONFIG_YML_FILE_PATH")
56
69
 
@@ -64,10 +77,61 @@ class Main
64
77
 
65
78
  fetcher = parseConfigYMLFile(appleConfigFilePath)
66
79
  fetcher.execute()
67
- end
80
+
81
+ checkLatestVersionOfZReviewTender()
82
+ end
83
+
84
+ opts.on('-i', '--init', 'init config yml file from template.') do
85
+ configTemplateFolder = "#{File.expand_path("..", __dir__)}/config"
86
+ appleSourceExampleYML = "#{configTemplateFolder}/apple.example.yml"
87
+ androidSourceExampleYML = "#{configTemplateFolder}/android.example.yml"
88
+ appleDestExampleYML = "#{configTemplateFolder}/apple.yml"
89
+ androidDestExampleYML = "#{configTemplateFolder}/android.yml"
90
+
91
+ if File.exists?(appleSourceExampleYML)
92
+ if File.exists?(appleDestExampleYML)
93
+ puts "Failed! Config YML File Exists: #{appleDestExampleYML}"
94
+ else
95
+ FileUtils.cp(appleSourceExampleYML, appleDestExampleYML)
96
+ puts "Init Apple Config YML File at:#{appleDestExampleYML} Success!"
97
+ end
98
+ end
99
+ #
100
+ if File.exists?(androidSourceExampleYML)
101
+ if File.exists?(androidDestExampleYML)
102
+ puts "Failed! Config YML File Exists: #{androidDestExampleYML}"
103
+ else
104
+ FileUtils.cp(androidSourceExampleYML, androidDestExampleYML)
105
+ puts "Init Android Config YML File at:#{androidDestExampleYML} Success!"
106
+ end
107
+ end
108
+
109
+ checkLatestVersionOfZReviewTender()
110
+ end
111
+
112
+ opts.on('-n', '--new', 'update to latest version of ZReviewTender by RubyGem') do
113
+ version = Version.new
114
+
115
+ if version.getRemoteVersion() > version.getLocalVersion()
116
+ system('gem update ZReviewTender')
117
+ else
118
+ puts "You're using the latest version of ZReviewTender!"
119
+ end
120
+ end
68
121
  end.parse!
69
122
  end
70
123
 
124
+ private
125
+ def checkLatestVersionOfZReviewTender()
126
+ version = Version.new
127
+ if version.getRemoteVersion() > version.getLocalVersion()
128
+ puts "##########################################################"
129
+ puts "##### New Version Available!!! #####"
130
+ puts "##### Please type `ZReviewTender -n` to update!! #####"
131
+ puts "##########################################################"
132
+ end
133
+ end
134
+
71
135
  private
72
136
  def configFileCheck(path, command)
73
137
  if !File.exists? path
@@ -120,8 +184,14 @@ class Main
120
184
  end
121
185
  end
122
186
 
123
- begin
187
+ begin
188
+ puts "#https://github.com/ZhgChgLi/ZReviewTender"
189
+ puts "You have read and agree with the Disclaimer."
124
190
  Main.new()
191
+ puts "Execute Successfully!!!"
192
+ puts "#https://github.com/ZhgChgLi/ZReviewTender"
193
+ puts "#Thanks for using this tool."
194
+ puts "#If this is helpful, please help to star the repo or recommend it to your friends."
125
195
  rescue => e
126
196
  logger = ZLogger.new(ENV['PWD'] || ::Dir.pwd)
127
197
  title = "#Error: #{e.class} #{e.message}"
@@ -0,0 +1,26 @@
1
+ platform: 'android'
2
+ packageName: '' # Android App Package Name
3
+ keyFilePath: '' # Google Android Publisher API Credential .json File Path
4
+ playConsoleDeveloperAccountID: '' # Google Console Developer Account ID
5
+ playConsoleAppID: '' # Google Console App ID
6
+ processors:
7
+ - FilterProcessor:
8
+ class: "FilterProcessor"
9
+ enable: true # enable
10
+ keywordsInclude: [] # keywords you want to filter out
11
+ ratingsInclude: [] # ratings you want to filter out
12
+ territoriesInclude: [] # territories you want to filter out(language for android e.g. zh-Hant, en)
13
+ - GoogleTranslateProcessor: # Google Translate Processor, will translate review text to your language, you can remove whole block if you don't needed it.
14
+ class: "GoogleTranslateProcessor"
15
+ enable: false # enable
16
+ googleTranslateAPIKeyFilePath: '' # Google Translate API Credential .json File Path
17
+ googleTranslateTargetLang: 'zh-TW' # Translate to what Language
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
+ - SlackProcessor: # Slack Processor, resend App Review to Slack.
20
+ class: "SlackProcessor"
21
+ enable: true # enable
22
+ slackTimeZoneOffset: "+08:00" # Review Created Date TimeZone
23
+ slackAttachmentGroupByNumber: "1" # 1~100, how many review message in 1 slack message.
24
+ slackBotToken: "" # Slack Bot Token, send slack message throught Slack Bot.
25
+ slackBotTargetChannel: "" # Slack Bot Token, send slack message throught Slack Bot. (recommended, first priority)
26
+ slackInCommingWebHookURL: "" # Slack In-Comming WebHook URL, Send slack message throught In-Comming WebHook, not recommended, deprecated.
@@ -0,0 +1,26 @@
1
+ platform: 'apple'
2
+ appStoreConnectP8PrivateKeyFilePath: '' # APPLE STORE CONNECT API PRIVATE .p8 KEY File Path
3
+ appStoreConnectP8PrivateKeyID: '' # APPLE STORE CONNECT API PRIVATE KEY ID
4
+ appStoreConnectIssueID: '' # APPLE STORE CONNECT ISSUE ID
5
+ appID: '' # APP ID
6
+ processors:
7
+ - FilterProcessor:
8
+ class: "FilterProcessor"
9
+ enable: true # enable
10
+ keywordsInclude: [] # keywords you want to filter out
11
+ ratingsInclude: [] # ratings you want to filter out
12
+ territoriesInclude: [] # territories you want to filter out
13
+ - GoogleTranslateProcessor: # Google Translate Processor, will translate review text to your language, you can remove whole block if you don't needed it.
14
+ class: "GoogleTranslateProcessor"
15
+ enable: false # enable
16
+ googleTranslateAPIKeyFilePath: '' # Google Translate API Credential .json File Path
17
+ googleTranslateTargetLang: 'zh-TW' # Translate to what Language
18
+ googleTranslateTerritoriesExclude: ["TWN","CHN"] # Review origin Territory that you don't want to translate.
19
+ - SlackProcessor: # Slack Processor, resend App Review to Slack.
20
+ class: "SlackProcessor"
21
+ enable: true # enable
22
+ slackTimeZoneOffset: "+08:00" # Review Created Date TimeZone
23
+ slackAttachmentGroupByNumber: "1" # 1~100, how many review message in 1 slack message.
24
+ slackBotToken: "" # Slack Bot Token, send slack message throught Slack Bot.
25
+ slackBotTargetChannel: "" # Slack Bot Token, send slack message throught Slack Bot. (recommended, first priority)
26
+ slackInCommingWebHookURL: "" # Slack In-Comming WebHook URL, Send slack message throught In-Comming WebHook, not recommended, deprecated.
@@ -17,16 +17,21 @@ class AndroidFetcher < ReviewFetcher
17
17
 
18
18
  @client = Google::Apis::AndroidpublisherV3::AndroidPublisherService.new
19
19
  @client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: config.keyContent, scope: 'https://www.googleapis.com/auth/androidpublisher')
20
+
21
+ puts "[AndroidFetcher] Init Success."
20
22
  end
21
23
 
22
24
  def execute()
23
25
 
24
26
  latestCheckTimestamp = getPlatformLatestCheckTimestamp()
25
27
 
28
+ puts "[AndroidFetcher] Start execute(), latestCheckTimestamp: #{latestCheckTimestamp}"
29
+
26
30
  reviews = []
27
31
 
28
32
  # Google API Bug, couldn't specify limit/offse/pagination, google only return a few recent reviews.
29
33
  customerReviews = client.list_reviews(config.packageName).reviews
34
+ puts "[AndroidFetcher] Fetch reviews in #{config.packageName}, count: #{customerReviews.length}"
30
35
  customerReviews.each do |customerReview|
31
36
 
32
37
  customerReviewID = customerReview.review_id
@@ -53,9 +58,13 @@ class AndroidFetcher < ReviewFetcher
53
58
  end
54
59
 
55
60
  reviews = reviews.reject{ |review| latestCheckTimestamp >= review.createdDateTimestamp }.sort! { |a, b| a.createdDateTimestamp <=> b.createdDateTimestamp }
56
-
61
+
62
+ puts "[AndroidFetcher] latest reviews count: #{reviews.length}"
63
+
57
64
  if reviews.length > 0
58
65
 
66
+ puts "[AndroidFetcher] latest review: #{reviews.last.body}, #{reviews.last.createdDateTimestamp}"
67
+
59
68
  setPlatformLatestCheckTimestamp(reviews.last.createdDateTimestamp)
60
69
 
61
70
  # init first time, send welcome message
data/lib/AppleFetcher.rb CHANGED
@@ -18,16 +18,22 @@ class AppleFetcher < ReviewFetcher
18
18
  @logger = ZLogger.new(config.baseExecutePath)
19
19
  @platform = 'Apple'
20
20
  @token = generateJWT()
21
+
22
+ puts "[AppleFetcher] Init Success."
21
23
  end
22
24
 
23
25
  def execute()
24
26
 
25
27
  latestCheckTimestamp = getPlatformLatestCheckTimestamp()
26
28
 
29
+ puts "[AppleFetcher] Start execute(), latestCheckTimestamp: #{latestCheckTimestamp}"
30
+
27
31
  reviews = fetchReviews(latestCheckTimestamp)
28
32
 
29
33
  if reviews.length > 0
30
34
  reviews.sort! { |a, b| a.createdDateTimestamp <=> b.createdDateTimestamp }
35
+
36
+ puts "[AppleFetcher] latest review: #{reviews.last.body}, #{reviews.last.createdDateTimestamp}"
31
37
  setPlatformLatestCheckTimestamp(reviews.last.createdDateTimestamp)
32
38
 
33
39
  # init first time, send welcome message
@@ -46,10 +52,14 @@ class AppleFetcher < ReviewFetcher
46
52
  customerReviewsLink = "https://api.appstoreconnect.apple.com/v1/apps/#{config.appID}/customerReviews?sort=-createdDate"
47
53
  reviews = []
48
54
 
55
+ puts "[AppleFetcher] Fetch reviews in #{config.appID}"
56
+
49
57
  loop do
50
58
  customerReviews = request(customerReviewsLink)
51
59
  customerReviewsLink = customerReviews&.dig("links", "next")
52
60
 
61
+ puts "[AppleFetcher] Fetch reviews, page url: #{customerReviewsLink}"
62
+ puts "[AppleFetcher] Fetch reviews, page's reviews count: #{customerReviews&.dig("data").length}"
53
63
  customerReviews&.dig("data").each do |customerReview|
54
64
 
55
65
  customerReviewID = customerReview&.dig("id")
@@ -83,11 +93,18 @@ class AppleFetcher < ReviewFetcher
83
93
  break if customerReviewsLink.nil?
84
94
  end
85
95
 
96
+ puts "[AppleFetcher] Fetch reviews in #{config.appID}, total reviews count: #{reviews.length}"
97
+
86
98
  return reviews
87
99
  end
88
100
 
101
+ # because customerReviews, won't give us app version information
102
+ # so, we need to query it from appStoreVersions api and combine together
89
103
  private
90
104
  def fullfillAppInfo(reviews)
105
+
106
+ puts "[AppleFetcher] Full fill app version information."
107
+
91
108
  customerReviewWhichAppVersionIsNil = reviews.select{ |review| review.appVersion.nil? }.map.with_index { |review, index| {"id":review.id, "index": index} }
92
109
 
93
110
  appStoreVersionsLink = "https://api.appstoreconnect.apple.com/v1/apps/#{config.appID}/appStoreVersions"
@@ -96,6 +113,8 @@ class AppleFetcher < ReviewFetcher
96
113
  appStoreVersions = request(appStoreVersionsLink)
97
114
  appStoreVersionsLink = appStoreVersions&.dig("links", "next")
98
115
 
116
+ puts "[AppleFetcher] List app store version, page url: #{appStoreVersionsLink}"
117
+ puts "[AppleFetcher] List app store version, versions count: #{appStoreVersions&.dig("data").length}"
99
118
  appStoreVersions&.dig("data").each do |appStoreVersion|
100
119
  applePlatform = appStoreVersion&.dig("attributes","platform")
101
120
  versionString = appStoreVersion&.dig("attributes","versionString")
@@ -108,6 +127,8 @@ class AppleFetcher < ReviewFetcher
108
127
  customerReviews = request(customerReviewsLink)
109
128
  customerReviewsLink = customerReviews&.dig("links", "next")
110
129
 
130
+ puts "[AppleFetcher] Fetch version reviews, page url: #{customerReviewsLink}"
131
+ puts "[AppleFetcher] Fetch version reviews, reviews count: #{customerReviews&.dig("data").length}"
111
132
  customerReviews&.dig("data").each do |customerReview|
112
133
  customerReviewID = customerReview&.dig("id")
113
134
  if customerReviewID.nil?
@@ -121,6 +142,8 @@ class AppleFetcher < ReviewFetcher
121
142
 
122
143
  customerReviewWhichAppVersionIsNil.delete_at(findIndex)
123
144
 
145
+ puts "[AppleFetcher] Count of reviews need full fill app version: #{customerReviewWhichAppVersionIsNil.length}"
146
+
124
147
  if customerReviewWhichAppVersionIsNil.length < 1
125
148
  customerReviewsLink = nil
126
149
  break
@@ -172,7 +195,9 @@ class AppleFetcher < ReviewFetcher
172
195
  raise "Could not connect to api.appstoreconnect.apple.com, error message: #{response}"
173
196
  else
174
197
  @token = generateJWT()
175
- logger.logWarn("JWT Expired, refresh a new one. (#{retryCount + 1})")
198
+ message = "JWT Expired, refresh a new one. (#{retryCount + 1})"
199
+ logger.logWarn(message)
200
+ puts "[AppleFetcher] #{message}"
176
201
  return request(url, retryCount + 1)
177
202
  end
178
203
  else
@@ -0,0 +1,39 @@
1
+ $lib = File.expand_path('../lib', File.dirname(__FILE__))
2
+
3
+ require "net/http"
4
+
5
+ class Version
6
+ def getLocalVersion()
7
+ versionFilePath = "#{File.expand_path("../..", __dir__)}/.version"
8
+
9
+ result = nil
10
+ if File.file?(versionFilePath)
11
+ result = File.read(versionFilePath).strip
12
+ else
13
+ result = Gem.loaded_specs["ZReviewTender"].version.version
14
+ end
15
+
16
+ if !result.nil?
17
+ Gem::Version.new(result)
18
+ else
19
+ nil
20
+ end
21
+ end
22
+
23
+ def getRemoteVersion()
24
+ apiPath = 'https://rubygems.org/api/v1/gems/ZReviewTender.json'
25
+
26
+ uri = URI(apiPath)
27
+ https = Net::HTTP.new(uri.host, uri.port)
28
+ https.use_ssl = true
29
+ request = Net::HTTP::Get.new(uri)
30
+ response = https.request(request).read_body
31
+ result = JSON.parse(response)
32
+
33
+ if !result['version'].nil?
34
+ Gem::Version.new(result['version'])
35
+ else
36
+ nil
37
+ end
38
+ end
39
+ end
@@ -27,6 +27,8 @@ class FilterProcessor < Processor
27
27
  if !config["territoriesInclude"].nil?
28
28
  @territoriesInclude = config["territoriesInclude"]
29
29
  end
30
+
31
+ puts "[FilterProcessor] Init Success."
30
32
  end
31
33
 
32
34
  def processReviews(reviews, platform)
@@ -35,17 +37,23 @@ class FilterProcessor < Processor
35
37
  end
36
38
 
37
39
  if ratingsInclude.length > 0
40
+ orgReviewsCount = reviews.length
38
41
  reviews = reviews.select{ |review| ratingsInclude.map{ |rating| rating.to_i }.include? review.rating }
42
+ puts "[FilterProcessor] filter out ratings from #{orgReviewsCount} to #{reviews.length}"
39
43
  end
40
44
 
41
45
  if territoriesInclude.length > 0
46
+ orgReviewsCount = reviews.length
42
47
  reviews = reviews.select{ |review| territoriesInclude.map{ |territory| territory.upcase }.include? review.territory.upcase }
48
+ puts "[FilterProcessor] filter out ratings from #{orgReviewsCount} to #{reviews.length}"
43
49
  end
44
50
 
45
51
  if keywordsInclude.length > 0
52
+ orgReviewsCount = reviews.length
46
53
  keywordsInclude.select{ |keywordsInclude| keywordsInclude != "" }.each do |keywordInclude|
47
54
  reviews = reviews.select{ |review| review.body.include? keywordInclude }
48
55
  end
56
+ puts "[FilterProcessor] filter out ratings from #{orgReviewsCount} to #{reviews.length}"
49
57
  end
50
58
 
51
59
  return reviews
@@ -30,6 +30,8 @@ class GoogleTranslateProcessor < Processor
30
30
  if !config['googleTranslateTerritoriesExclude'].nil? && config['googleTranslateTerritoriesExclude'].length > 0
31
31
  @territoriesExclude = config['googleTranslateTerritoriesExclude']
32
32
  end
33
+
34
+ puts "[GoogleTranslateProcessor] Init Success."
33
35
  end
34
36
 
35
37
  def processReviews(reviews, platform)
@@ -42,6 +44,8 @@ class GoogleTranslateProcessor < Processor
42
44
  next
43
45
  end
44
46
 
47
+ puts "[GoogleTranslateProcessor] translate #{reviews[index].body} from #{reviews[index].territory} to #{targetLang}"
48
+
45
49
  if !reviews[index].title.nil?
46
50
  reviews[index].title = "#{client.translate reviews[index].title, to: targetLang} (#{reviews[index].title})"
47
51
  end
@@ -33,6 +33,8 @@ class SlackProcessor < Processor
33
33
  elsif !botToken.nil? && botToken != "" && (targetChannel.nil? || targetChannel == "")
34
34
  raise "must specify slackBotTargetChannel in SlackProcessor."
35
35
  end
36
+
37
+ puts "[SlackProcessor] Init Success."
36
38
  end
37
39
 
38
40
  def processReviews(reviews, platform)
@@ -74,7 +76,7 @@ class SlackProcessor < Processor
74
76
 
75
77
  loop do
76
78
  payload = pendingPayloads.shift
77
-
79
+
78
80
  result = request(payload)
79
81
  if !result[:ok]
80
82
  logger.logError(payload)
@@ -85,6 +87,7 @@ class SlackProcessor < Processor
85
87
  end
86
88
  end
87
89
 
90
+ puts "[SlackProcessor] Send new Review messages, rest: #{pendingPayloads.length}"
88
91
  break if pendingPayloads.length < 1
89
92
  end
90
93
 
@@ -109,6 +112,7 @@ class SlackProcessor < Processor
109
112
 
110
113
  payload.attachments.append(attachment)
111
114
 
115
+ puts "[SlackProcessor] sendWelcomMessage(#{title})"
112
116
  request(payload)
113
117
  end
114
118
 
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.1.1
4
+ version: 1.2.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-12 00:00:00.000000000 Z
11
+ date: 2022-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http
@@ -73,7 +73,10 @@ executables:
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".version"
76
77
  - bin/ZReviewTender
78
+ - config/android.example.yml
79
+ - config/apple.example.yml
77
80
  - lib/AndroidFetcher.rb
78
81
  - lib/AppleFetcher.rb
79
82
  - lib/Helper.rb
@@ -82,6 +85,7 @@ files:
82
85
  - lib/Models/Processor.rb
83
86
  - lib/Models/Review.rb
84
87
  - lib/Models/ReviewFetcher.rb
88
+ - lib/Models/Version.rb
85
89
  - lib/Processors/FilterProcessor.rb
86
90
  - lib/Processors/GoogleTranslateProcessor.rb
87
91
  - lib/Processors/ProcessorTemplate.rb