-
Notifications
You must be signed in to change notification settings - Fork 31
feat(experiment): add apps.icon.set support for non-hosted app icons #469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
4d6a19e
2053f5d
febaece
27ba074
462e653
e11c382
e396a02
a126d2a
54387b6
b382d68
5d0ee94
4a06079
73e27f0
0c5b3be
41a63f4
c5d8b54
7b30774
00fbcca
2058c6a
76bdb47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -35,6 +35,8 @@ import ( | |||||
|
|
||||||
| const ( | ||||||
| appIconMethod = "apps.hosted.icon" | ||||||
| // AppIconSetMethod is the API method for setting app icons for non-hosted apps. | ||||||
| AppIconSetMethod = "apps.icon.set" | ||||||
| ) | ||||||
|
|
||||||
| // IconResult details to be saved | ||||||
|
|
@@ -48,6 +50,16 @@ type iconResponse struct { | |||||
|
|
||||||
| // Icon updates a Slack App's icon | ||||||
|
srtaalej marked this conversation as resolved.
Outdated
|
||||||
| func (c *Client) Icon(ctx context.Context, fs afero.Fs, token, appID, iconFilePath string) (IconResult, error) { | ||||||
| return c.uploadIcon(ctx, fs, token, appID, iconFilePath, appIconMethod, "file") | ||||||
| } | ||||||
|
|
||||||
| // IconSet sets a Slack App's icon using the apps.icon.set API method. | ||||||
| func (c *Client) IconSet(ctx context.Context, fs afero.Fs, token, appID, iconFilePath string) (IconResult, error) { | ||||||
| return c.uploadIcon(ctx, fs, token, appID, iconFilePath, AppIconSetMethod, "icon") | ||||||
| } | ||||||
|
|
||||||
| // uploadIcon uploads an icon to the given API method. | ||||||
| func (c *Client) uploadIcon(ctx context.Context, fs afero.Fs, token, appID, iconFilePath, apiMethod, fileFieldName string) (IconResult, error) { | ||||||
| var ( | ||||||
| iconBytes []byte | ||||||
| err error | ||||||
|
|
@@ -81,7 +93,7 @@ func (c *Client) Icon(ctx context.Context, fs afero.Fs, token, appID, iconFilePa | |||||
|
|
||||||
| var part io.Writer | ||||||
| h := make(textproto.MIMEHeader) | ||||||
| h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, "file", iconStat.Name())) | ||||||
| h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, fileFieldName, iconStat.Name())) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
🌚 suggestion: Let's revert the addition of |
||||||
| h.Set("Content-Type", http.DetectContentType(iconBytes)) | ||||||
| part, err = writer.CreatePart(h) | ||||||
| if err != nil { | ||||||
|
|
@@ -101,7 +113,7 @@ func (c *Client) Icon(ctx context.Context, fs afero.Fs, token, appID, iconFilePa | |||||
| writer.Close() | ||||||
|
|
||||||
| var sURL *url.URL | ||||||
| sURL, err = url.Parse(c.host + "/api/" + appIconMethod) | ||||||
| sURL, err = url.Parse(c.host + "/api/" + apiMethod) | ||||||
| if err != nil { | ||||||
| return IconResult{}, err | ||||||
| } | ||||||
|
|
||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📚 note: Let's document this too! https://docs.slack.dev/tools/slack-cli/reference/experiments |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ import ( | |
| "github.com/opentracing/opentracing-go" | ||
| "github.com/slackapi/slack-cli/internal/api" | ||
| "github.com/slackapi/slack-cli/internal/config" | ||
| "github.com/slackapi/slack-cli/internal/experiment" | ||
| "github.com/slackapi/slack-cli/internal/pkg/manifest" | ||
| "github.com/slackapi/slack-cli/internal/shared" | ||
| "github.com/slackapi/slack-cli/internal/shared/types" | ||
|
|
@@ -521,30 +522,25 @@ func InstallLocalApp(ctx context.Context, clients *shared.ClientFactory, orgGran | |
| return app, result, installState, err | ||
| } | ||
|
|
||
| // | ||
| // TODO: Currently, cannot update the icon if app is not hosted. | ||
| // | ||
| // upload icon, default to icon.png | ||
| // var iconPath = slackYaml.Icon | ||
| // if iconPath == "" { | ||
| // if _, err := os.Stat("icon.png"); !os.IsNotExist(err) { | ||
| // iconPath = "icon.png" | ||
| // } | ||
| // } | ||
| // if iconPath != "" { | ||
| // clients.IO.PrintDebug(ctx, "uploading icon") | ||
| // err = updateIcon(ctx, clients, iconPath, env.AppID, token) | ||
| // if err != nil { | ||
| // clients.IO.PrintError(ctx, "An error occurred updating the Icon", err) | ||
| // } | ||
| // // Save a md5 hash of the icon in environments.yaml | ||
| // var iconHash string | ||
| // iconHash, err = getIconHash(iconPath) | ||
| // if err != nil { | ||
| // return env, api.DeveloperAppInstallResult{}, err | ||
| // } | ||
| // env.IconHash = iconHash | ||
| // } | ||
| // upload icon for non-hosted apps (gated behind set-icon experiment) | ||
| if clients.Config.WithExperimentOn(experiment.SetIcon) { | ||
| var iconPath = slackManifest.Icon | ||
| if iconPath == "" { | ||
| if _, err := os.Stat("icon.png"); !os.IsNotExist(err) { | ||
| iconPath = "icon.png" | ||
| } | ||
| } | ||
| if iconPath != "" { | ||
| clients.IO.PrintDebug(ctx, "uploading icon") | ||
| _, iconErr := clients.API().IconSet(ctx, clients.Fs, token, app.AppID, iconPath) | ||
|
Comment on lines
+534
to
+535
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔬 question: Could we match debug log outputs for the While other methods include various request and response details that are useful in debugging. I think edges in image upload might make verbose logging most important here!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is a gap in both apps.icon.set and apps.hosted.icon I'm going to leave this for a followup PR 🫡 |
||
| if iconErr != nil { | ||
| clients.IO.PrintDebug(ctx, "icon error: %s", iconErr) | ||
| _, _ = clients.IO.WriteOut().Write([]byte(style.SectionSecondaryf("Error updating app icon: %s", iconErr))) | ||
| } else { | ||
| _, _ = clients.IO.WriteOut().Write([]byte(style.SectionSecondaryf("Updated app icon: %s", iconPath))) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // update config with latest yaml hash | ||
| // env.Hash = slackYaml.Hash | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.