ZReviewTender 1.3.6 → 1.3.8

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: feb984f506b75958c72f8761516e3a2f2eb7487bebe769cb34749b5ee9b7922e
4
- data.tar.gz: 6e27d2cf2cb46cef519dec0b5c47504bd8d3db94dc36836b5994bedb41b36a13
3
+ metadata.gz: '016962d0d7c4215f6c60a77d20fb83290d5cd5b65e6883de27d7fb5116cfccdb'
4
+ data.tar.gz: 84810201df2669c00b955a8d7da1382112dd4041e963b8cbd3730dc05e988f8c
5
5
  SHA512:
6
- metadata.gz: 1cc47714f9d05221d981fd09439a12ebb053e10233057b09594a1e814a5a9481842a280e613ad14ae650743e470a9d403371b3fba94b75524e1a0073ee2fc3cf
7
- data.tar.gz: 4e67b7b958027bf74a4c0f870d26b30f77ac12da9e7b4b9cd1cde3e4a94805606bc2d9d8aab2d12194d4b8af94196882869d7ff4cc536a671eb2c3899ad3e5a9
6
+ metadata.gz: a2cbe8d510432fb5a353faa7357ea5b9b194d58d8ef4f3e8dfec69792ab3f8b4512c1b43efb26d525be4ccb62c42ad61ebe3f6c9c37ebecd43da4fc6b71d4d4d
7
+ data.tar.gz: 520a4d667e91b28dba82c1b5f7829fd6566c7b0976ca7c90f7620b9d857e6efa463dd854d2eb3f5b9629e106557349b7f2dab031dfd8a20e457912c87dbd9d03
data/.version CHANGED
@@ -1 +1 @@
1
- 1.3.6
1
+ 1.3.8
@@ -46,6 +46,30 @@ processors:
46
46
  # %APPVERSION% for review's reviewer app version
47
47
  # %CREATEDDATE% for review's created date
48
48
 
49
+ keywordsInclude: [] # keywords you want to filter out
50
+ ratingsInclude: [] # ratings you want to filter out
51
+ territoriesInclude: [] # territories you want to filter out(language for android e.g. zh-Hant, en)
52
+ - AsanaProcessor:
53
+ class: "AsanaProcessor"
54
+ enable: false # enable
55
+ asanaTimeZoneOffset: "+08:00"
56
+ asanaToken: "" # Asana Personal Access Token, get it here -> https://app.asana.com/0/my-apps
57
+ asanaProjectID: "" # Asana Project ID, get it in project url -> https://app.asana.com/0/asanaProjectID/list
58
+ asanaSectionName: "" # Task Target Project - Section Name, optional
59
+ asanaTaskTitleTemplate: "%PLATFORM% - %RATING% ⭐️ - %TITLE%" # Asana Task Title Template
60
+ asanaTaskBodyTemplate: "Title: %TITLE%\n---\nBody:\n%BODY%\n---\n- UserName: %USERNAME%\n- App Version: %APPVERSION%\n- Date:%CREATEDDATE%" # Asana Task Body Template
61
+ # you can uses magic variable below to compose string.
62
+ # %TITLE% for review's title
63
+ # %BODY% for review's content
64
+ # %RATING% for review's rating 1~5
65
+ # %PLATFORM% for review's platform Apple or Android
66
+ # %ID% for review's ID
67
+ # %USERNAME% for review's reviewer username
68
+ # %URL% for link to review
69
+ # %TERRITORY% for review's territory (territory for Apple e.g. TWN)
70
+ # %APPVERSION% for review's reviewer app version
71
+ # %CREATEDDATE% for review's created date
72
+
49
73
  keywordsInclude: [] # keywords you want to filter out
50
74
  ratingsInclude: [] # ratings you want to filter out
51
75
  territoriesInclude: [] # territories you want to filter out(language for android e.g. zh-Hant, en)
@@ -47,6 +47,30 @@ processors:
47
47
  # %APPVERSION% for review's reviewer app version
