fastlane-plugin-slack_bot 0.1.2 → 0.4.1

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: 7340f09d68383428d22988f1cee11d6a175bfdb3d4443af48dc070a2a366dee4
4
- data.tar.gz: ef98d678fac65cb75943ba53daee4e5da38b9c21d1bda396b790b4d0736a9a93
3
+ metadata.gz: 9e0d95cdc34c99e1608ec3d1e30ff2f0b538516bd370fd166bc09c97d61e5781
4
+ data.tar.gz: cc8eb032bfc0b3e3022a2a390981120cdf9245812ef46c7fbe9ff0dd2808a0f5
5
5
  SHA512:
6
- metadata.gz: b4f4e61b04ed004d81436de2202cb66df05420e34d94583e39c145048fba2e00bd0c60392fa38b9a8163bb7c1e1d8c891bcf218674aced8c82da46f625598c0b
7
- data.tar.gz: 36fbd80160b344bc8d53e5d6a346baf77de81159f1ec9cc2d116173ed8505d7b8f6737d0133651277eef0c2a4fafec5c1dcf47cf686a697c8418ac41e05b9cab
6
+ metadata.gz: 9d76ae4594ce67f876db6d0fe4673503f05088e64cad0bf6faf5bd5f0fcaaa5d972f2c146454aa425e6a1de980436297533e5881eb8438547e78878783dc6706
7
+ data.tar.gz: d0abe8adad2c616a9feb9521bf29a2cda9f49cbab0f4895379bbb97fd2ed2791d354f9b1bdafdb59430e0773ecf0baa9888d0aa0ecefd6e448974f866dda0556
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Manish Rathi <m.rathi@catawiki.nl>
3
+ Copyright (c) 2021 Manish Rathi
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,15 +1,34 @@
1
1
  ## Fastlane `slack_bot` plugin
2
2
 
3
3
  [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-slack_bot)
