Repository: slack-go/slack
Pull request #1293 (2024-06-13 09:39:16)

chore: make channel optional on `UploadFileV2`
##### Pull Request Guidelines

These are recommendations for pull requests.
They are strictly guidelines to help manage expectations.

##### PR preparation
Run `make pr-prep` from the root of the repository to run formatting, linting and tests.

##### Should this be an issue instead
- [ ] is it a convenience method? (no new functionality, streamlines some use case)
- [ ] exposes a previously private type, const, method, etc.
- [ ] is it application specific (caching, retry logic, rate limiting, etc)
- [ ] is it performance related.

##### API changes

Since API changes have to be maintained they undergo a more detailed review and are more likely to require changes.

This change is non-breaking, and will allow users to upload files using the new `v2` endpoint that don't have channel id, so they won't automatically be posted. This is supported by Slack and needed if users want to attach the files to a post vs have them posted in the same thread/channel later.

###### Examples of API changes that do not meet guidelines:

None.


Patch:
diff --git a/conversation.go b/conversation.go
index 787a961..5552375 100644
--- a/conversation.go
+++ b/conversation.go
@@ -25,6 +25,7 @@ type Conversation struct {
 	IsGlobalShared     bool     `json:"is_global_shared"`
 	IsPendingExtShared bool     `json:"is_pending_ext_shared"`
 	IsPrivate          bool     `json:"is_private"`
+	IsReadOnly         bool     `json:"is_read_only"`
 	IsMpIM             bool     `json:"is_mpim"`
 	Unlinked           int      `json:"unlinked"`
 	NameNormalized     string   `json:"name_normalized"`
diff --git a/files.go b/files.go
index 40a5d16..9db1662 100644
--- a/files.go
+++ b/files.go
@@ -522,11 +522,13 @@ func (api *Client) completeUploadExternal(ctx context.Context, fileID string, pa
 		return nil, err
 	}
 	values := url.Values{
-		"token":      {api.token},
-		"files":      {string(requestBytes)},
-		"channel_id": {params.channel},
+		"token": {api.token},
+		"files": {string(requestBytes)},
 	}
 
+	if params.channel != "" {
+		values.Add("channel_id", params.channel)
+	}
 	if params.initialComment != "" {
 		values.Add("initial_comment", params.initialComment)
 	}
@@ -555,7 +557,7 @@ func (api *Client) UploadFileV2(params UploadFileV2Parameters) (*FileSummary, er
 // UploadFileV2 uploads file to a given slack channel using 3 steps with a custom context -
 //  1. Get an upload URL using files.getUploadURLExternal API
 //  2. Send the file as a post to the URL provided by slack
-//  3. Complete the upload and share it to the specified channel using files.completeUploadExternal
+//  3. Complete the upload and if a channel is specified, post it to the specified channel using files.completeUploadExternal
 func (api *Client) UploadFileV2Context(ctx context.Context, params UploadFileV2Parameters) (file *FileSummary, err error) {
 	if params.Filename == "" {
 		return nil, fmt.Errorf("file.upload.v2: filename cannot be empty")
@@ -563,9 +565,7 @@ func (api *Client) UploadFileV2Context(ctx context.Context, params UploadFileV2P
 	if params.FileSize == 0 {
 		return nil, fmt.Errorf("file.upload.v2: file size cannot be 0")
 	}
-	if params.Channel == "" {
-		return nil, fmt.Errorf("file.upload.v2: channel cannot be empty")
-	}
+
 	u, err := api.getUploadURLExternal(ctx, getUploadURLExternalParameters{
 		altText:     params.AltTxt,
 		fileName:    params.Filename,
diff --git a/reminders.go b/reminders.go
index 53d67c0..5543a15 100644
--- a/reminders.go
+++ b/reminders.go
@@ -41,10 +41,7 @@ func (api *Client) doReminders(ctx context.Context, path string, values url.Valu
 
 	// create an array of pointers to reminders
 	var reminders = make([]*Reminder, 0, len(response.Reminders))
-	for _, reminder := range response.Reminders {
-		reminders = append(reminders, reminder)
-	}
-
+	reminders = append(reminders, response.Reminders...)
 	return reminders, response.Err()
 }
 
diff --git a/webhooks.go b/webhooks.go
index e323353..8fc149d 100644
--- a/webhooks.go
+++ b/webhooks.go
@@ -24,6 +24,8 @@ type WebhookMessage struct {
 	ReplaceOriginal bool         `json:"replace_original"`
 	DeleteOriginal  bool         `json:"delete_original"`
 	ReplyBroadcast  bool         `json:"reply_broadcast,omitempty"`
+	UnfurlLinks     bool         `json:"unfurl_links,omitempty"`
+	UnfurlMedia     bool         `json:"unfurl_media,omitempty"`
 }
 
 func PostWebhook(url string, msg *WebhookMessage) error {


Test patch:
diff --git a/files_test.go b/files_test.go
index f304a4e..59afc1c 100644
--- a/files_test.go
+++ b/files_test.go
@@ -272,4 +272,13 @@ func TestUploadFileV2(t *testing.T) {
 	if _, err := api.UploadFileV2(params); err != nil {
 		t.Errorf("Unexpected error: %s", err)
 	}
+
+	reader = bytes.NewBufferString("test no channel")
+	params = UploadFileV2Parameters{
+		Filename: "test.txt",
+		Reader:   reader,
+		FileSize: 15}
+	if _, err := api.UploadFileV2(params); err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	}
 }