48
48
  # %CREATEDDATE% for review's created date
49
49
 
50
+ keywordsInclude: [] # keywords you want to filter out
51
+ ratingsInclude: [] # ratings you want to filter out
52
+ territoriesInclude: [] # territories you want to filter out (territory for Apple e.g. TWN)
53
+ - AsanaProcessor:
54
+ class: "AsanaProcessor"
55
+ enable: false # enable
56
+ asanaTimeZoneOffset: "+08:00"
57
+ asanaToken: "" # Asana Personal Access Token, get it here -> https://app.asana.com/0/my-apps
58
+ asanaProjectID: "" # Asana Project ID, get it in project url -> https://app.asana.com/0/asanaProjectID/list
59
+ asanaSectionName: "" # Task Target Project - Section Name, optional
60
+ asanaTaskTitleTemplate: "%PLATFORM% - %RATING% ⭐️ - %TITLE%" # Asana Task Title Template
61
+ asanaTaskBodyTemplate: "Title: %TITLE%\n---\nBody:\n%BODY%\n---\n- UserName: %USERNAME%\n- App Version: %APPVERSION%\n- Date:%CREATEDDATE%" # Asana Task Body Template
62
+ # you can uses magic variable below to compose string.
63
+ # %TITLE% for review's title
64
+ # %BODY% for review's content
65
+ # %RATING% for review's rating 1~5
66
+ # %PLATFORM% for review's platform Apple or Android
67
+ # %ID% for review's ID
68
+ # %USERNAME% for review's reviewer username
69
+ # %URL% for link to review
70
+ # %TERRITORY% for review's territory (territory for Apple e.g. TWN)
71
+ # %APPVERSION% for review's reviewer app version
72
+ # %CREATEDDATE% for review's created date
73
+
50
74
  keywordsInclude: [] # keywords you want to filter out
51
75
  ratingsInclude: [] # ratings you want to filter out
52
76
  territoriesInclude: [] # territories you want to filter out (territory for Apple e.g. TWN)
@@ -112,7 +112,7 @@ class AndroidFetcher < ReviewFetcher
112
112
  if !config.accountID.nil? && !config.appID.nil?
113
113
  url = "https://play.google.com/console/developers/#{config.accountID}/app/#{config.appID}/user-feedback/review-details?reviewId=#{customerReviewID}"
114
114
  end
115
- reviews.append(Review.new(customerReviewPlatform, customerReviewID, customerReviewReviewerNickname, customerReviewRating, customerReviewTitle, customerReviewBody, customerReviewCreatedDateTimestamp, url, customerReviewVersionString, customerReviewTerritory))
115
+ reviews.append(Review.new(customerReviewPlatform, customerReviewID, customerReviewReviewerNickname, customerReviewRating, customerReviewTitle, customerReviewBody, customerReviewCreatedDateTimestamp, url, customerReviewVersionString, customerReviewTerritory, {}))
116
116
 
117
117
  # init first time, need first review to set as latestCheckTimestamp
118
118
  if latestCheckTimestamp == 0
data/lib/AppleFetcher.rb CHANGED
@@ -80,7 +80,7 @@ class AppleFetcher < ReviewFetcher
80
80
  break
81
81
  else
82
82
  url = "https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{config.appID}/ios/ratingsResponses"
83
- reviews.append(Review.new(nil, customerReviewID, customerReviewReviewerNickname, customerReviewRating, customerReviewTitle, customerReviewBody, customerReviewCreatedDateTimestamp, url, nil, customerReviewTerritory))
83
+ reviews.append(Review.new(nil, customerReviewID, customerReviewReviewerNickname, customerReviewRating, customerReviewTitle, customerReviewBody, customerReviewCreatedDateTimestamp, url, nil, customerReviewTerritory, {}))
84
84
 
85
85
  # init first time, need first review to set as latestCheckTimestamp