4
-
5
- ## About slack_bot
6
-
7
- A fastlane plugin to post slack message using bot api token. 🚀
8
- Note: `Fastlane` comes with `slack` plugin by default, which uses slack webhook url, which can't send direct message & other limitations.
4
+ ![![License]](https://img.shields.io/badge/license-MIT-green.svg?style=flat)
5
+ [![Gem Version](https://badge.fury.io/rb/fastlane-plugin-slack_bot.svg)](https://badge.fury.io/rb/fastlane-plugin-slack_bot)
6
+ ![![RubyGem Download Badge]](https://ruby-gem-downloads-badge.herokuapp.com/fastlane-plugin-slack_bot?type=total)
7
+ [![Twitter: @manish](https://img.shields.io/badge/contact-@manish-blue.svg?style=flat)](https://twitter.com/manish_rathi_)
8
+
9
+ A fastlane plugin to customize your automation workflow(s) with a **Slack Bot** 🤖 using the [Slack APIs](https://api.slack.com/)
10
+
11
+ - [About](#about)
12
+ - [Getting Started](#getting-started)
13
+ - [Features](#features)
14
+ - [Post a message](#examples-post-a-message) examples
15
+ - [Upload a file](#examples-upload-a-message) examples
16
+ - [About Fastlane](#about-fastlane)
17
+
18
+ ## About
19
+
20
+ A fastlane plugin to post slack message and much more using Slack bot api token. 🚀\
21
+ **Note:** `Fastlane` comes with built-in `slack` action by default, which uses slack webhook url and have webhook limitations.
22
+ i.e Listing couple of slack **webhook url** limitations:
23
+ - can't post a direct message to a slack user.
24
+ - can’t post a message inside a slack thread.
25
+ - can’t update a posted slack message.
26
+ - can’t list and upload a file inside a slack channel.
27
+ - much more, compare to a **Slack Bot** 🤖 using the [Slack APIs](https://api.slack.com/)
9
28
 
10
29
  ## Getting Started
11
30
 
12
- 1. Generate `Slack token` for `Fastlane` bot
31
+ 1. [Generate `Slack token` for `Fastlane` bot](https://slack.com/intl/en-nl/help/articles/115005265703-Create-a-bot-for-your-workspace)
13
32
  - From your Slack organization page, go to `Manage` -> `Custom Integrations`
14
33
  - Open `Bots`
15
34
  - Add Configuration
@@ -23,43 +42,209 @@ fastlane add_plugin slack_bot
23
42
  ```
24
43
  If you are using fastlane using Gemfile in your project, add it to your project by running:
25
44
  ```bash
26
- bundle exec fastlane add_plugin slack_bot
45
+ bundle exec fastlane add_plugin slack_bot
27
46
  ```
28
47
 
29
- 3. Add `slack_bot` to your lane in `Fastfile` whenever you want to post a slack message
48
+ 3. Use `slack_bot` features inside your lane in `Fastfile` whenever you want.
49
+
50
+ ## Features
51
+ Using this `slack_bot` plugin, you can:
52
+
53
+ - Post a message using [chat.postMessage](https://api.slack.com/methods/chat.postMessage) Slack API
54
+ - [x] Post a message to a _public_ channel
55
+ - [x] Post a message to a _private_ channel
56
+ - [x] Post a message to a _slack user_ (DM)
57
+ - [x] Post a message inside a _slack thread_ 🧵
58
+ - [x] Post a message with _custom Bot username and icon_
59
+
60
+ - Update a message using [chat.update](https://api.slack.com/methods/chat.update) Slack API
61
+ - [x] update a message in a channel
62
+
63
+ - List of files in a channel using [files.list](https://api.slack.com/methods/files.list) Slack API
64
+ - [x] A list of files in a channel, It can be filtered and sliced in various ways.
65
+
66
+ - Upload a file using [files.upload](https://api.slack.com/methods/files.upload) Slack API
67
+ - [x] Upload a file to a _public_ channel
68
+ - [x] Upload a file to a _private_ channel
69
+ - [x] Upload a file to a _slack user_ (DM)
70
+ - [x] Upload a file inside a _slack thread_ 🧵
71
+ - [x] Upload a file with _multiple channels/users_
72
+
73
+
74
+ ## Examples (Post a message)
75
+
76
+ Let’s post a message to the default slack bot channel.
77
+
78
+ ```ruby
79
+ # share on Slack
80
+ post_to_slack(message: "App successfully released!")
81
+ ```
82
+
83
+ Let’s post a direct message to a slack user that unit tests CI has been failed.
84
+
85
+ ```ruby
86
+ # share on Slack
87
+ post_to_slack(
88
+ message: "CI: Your unit tests on #{ENV['CI_COMMIT_REF_NAME']} failed",
89
+ channel: "@SlackUsername" # This can be Slack userID, instead of username i.e @UXXXXX
90
+ )
91
+ ```
30
92
 
31
- In the following example lets send slack message to `#ios-team` channel for test-flight build.
93
+ Let’s post a slack message to the `#ios-team` channel about the new test-flight build.
32
94
 
33
95
  ```ruby
34
96
  lane :beta do
35
97
  gym # Build the app and create .ipa file
36
98
  pilot # Upload build to TestFlight
37
-
99
+
38
100
  version_number = get_version_number # Get project version
39
101
  build_number = get_build_number # Get build number
40
102
  beta_release_name = "#{version_number}-#{build_number}-beta-release"
41
-
103
+
42
104
  # share on Slack
43
105
  post_to_slack(
44
- api_token: "xyz", # Preferably configure as ENV['SLACK_API_TOKEN']
45
106
  message: "Hi team, we have a new test-flight beta build: #{beta_release_name}",
46
107
  channel: "#ios-team"
47
108
  )
48
109
  end
49
110
  ```
50
111
 
51
- ## Issues and Feedback
112
+ Let’s post a slack message with custom payload.
113
+
114
+ ```ruby
115
+ # share on Slack
116
+ post_to_slack(
117
+ api_token: "xyz", # Preferably configure as ENV['SLACK_API_TOKEN']
118
+ message: "App successfully released!",
119
+ channel: "#channel", # Optional, by default will post to the default channel configured for the Slack Bot.
120
+ success: true, # Optional, defaults to true.
121
+ payload: { # Optional, lets you specify any number of your own Slack attachments.
122
+ "Build Date" => Time.new.to_s,
123
+ "Built by" => "Jenkins",
124
+ },
125
+ default_payloads: [:git_branch, :git_author], # Optional, lets you specify an allowlist of default payloads to include. Pass an empty array to suppress all the default payloads.
126
+ # Don't add this key, or pass nil, if you want all the default payloads. The available default payloads are: `lane`, `test_result`, `git_branch`, `git_author`, `last_git_commit`, `last_git_commit_hash`.
127
+ attachment_properties: { # Optional, lets you specify any other properties available for attachments in the slack API (see https://api.slack.com/docs/attachments).
128
+ # This hash is deep merged with the existing properties set using the other properties above. This allows your own fields properties to be appended to the existing fields that were created using the `payload` property for instance.
129
+ thumb_url: "http://example.com/path/to/thumb.png",
130
+ fields: [{
131
+ title: "My Field",
132
+ value: "My Value",
133
+ short: true
134
+ }]
135
+ }
136
+ )
137
+ ```
138
+
139
+ Let’s post a slack message inside a slack thread 🧵
140
+
141
+ ```ruby
142
+ lane :release do
143
+ # Start the release with slack release thread
144
+ release_thread = post_to_slack(
145
+ message: "Good morning team, CI has started the AppStore release. You can find more information inside this thread 🧵",
146
+ channel: "#ios-team"
147
+ )
148
+
149
+ # Important: Save this slack thread timestamp for futher slack messages
150
+ release_thread_ts = release_thread[:json]["ts"]
151
+
152
+ gym # Build the app and create .ipa file
153
+
154
+ # Post an update in release thread
155
+ post_to_slack(
156
+ message: "App has been build successfully! 💪",
157
+ channel: "#ios-team",
158
+ thread_ts: release_thread_ts
159
+ )
160
+
161
+ deliver # Upload build to AppStore
162
+
163
+ # Post an update in release thread
164
+ post_to_slack(
165
+ message: "App has been uploaded to the AppStore and submitted for Apple's review! 🚀",
166
+ channel: "#ios-team",
167
+ thread_ts: release_thread_ts
168
+ )
169
+ end
170
+ ```
171
+
172
+ Let’s post a message with custom slack bot username and icon
52
173
 
53
- For any other issues and feedback about this plugin, please submit it to this repository.
174
+ ```ruby
175
+ # share on Slack
176
+ post_to_slack(
177
+ message: "App successfully released!",
178
+ username: "Release Bot", # Overrides the bot's image
179
+ icon_url: "https://fastlane.tools/assets/img/fastlane_icon.png" # Overrides the bot's icon
180
+ )
181
+ ```
54
182
 
55
- ## Troubleshooting
183
+ ## Examples (Upload a file)
56
184
 
57
- If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
185
+ Let’s Upload a file to a slack channel that main branch unit tests has been failed, see scan logs.
58
186
 
59
- ## Using _fastlane_ Plugins
187
+ ```ruby
188
+ # File upload on Slack
189
+ file_upload_to_slack(
190
+ initial_comment: "CI: main-branch unit tests failed",
191
+ file_path: "scan.log",
192
+ channels: "#ios-team" # Comma-separated list of slack #channel names where the file will be shared
193
+ )
194
+ ```
195
+
196
+ Let’s Upload a file to a slack user that your branch unit tests has been failed, see scan logs.
197
+
198
+ ```ruby
199
+ # File upload on Slack
200
+ file_upload_to_slack(
201
+ initial_comment: "CI: Your unit tests on #{ENV['CI_COMMIT_REF_NAME']} failed",
202
+ file_path: "scan.log",
203
+ channels: "@SlackUsername" # This can be Slack userID, instead of username i.e @UXXXXX
204
+ )
205
+ ```
60
206
 
61
- For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
207
+ Let’s Upload a file inside a slack thread 🧵
208
+
209
+ ```ruby
210
+ lane :release do
211
+ # Start the release with slack release thread
212
+ release_thread = post_to_slack(
213
+ message: "Good morning team, CI has started the AppStore release. You can find more information inside this thread 🧵",
214
+ channel: "#ios-team"
215
+ )
216
+
217
+ # Important: Save this slack thread timestamp for futher slack messages
218
+ release_thread_ts = release_thread[:json]["ts"]
219
+
220
+ gym # Build the app and create .ipa file
221
+
222
+ # Post an update in release thread
223
+ post_to_slack(
224
+ message: "App has been build successfully! 💪",
225
+ channel: "#ios-team",
226
+ thread_ts: release_thread_ts
227
+ )
228
+
229
+ deliver # Upload build to AppStore
230
+
231
+ # Post an update in release thread
232
+ post_to_slack(
233
+ message: "App has been uploaded to the AppStore and submitted for Apple's review! 🚀",
234
+ channel: "#ios-team",
235
+ thread_ts: release_thread_ts
236
+ )
237
+
238
+ # Spaceship logs file upload on Slack
239
+ file_upload_to_slack(
240
+ initial_comment: "Deliver:: Spaceship logs",
241
+ file_path: "spaceship.log",
242
+ channels: "#ios-team",
243
+ thread_ts: release_thread_ts
244
+ )
245
+ end
246
+ ```
62
247
 
63
- ## About _fastlane_
248
+ ## About Fastlane
64
249
 
65
250
  _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
@@ -0,0 +1,176 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/slack_bot_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ module SharedValues
7
+ FILE_UPLOAD_TO_SLACK_RESULT = :FILE_UPLOAD_TO_SLACK_RESULT
8
+ end
9
+
10
+ class FileUploadToSlackAction < Action
11
+ def self.run(params)
12
+ file_path = params[:file_path]
13
+
14
+ if params[:file_name].to_s.empty?
15
+ file_name = File.basename(file_path, ".*") # if file_path = "/path/file_name.jpeg" then will return "file_name"
16
+ else
17
+ file_name = params[:file_name]
18
+ end
19
+
20
+ if params[:file_type].to_s.empty?
21
+ file_type = File.extname(file_path)[1..-1] # if file_path = "/path/file_name.jpeg" then will return "jpeg"
22
+ else
23
+ file_type = params[:file_type]
24
+ end
25
+
26
+ begin
27
+ require 'faraday'
28
+
29
+ api_url = "https://slack.com/api/files.upload"
30
+ conn = Faraday.new(url: api_url) do |faraday|
31
+ faraday.request :multipart
32
+ faraday.request :url_encoded
33
+ faraday.adapter :net_http
34
+ end
35
+
36
+ payload = {
37
+ channels: params[:channels],
38
+ file: Faraday::FilePart.new(file_path, file_type),
39
+ filename: file_name,
40
+ filetype: file_type
41
+ }
42
+
43
+ payload[:title] = params[:title] unless params[:title].nil?
44
+ payload[:initial_comment] = params[:initial_comment] unless params[:initial_comment].nil?
45
+ payload[:thread_ts] = params[:thread_ts] unless params[:thread_ts].nil?
46
+
47
+ response = conn.post do |req|
48
+ req.headers['Authorization'] = "Bearer #{params[:api_token]}"
49
+ req.body = payload
50
+ end
51
+
52
+ result = self.formatted_result(response)
53
+ rescue => exception
54
+ UI.error("Exception: #{exception}")
55
+ return nil
56
+ else
57
+ UI.success("Successfully uploaded file to Slack! 🚀")
58
+ Actions.lane_context[SharedValues::FILE_UPLOAD_TO_SLACK_RESULT] = result
59
+ return result
60
+ end
61
+ end
62
+
63
+ def self.formatted_result(response)
64
+ result = {
65
+ status: response[:status],
66
+ body: response.body || "",
67
+ json: self.parse_json(response.body) || {}
68
+ }
69
+ end
70
+
71
+ def self.parse_json(value)
72
+ require 'json'
73
+
74
+ JSON.parse(value)
75
+ rescue JSON::ParserError
76
+ nil
77
+ end
78
+
79
+ #####################################################
80
+ # @!group Documentation
81
+ #####################################################
82
+
83
+ def self.description
84
+ "Upload a file to slack channel"
85
+ end
86
+
87
+ def self.details
88
+ "Upload a file to slack channel or DM to a slack user"
89
+ end
90
+
91
+ def self.available_options
92
+ [
93
+ FastlaneCore::ConfigItem.new(key: :api_token,
94
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_BOT_TOKEN",
95
+ description: "Slack bot Token",
96
+ sensitive: true,
97
+ code_gen_sensitive: true,
98
+ is_string: true,
99
+ default_value: ENV["SLACK_API_TOKEN"],
100
+ default_value_dynamic: true,
101
+ optional: false),
102
+ FastlaneCore::ConfigItem.new(key: :channels,
103
+ env_name: "FL_FETCH_FILES_SLACK_CHANNELS",
104
+ description: "Comma-separated list of slack #channel names where the file will be shared",
105
+ is_string: true,
106
+ optional: false),
107
+ FastlaneCore::ConfigItem.new(key: :file_path,
108
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_FILE_PATH",
109
+ description: "relative file path which will upload to slack",
110
+ is_string: true,
111
+ optional: false),
112
+ FastlaneCore::ConfigItem.new(key: :file_name,
113
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_FILE_NAME",
114
+ description: "This is optional filename of the file",
115
+ is_string: true,
116
+ optional: true),
117
+ FastlaneCore::ConfigItem.new(key: :file_type,
118
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_FILE_TYPE",
119
+ description: "This is optional filetype of the file",
120
+ is_string: true,
121
+ optional: true),
122
+ FastlaneCore::ConfigItem.new(key: :title,
123
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_TITLE",
124
+ description: "This is optional Title of file",
125
+ is_string: true,
126
+ optional: true),
127
+ FastlaneCore::ConfigItem.new(key: :initial_comment,
128
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_INITIAL_COMMENT",
129
+ description: "This is optional message text introducing the file",
130
+ is_string: true,
131
+ optional: true),
132
+ FastlaneCore::ConfigItem.new(key: :thread_ts,
133
+ env_name: "FL_FILE_UPLOAD_TO_SLACK_THREAD_TS",
134
+ description: "Provide another message's ts value to make this message a reply",
135
+ is_string: true,
136
+ optional: true)
137
+ ]
138
+ end
139
+
140
+ def self.authors
141
+ ["crazymanish"]
142
+ end
143
+
144
+ def self.example_code
145
+ [
146
+ 'file_upload_to_slack(
147
+ channels: "slack_channel_name",
148
+ file_path: "fastlane/test.png"
149
+ )',
150
+ 'file_upload_to_slack(
151
+ title: "This is test title",
152
+ channels: "slack_channel_name1, slack_channel_name2",
153
+ file_path: "fastlane/report.xml"
154
+ )',
155
+ 'file_upload_to_slack(
156
+ title: "This is test title",
157
+ initial_comment: "This is test initial comment",
158
+ channels: "slack_channel_name",
159
+ file_path: "fastlane/screenshots.zip"
160
+ )',
161
+ 'file_upload_to_slack(
162
+ title: "This is test title", # Optional, uploading file title
163
+ initial_comment: "This is test initial comment", # Optional, uploading file initial comment
164
+ channels: "slack_channel_name",
165
+ file_path: "fastlane/screenshots.zip",
166
+ thread_ts: thread_ts # Optional, Provide parent slack message `ts` value to upload this file as a reply.
167
+ )'
168
+ ]
169
+ end
170
+
171
+ def self.is_supported?(platform)
172
+ true
173
+ end
174
+ end
175
+ end
176
+ end
@@ -3,37 +3,73 @@ require_relative '../helper/slack_bot_helper'
3
3
 
4
4
  module Fastlane
5
5
  module Actions
6
+ module SharedValues
7
+ POST_TO_SLACK_RESULT = :POST_TO_SLACK_RESULT
8
+ end
9
+
6
10
  class PostToSlackAction < Action
7
11
  def self.run(options)
8
12
  require 'slack-notifier'
9
13
 
10
14
  options[:message] = (options[:message].to_s || '').gsub('\n', "\n")
11
15
  options[:message] = Slack::Notifier::Util::LinkFormatter.format(options[:message])
12
-
13
16
  options[:pretext] = options[:pretext].gsub('\n', "\n") unless options[:pretext].nil?
14
17
 
15
18
  if options[:channel].to_s.length > 0
16
19
  slack_channel = options[:channel]
17
- slack_channel = ('#' + options[:channel]) unless ['#', '@'].include?(slack_channel[0]) # send message to channel by default
20
+ slack_channel = ('#' + options[:channel]) unless ['#', 'C', '@'].include?(slack_channel[0]) # Add prefix(#) by default, if needed
18
21
  end
19
22
 
20
23
  slack_attachment = SlackAction.generate_slack_attachments(options)
24
+ bot_username = options[:username]
25
+ bot_icon_url = options[:icon_url]
21
26
 
22
27
  begin
23
28
  require 'excon'
24
29
 
25
30
  api_url = "https://slack.com/api/chat.postMessage"
26
- headers = { "Content-Type": "application/json", "Authorization": "Bearer #{options[:api_token]}" }
27
- payload = { channel: slack_channel, attachments: [slack_attachment] }.to_json
31
+ headers = {
32
+ "Content-Type": "application/json; charset=utf-8",
33
+ "Authorization": "Bearer #{options[:api_token]}"
34
+ }
35
+ payload = {
36
+ channel: slack_channel,
37
+ username: bot_username,
38
+ icon_url: bot_icon_url,
39
+ attachments: [slack_attachment]
40
+ }
41
+ payload[:as_user] = options[:as_user] if options[:as_user] # default is false
42
+ payload[:thread_ts] = options[:thread_ts] unless options[:thread_ts].nil?
43
+ payload = payload.to_json
28
44
 
29
- Excon.post(api_url, headers: headers, body: payload)
45
+ response = Excon.post(api_url, headers: headers, body: payload)
46
+ result = self.formatted_result(response)
30
47
  rescue => exception
31
48
  UI.error("Exception: #{exception}")
49
+ return nil
32
50
  else
33
51
  UI.success("Successfully sent Slack notification")
52
+ Actions.lane_context[SharedValues::POST_TO_SLACK_RESULT] = result
53
+ return result
34
54
  end
35
55
  end
36
56
 
57
+ def self.formatted_result(response)
58
+ result = {
59
+ status: response[:status],
60
+ body: response.body || "",
61
+ json: self.parse_json(response.body) || {}
62
+ }
63
+ end
64
+
65
+ def self.parse_json(value)
66
+ require 'json'
67
+
68
+ JSON.parse(value)
69
+ rescue JSON::ParserError
70
+ nil
71
+ end
72
+
37
73
  def self.description
38
74
  "Post a slack message"
39
75
  end
@@ -57,6 +93,24 @@ module Fastlane
57
93
  env_name: "FL_POST_TO_SLACK_CHANNEL",
58
94
  description: "#channel or @username",
59
95
  optional: true),
96
+ FastlaneCore::ConfigItem.new(key: :username,
97
+ env_name: "FL_SLACK_USERNAME",
98
+ description: "Overrides the bot's username (chat:write.customize scope required)",
99
+ default_value: "fastlane",
100
+ is_string: true,
101
+ optional: true),
102
+ FastlaneCore::ConfigItem.new(key: :icon_url,
103
+ env_name: "FL_SLACK_ICON_URL",
104
+ description: "Overrides the bot's image (chat:write.customize scope required)",
105
+ default_value: "https://fastlane.tools/assets/img/fastlane_icon.png",
106
+ is_string: true,
107
+ optional: true),
108
+ FastlaneCore::ConfigItem.new(key: :as_user,
109
+ env_name: "FL_POST_TO_SLACK_AS_USER",
110
+ description: "Pass true to post the message as the authed user. Defaults to false",
111
+ optional: true,
112
+ default_value: false,
113
+ is_string: false),
60
114
  FastlaneCore::ConfigItem.new(key: :pretext,
61
115
  env_name: "FL_POST_TO_SLACK_PRETEXT",
62
116
  description: "This is optional text that appears above the message attachment block. This supports the standard Slack markup language",
@@ -74,6 +128,7 @@ module Fastlane
74
128
  env_name: "FL_POST_TO_SLACK_DEFAULT_PAYLOADS",
75
129
  description: "Remove some of the default payloads. More information about the available payloads on GitHub",
76
130
  optional: true,
131
+ default_value: ['lane', 'test_result', 'git_branch', 'git_author', 'last_git_commit', 'last_git_commit_hash'],
77
132
  type: Array),
78
133
  FastlaneCore::ConfigItem.new(key: :attachment_properties,
79
134
  env_name: "FL_POST_TO_SLACK_ATTACHMENT_PROPERTIES",
@@ -85,7 +140,11 @@ module Fastlane
85
140
  description: "Was this successful? (true/false)",
86
141
  optional: true,
87
142
  default_value: true,
88
- is_string: false)
143
+ is_string: false),
144
+ FastlaneCore::ConfigItem.new(key: :thread_ts,
145
+ env_name: "FL_POST_TO_SLACK_THREAD_TS",
146
+ description: "Provide another message's ts value to make this message a reply",
147
+ optional: true)
89
148
  ]
90
149
  end
91
150
 
@@ -0,0 +1,149 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/slack_bot_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ module SharedValues
7
+ UPDATE_SLACK_MESSAGE_RESULT = :UPDATE_SLACK_MESSAGE_RESULT
8
+ end
9
+ class UpdateSlackMessageAction < Action
10
+ def self.run(options)
11
+ require 'slack-notifier'
12
+
13
+ options[:message] = (options[:message].to_s || '').gsub('\n', "\n")
14
+ options[:message] = Slack::Notifier::Util::LinkFormatter.format(options[:message])
15
+ options[:pretext] = options[:pretext].gsub('\n', "\n") unless options[:pretext].nil?
16
+ slack_attachment = SlackAction.generate_slack_attachments(options)
17
+
18
+ begin
19
+ require 'excon'
20
+
21
+ api_url = "https://slack.com/api/chat.update"
22
+ headers = { "Content-Type": "application/json", "Authorization": "Bearer #{options[:api_token]}" }
23
+ payload = { channel: options[:channel], attachments: [slack_attachment], ts: options[:ts] }.to_json
24
+
25
+ response = Excon.post(api_url, headers: headers, body: payload)
26
+ result = self.formatted_result(response)
27
+ rescue => exception
28
+ UI.error("Exception: #{exception}")
29
+ return nil
30
+ else
31
+ UI.success("Successfully updated the Slack message")
32
+ Actions.lane_context[SharedValues::UPDATE_SLACK_MESSAGE_RESULT] = result
33
+ return result
34
+ end
35
+ end
36
+
37
+ def self.formatted_result(response)
38
+ result = {
39
+ status: response[:status],
40
+ body: response.body || "",
41
+ json: self.parse_json(response.body) || {}
42
+ }
43
+ end
44
+
45
+ def self.parse_json(value)
46
+ require 'json'
47
+
48
+ JSON.parse(value)
49
+ rescue JSON::ParserError
50
+ nil
51
+ end
52
+
53
+ def self.description
54
+ "Update a slack message using time-stamp(ts) value"
55
+ end
56
+
57
+ def self.available_options
58
+ [
59
+ FastlaneCore::ConfigItem.new(key: :api_token,
60
+ env_name: "FL_UPDATE_SLACK_MESSAGE_BOT_TOKEN",
61
+ description: "Slack bot Token",
62
+ sensitive: true,
63
+ code_gen_sensitive: true,
64
+ is_string: true,
65
+ default_value: ENV["SLACK_API_TOKEN"],
66
+ default_value_dynamic: true,
67
+ optional: false),
68
+ FastlaneCore::ConfigItem.new(key: :ts,
69
+ env_name: "FL_UPDATE_SLACK_MESSAGE_TS",
70
+ description: "Timestamp of the message to be updated",
71
+ optional: false),
72
+ FastlaneCore::ConfigItem.new(key: :channel,
73
+ env_name: "FL_UPDATE_SLACK_MESSAGE_CHANNEL",
74
+ description: "Slack channel i.e C1234567890",
75
+ optional: false),
76
+ FastlaneCore::ConfigItem.new(key: :pretext,
77
+ env_name: "FL_UPDATE_SLACK_MESSAGE_PRETEXT",
78
+ description: "This is optional text that appears above the message attachment block. This supports the standard Slack markup language",
79
+ optional: true),
80
+ FastlaneCore::ConfigItem.new(key: :message,
81
+ env_name: "FL_UPDATE_SLACK_MESSAGE_MESSAGE",
82
+ description: "The message that should be displayed on Slack",
83
+ optional: true),
84
+ FastlaneCore::ConfigItem.new(key: :payload,
85
+ env_name: "FL_UPDATE_SLACK_MESSAGE_PAYLOAD",
86
+ description: "Add additional information to this post. payload must be a hash containing any key with any value",
87
+ default_value: {},
88
+ is_string: false),
89
+ FastlaneCore::ConfigItem.new(key: :default_payloads,
90
+ env_name: "FL_UPDATE_SLACK_MESSAGE_DEFAULT_PAYLOADS",
91
+ description: "Remove some of the default payloads. More information about the available payloads on GitHub",
92
+ optional: true,
93
+ default_value: ['lane', 'test_result', 'git_branch', 'git_author', 'last_git_commit', 'last_git_commit_hash'],
94
+ type: Array),
95
+ FastlaneCore::ConfigItem.new(key: :attachment_properties,
96
+ env_name: "FL_UPDATE_SLACK_MESSAGE_ATTACHMENT_PROPERTIES",
97
+ description: "Merge additional properties in the slack attachment, see https://api.slack.com/docs/attachments",
98
+ default_value: {},
99
+ is_string: false),
100
+ FastlaneCore::ConfigItem.new(key: :success,
101
+ env_name: "FL_UPDATE_SLACK_MESSAGE_SUCCESS",
102
+ description: "Was this successful? (true/false)",
103
+ optional: true,
104
+ default_value: true,
105
+ is_string: false)
106
+ ]
107
+ end
108
+
109
+ def self.authors
110
+ ["crazymanish"]
111
+ end
112
+
113
+ def self.example_code
114
+ [
115
+ 'update_slack_message(
116
+ ts: "1609711037.000100",
117
+ channel: "C1234567890",
118
+ message: "Update: App successfully released!"
119
+ )',
120
+ 'update_slack_message(
121
+ ts: "1609711037.000100",
122
+ channel: "C1234567890",
123
+ message: "Update: App successfully released!",
124
+ success: true, # Optional, defaults to true.
125
+ payload: { # Optional, lets you specify any number of your own Slack attachments.
126
+ "Build Date" => Time.new.to_s,
127
+ "Built by" => "Jenkins",
128
+ },
129
+ default_payloads: [:git_branch, :git_author], # Optional, lets you specify a whitelist of default payloads to include. Pass an empty array to suppress all the default payloads.
130
+ # Don\'t add this key, or pass nil, if you want all the default payloads. The available default payloads are: `lane`, `test_result`, `git_branch`, `git_author`, `last_git_commit`, `last_git_commit_hash`.
131
+ attachment_properties: { # Optional, lets you specify any other properties available for attachments in the slack API (see https://api.slack.com/docs/attachments).
132
+ # This hash is deep merged with the existing properties set using the other properties above. This allows your own fields properties to be appended to the existing fields that were created using the `payload` property for instance.
133
+ thumb_url: "http://example.com/path/to/thumb.png",
134
+ fields: [{
135
+ title: "My Field",
136
+ value: "My Value",
137
+ short: true
138
+ }]
139
+ }
140
+ )'
141
+ ]
142
+ end
143
+
144
+ def self.is_supported?(platform)
145
+ true
146
+ end
147
+ end
148
+ end
149
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module SlackBot
3
- VERSION = "0.1.2"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-slack_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manish Rathi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-07 00:00:00.000000000 Z
11
+ date: 2021-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -146,7 +146,9 @@ files:
146
146
  - README.md
147
147
  - lib/fastlane/plugin/slack_bot.rb
148
148
  - lib/fastlane/plugin/slack_bot/actions/fetch_files_slack.rb
149
+ - lib/fastlane/plugin/slack_bot/actions/file_upload_to_slack.rb
149
150
  - lib/fastlane/plugin/slack_bot/actions/post_to_slack.rb
151
+ - lib/fastlane/plugin/slack_bot/actions/update_slack_message.rb
150
152
  - lib/fastlane/plugin/slack_bot/helper/slack_bot_helper.rb
151
153
  - lib/fastlane/plugin/slack_bot/version.rb
152
154
  homepage: https://github.com/crazymanish/fastlane-plugin-slack_bot
@@ -168,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
170
  - !ruby/object:Gem::Version
169
171
  version: '0'
170
172
  requirements: []
171
- rubygems_version: 3.0.3
173
+ rubygems_version: 3.1.4
172
174
  signing_key:
173
175
  specification_version: 4
174
176
  summary: "A fastlane plugin to post slack message using bot api token. \U0001F680"