86
86
  if latestCheckTimestamp == 0
@@ -13,4 +13,19 @@ class Processor
13
13
  def processReviews(reviews, platform)
14
14
 
15
15
  end
16
+
17
+ def renderReview(templateText, review, timeZoneOffset)
18
+ templateText = templateText.gsub("%TITLE%", review.title || "")
19
+ templateText = templateText.gsub("%BODY%", review.body || "")
20
+ templateText = templateText.gsub("%RATING%", review.rating.nil? ? "" :review.rating.to_s)
21
+ templateText = templateText.gsub("%PLATFORM%", review.platform || "")
22
+ templateText = templateText.gsub("%ID%", review.id || "")
23
+ templateText = templateText.gsub("%USERNAME%", review.userName || "")
24
+ templateText = templateText.gsub("%URL%", review.url || "")
25
+ templateText = templateText.gsub("%TERRITORY%", review.territory || "")
26
+ templateText = templateText.gsub("%APPVERSION%", review.appVersion || "")
27
+ templateText = templateText.gsub("%CREATEDDATE%", review.createdDateTimestamp.nil? ? "" : Time.at(review.createdDateTimestamp).getlocal(timeZoneOffset).to_s)
28
+
29
+ return templateText
30
+ end
16
31
  end
data/lib/Models/Review.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  $lib = File.expand_path('../', File.dirname(__FILE__))
2
2
 
3
3
  class Review
4
- attr_accessor :platform, :id, :userName, :rating, :title, :body, :createdDateTimestamp, :url, :appVersion, :territory
5
- def initialize(platform, id, userName, rating, title, body, createdDateTimestamp, url, appVersion, territory)
4
+ attr_accessor :platform, :id, :userName, :rating, :title, :body, :createdDateTimestamp, :url, :appVersion, :territory, :tempData
5
+ def initialize(platform, id, userName, rating, title, body, createdDateTimestamp, url, appVersion, territory, tempData)
6
6
  @platform = platform # 來源平台 android or apple
7
7
  @id = id # review id
8
8
  @userName = userName # reviewer
@@ -13,5 +13,6 @@ class Review
13
13
  @url = url # 前往 review 的連結 (apple 不提供後台指定到某個 review 的連結)
14
14
  @appVersion = appVersion # app 版本號
15
15
  @territory = territory # apple: 地區(TWN/JPN...), android: 語系(zh-tw/en...)
16
+ @tempData = tempData # 程式內部傳遞使用
16
17
  end
17
18
  end
@@ -20,7 +20,15 @@ class ReviewFetcher
20
20
 
21
21
  def processReviews(reviews, platform)
22
22
  processors.each do |processor|
23
- reviews = processor.processReviews(reviews, platform)
23
+ begin
24
+ reviews = processor.processReviews(reviews, platform)
25
+ rescue => e
26
+ errorMessage = "# Processor Error"
27
+ errorMessage += "#Error Message: #{e.message}\n"
28
+ errorMessage += "#Error Class: #{e.class}\n"
29
+ errorMessage += "#Backtrace Start#\n#{e.backtrace.join("\n")}\n#Backtrace End#\n"
30
+ logger.logError(errorMessage)
31
+ end
24
32
  end
25
33
  end
26
34
 
@@ -0,0 +1,133 @@
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 AsanaProcessor < Processor
10
+
11
+ attr_accessor :keywordsInclude, :ratingsInclude, :territoriesInclude, :logger, :timeZoneOffset, :token, :projectID, :sectionName, :taskTitleTemplate, :taskBodyTemplate, :asanaAPIURL
12
+
13
+ def initialize(config, configFilePath, baseExecutePath)
14
+ @config = config
15
+ @configFilePath = configFilePath
16
+ @baseExecutePath = baseExecutePath
17
+ @logger = ZLogger.new(baseExecutePath)
18
+
19
+ @asanaAPIURL = "https://app.asana.com/api/1.0"
20
+ @token = Helper.unwrapRequiredParameter(config, "asanaToken")
21
+ @projectID = Helper.unwrapRequiredParameter(config, "asanaProjectID")
22
+ @taskTitleTemplate = Helper.unwrapRequiredParameter(config, "asanaTaskTitleTemplate")
23
+ @taskBodyTemplate = Helper.unwrapRequiredParameter(config, "asanaTaskBodyTemplate")
24
+ @timeZoneOffset = Helper.unwrapRequiredParameter(config, "asanaTimeZoneOffset")
25
+ @sectionName = nil
26
+ if !config["asanaSectionName"].nil? && config["asanaSectionName"] != ""
27
+ @sectionName = config["asanaSectionName"].strip
28
+ end
29
+
30
+ @keywordsInclude = []
31
+ if !config["keywordsInclude"].nil?
32
+ @keywordsInclude = config["keywordsInclude"]
33
+ end
34
+
35
+ @ratingsInclude = []
36
+ if !config["ratingsInclude"].nil?
37
+ @ratingsInclude = config["ratingsInclude"]
38
+ end
39
+
40
+ @territoriesInclude = []
41
+ if !config["territoriesInclude"].nil?
42
+ @territoriesInclude = config["territoriesInclude"]
43
+ end
44
+
45
+ puts "[AsanaProcessor] Init Success."
46
+ end
47
+
48
+ def processReviews(reviews, platform)
49
+ if reviews.length < 1
50
+ return reviews
51
+ end
52
+
53
+ sectionID = findSectionIDFromSectionName(sectionName)
54
+
55
+ filterReviews = reviews
56
+
57
+ if ratingsInclude.length > 0
58
+ filterReviews = filterReviews.select{ |review| ratingsInclude.map{ |rating| rating.to_i }.include? review.rating }
59
+ end
60
+
61
+ if territoriesInclude.length > 0
62
+ filterReviews = filterReviews.select{ |review| territoriesInclude.map{ |territory| territory.upcase }.include? review.territory.upcase }
63
+ end
64
+
65
+ if keywordsInclude.length > 0
66
+ keywordsInclude.select{ |keywordsInclude| keywordsInclude != "" }.each do |keywordInclude|
67
+ filterReviews = filterReviews.select{ |review| review.body.include? keywordInclude }
68
+ end
69
+ end
70
+
71
+ filterReviews.each do |review|
72
+ title = renderReview(taskTitleTemplate, review, timeZoneOffset)
73
+ body = renderReview(taskBodyTemplate, review, timeZoneOffset)
74
+
75
+ requestTaskData = {
76
+ "name": title,
77
+ "notes": body,
78
+ "projects": [projectID.to_s]
79
+ }
80
+
81
+ if !review.createdDateTimestamp.nil?
82
+ requestTaskData['due_at'] = Time.at(review.createdDateTimestamp).iso8601
83
+ end
84
+
85
+ taskData = asanaAPI("/tasks", "POST", requestTaskData)
86
+ taskData = taskData["data"]
87
+
88
+ review.tempData["asanaTaskGID"] = taskData["gid"]
89
+
90
+ if !sectionID.nil? && !taskData.nil?
91
+ asanaAPI("/sections/#{sectionID}/addTask", "POST", {"task": taskData["gid"]})
92
+ end
93
+
94
+ puts "[AsanaProcessor] Insert Review #{title} as a task to asana project."
95
+ end
96
+
97
+ return reviews
98
+ end
99
+
100
+ private
101
+ def findSectionIDFromSectionName(sectionName)
102
+ if !sectionName.nil?
103
+ sections = asanaAPI("/projects/#{projectID}/sections")["data"]
104
+ section = sections.find{ |section| section["name"].strip == sectionName }
105
+ if !section.nil?
106
+ return section["gid"]
107
+ end
108
+ end
109
+
110
+ return nil
111
+ end
112
+
113
+ private
114
+ def asanaAPI(path, method = "GET", data = nil)
115
+ uri = URI(asanaAPIURL+path)
116
+ https = Net::HTTP.new(uri.host, uri.port)
117
+ https.use_ssl = true
118
+
119
+ request = Net::HTTP::Get.new(uri)
120
+ if method.upcase == "POST"
121
+ request = Net::HTTP::Post.new(uri)
122
+ if !data.nil?
123
+ request['Content-Type'] = 'application/json'
124
+ request.body = JSON.dump({"data": data})
125
+ end
126
+ end
127
+
128
+ request['Authorization'] = "Bearer #{token}";
129
+
130
+ response = https.request(request).read_body
131
+ result = JSON.parse(response)
132
+ end
133
+ end
@@ -105,17 +105,7 @@ class GoogleSheetProcessor < Processor
105
105
  sortedFilterReviews.each do |review|
106
106
  cols = []
107
107
  formatValues.each do |formatValue|
108
- formatValue = formatValue.gsub("%TITLE%", review.title || "")
109
- formatValue = formatValue.gsub("%BODY%", review.body || "")
110
- formatValue = formatValue.gsub("%RATING%", review.rating.nil? ? "" :review.rating.to_s)
111
- formatValue = formatValue.gsub("%PLATFORM%", review.platform || "")
112
- formatValue = formatValue.gsub("%ID%", review.id || "")
113
- formatValue = formatValue.gsub("%USERNAME%", review.userName || "")
114
- formatValue = formatValue.gsub("%URL%", review.url || "")
115
- formatValue = formatValue.gsub("%TERRITORY%", review.territory || "")
116
- formatValue = formatValue.gsub("%APPVERSION%", review.appVersion || "")
117
- formatValue = formatValue.gsub("%CREATEDDATE%", review.createdDateTimestamp.nil? ? "" : Time.at(review.createdDateTimestamp).getlocal(timeZoneOffset).to_s)
118
-
108
+ formatValue = renderReview(formatValue, review, timeZoneOffset)
119
109
  cols.append(formatValue)
120
110
  end
121
111
  values.append(cols)
@@ -0,0 +1,159 @@
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 SlackAndAsanaConnector < Processor
10
+
11
+ attr_accessor :logger, :slackBotToken, :asanaToken, :projectID, :asanaAPIURL
12
+
13
+ def initialize(config, configFilePath, baseExecutePath)
14
+ @config = config
15
+ @configFilePath = configFilePath
16
+ @baseExecutePath = baseExecutePath
17
+ @logger = ZLogger.new(baseExecutePath)
18
+
19
+ @asanaAPIURL = "https://app.asana.com/api/1.0"
20
+ @asanaToken = Helper.unwrapRequiredParameter(config, "asanaToken")
21
+ @slackBotToken = Helper.unwrapRequiredParameter(config, "slackBotToken")
22
+
23
+ puts "[SlackAndAsanaConnector] Init Success."
24
+ end
25
+
26
+ def processReviews(reviews, platform)
27
+ if reviews.length < 1
28
+ return reviews
29
+ end
30
+
31
+ pendingReviews = reviews.dup
32
+
33
+ loop do
34
+ review = pendingReviews.shift
35
+
36
+ result = retrieveSlackMessage(review)
37
+ if !result["ok"]
38
+ if result["error"] == "ratelimited"
39
+ puts "[SlackAndAsanaConnector] Reached Rate Limited, sleep 1 sec..."
40
+ sleep(1)
41
+ pendingReviews.insert(0, review)
42
+ end
43
+ else
44
+ sendAsanaCommentMessage(review, "ref: #{result["permalink"]}")
45
+ end
46
+
47
+ puts "[SlackAndAsanaConnector] Connect Slack Message to Asana Task, rest: #{pendingReviews.length}"
48
+ break if pendingReviews.length < 1
49
+ end
50
+
51
+ pendingReviews = reviews.dup
52
+
53
+ loop do
54
+ review = pendingReviews.shift
55
+ asanaTaskURL = retrieveAsanaTaskURL(review)
56
+ if !asanaTaskURL.nil?
57
+ result = sendSlackCommnetMessage(review, "<#{asanaTaskURL}| Go To *Asana Task*>")
58
+ if !result["ok"]
59
+ if result["error"] == "ratelimited"
60
+ puts "[SlackAndAsanaConnector] Reached Rate Limited, sleep 1 sec..."
61
+ sleep(1)
62
+ pendingReviews.insert(0, review)
63
+ end
64
+ end
65
+ end
66
+
67
+ puts "[SlackAndAsanaConnector] Connect Asana Task to Slack Message, rest: #{pendingReviews.length}"
68
+ break if pendingReviews.length < 1
69
+ end
70
+
71
+ return reviews
72
+ end
73
+
74
+ private
75
+ def retrieveSlackMessage(review)
76
+ uri = URI("https://slack.com/api/chat.getPermalink?channel=#{review.tempData["slackChannelID"]}&message_ts=#{review.tempData["slackTS"]}")
77
+ headers = {'Content-Type': 'application/json; charset=utf-8', 'Authorization': "Bearer #{slackBotToken}"}
78
+
79
+ http = Net::HTTP.new(uri.host, uri.port)
80
+ http.use_ssl = true
81
+ req = Net::HTTP::Get.new(uri.request_uri, headers)
82
+ res = http.request(req)
83
+
84
+ result = JSON.parse(res.body)
85
+ return result
86
+ end
87
+
88
+ private
89
+ def sendSlackCommnetMessage(review, message)
90
+ payload = Payload.new()
91
+ payload.text = message
92
+ payload.channel = review.tempData["slackChannelID"]
93
+ payload.thread_ts = review.tempData["slackTS"]
94
+ payload.unfurl_links = true
95
+ payload.unfurl_media = true
96
+ uri = URI("https://slack.com/api/chat.postMessage")
97
+ headers = {'Content-Type': 'application/json; charset=utf-8', 'Authorization': "Bearer #{slackBotToken}"}
98
+
99
+ http = Net::HTTP.new(uri.host, uri.port)
100
+ http.use_ssl = true
101
+ req = Net::HTTP::Post.new(uri.request_uri, headers)
102
+ req.body = payload.to_json
103
+ res = http.request(req)
104
+
105
+ result = JSON.parse(res.body)
106
+ return result
107
+ end
108
+
109
+
110
+ private
111
+ def retrieveAsanaTaskURL(review)
112
+ if review.tempData["asanaTaskGID"].nil? || review.tempData["asanaTaskGID"] == ""
113
+ return nil
114
+ end
115
+
116
+ return "https://app.asana.com/0/0/#{review.tempData["asanaTaskGID"]}/f"
117
+ end
118
+
119
+ private
120
+ def sendAsanaCommentMessage(review, message)
121
+ if review.tempData["asanaTaskGID"].nil? || review.tempData["asanaTaskGID"] == ""
122
+ return nil
123
+ end
124
+
125
+ path = "/tasks/#{review.tempData["asanaTaskGID"]}/stories"
126
+ uri = URI(asanaAPIURL+path)
127
+ https = Net::HTTP.new(uri.host, uri.port)
128
+ https.use_ssl = true
129
+
130
+ request = Net::HTTP::Post.new(uri)
131
+ request['Content-Type'] = 'application/json'
132
+ request.body = JSON.dump({"data": {"text": message}})
133
+
134
+ request['Authorization'] = "Bearer #{asanaToken}"
135
+
136
+ response = https.request(request).read_body
137
+
138
+ return result = JSON.parse(response)
139
+ end
140
+
141
+ private
142
+ class Payload
143
+ attr_accessor :channel, :thread_ts, :text, :unfurl_links, :unfurl_media
144
+
145
+ def as_json(options={})
146
+ {
147
+ channel: @channel,
148
+ thread_ts: @thread_ts,
149
+ text: @text,
150
+ unfurl_links: @unfurl_links,
151
+ unfurl_media: @unfurl_media
152
+ }
153
+ end
154
+
155
+ def to_json(*options)
156
+ as_json(*options).to_json(*options)
157
+ end
158
+ end
159
+ end
@@ -42,7 +42,7 @@ class SlackProcessor < Processor
42
42
  return reviews
43
43
  end
44
44
 
45
- pendingPayloads = []
45
+ pendingRequests = []
46
46
 
47
47
  # Slack Message Limit: posting one message per second per channel
48
48
  reviews.each_slice(attachmentGroupByNumber) do |reviewGroup|
@@ -71,12 +71,16 @@ class SlackProcessor < Processor
71
71
  payload.attachments.append(attachment)
72
72
  end
73
73
 
74
- pendingPayloads.append(payload)
74
+ pendingRequests.append({"payload" => payload, "reviewGroup" => reviewGroup})
75
75
  end
76
+
77
+ resultReviews = []
76
78
 
77
79
  loop do
78
- payload = pendingPayloads.shift
79
-
80
+ pendingRequest = pendingRequests.shift
81
+ payload = pendingRequest["payload"]
82
+ reviewGroup = pendingRequest["reviewGroup"]
83
+
80
84
  result = request(payload)
81
85
  if !result[:ok]
82
86
  logger.logError(payload)
@@ -84,12 +88,17 @@ class SlackProcessor < Processor
84
88
  if result[:message] == "ratelimited"
85
89
  puts "[SlackProcessor] Reached Rate Limited, sleep 1 sec..."
86
90
  sleep(1)
87
- pendingPayloads.insert(0, payload)
91
+ pendingRequests.insert(0, pendingRequest)
92
+ end
93
+ elsif !result[:ts].nil?
94
+ reviewGroup.each do |review|
95
+ review.tempData["slackTS"] = result[:ts]
96
+ review.tempData["slackChannelID"] = targetChannel
88
97
  end
89
98
  end
90
99
 
91
- puts "[SlackProcessor] Send new Review messages, rest: #{pendingPayloads.length}"
92
- break if pendingPayloads.length < 1
100
+ puts "[SlackProcessor] Send new Review messages, rest: #{pendingRequests.length}"
101
+ break if pendingRequests.length < 1
93
102
  end
94
103
 
95
104
  return reviews
@@ -140,10 +149,10 @@ class SlackProcessor < Processor
140
149
  res = http.request(req)
141
150
 
142
151
  if isInCommingWebHook
143
- return {"ok":res.body == "ok", "message":nil}
152
+ return {"ok":res.body == "ok", "message":nil, "ts": result['ts']}
144
153
  else
145
154
  result = JSON.parse(res.body)
146
- return {"ok":result["ok"] == true, "message":result['error']}
155
+ return {"ok":result["ok"] == true, "message":result['error'], "ts": result['ts']}
147
156
  end
148
157
 
149
158
  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.3.6
4
+ version: 1.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - ZhgChgLi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-19 00:00:00.000000000 Z
11
+ date: 2023-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http
@@ -59,10 +59,12 @@ files:
59
59
  - lib/Models/Review.rb
60
60
  - lib/Models/ReviewFetcher.rb
61
61
  - lib/Models/Version.rb
62
+ - lib/Processors/AsanaProcessor.rb
62
63
  - lib/Processors/FilterProcessor.rb
63
64
  - lib/Processors/GoogleSheetProcessor.rb
64
65
  - lib/Processors/GoogleTranslateProcessor.rb
65
66
  - lib/Processors/ProcessorTemplate.rb
67
+ - lib/Processors/SlackAndAsanaConnector.rb
66
68
  - lib/Processors/SlackProcessor.rb
67
69
  - lib/ZLogger.rb
68
70
  homepage: https://github.com/ZhgChgLi/ZReviewTender