package slack import ( "context" "encoding/json" "net/url" ) // Manifest is an application manifest schema type Manifest struct { Metadata ManifestMetadata `json:"_metadata,omitempty" yaml:"_metadata,omitempty"` Display Display `json:"display_information" yaml:"display_information"` Settings Settings `json:"settings,omitempty" yaml:"settings,omitempty"` Features Features `json:"features,omitempty" yaml:"features,omitempty"` OAuthConfig OAuthConfig `json:"oauth_config,omitempty" yaml:"oauth_config,omitempty"` } // CreateManifest creates an app from an app manifest func (api *Client) CreateManifest(manifest *Manifest, token string) (*ManifestResponse, error) { return api.CreateManifestContext(context.Background(), manifest, token) } // CreateManifestContext creates an app from an app manifest with a custom context func (api *Client) CreateManifestContext(ctx context.Context, manifest *Manifest, token string) (*ManifestResponse, error) { if token == "" { token = api.configToken } jsonBytes, err := json.Marshal(manifest) if err != nil { return nil, err } values := url.Values{ "token": {token}, "manifest": {string(jsonBytes)}, } response := &ManifestResponse{} err = api.postMethod(ctx, "apps.manifest.create", values, response) if err != nil { return nil, err } return response, response.Err() } // DeleteManifest permanently deletes an app created through app manifests func (api *Client) DeleteManifest(token string, appId string) (*SlackResponse, error) { return api.DeleteManifestContext(context.Background(), token, appId) } // DeleteManifestContext permanently deletes an app created through app manifests with a custom context func (api *Client) DeleteManifestContext(ctx context.Context, token string, appId string) (*SlackResponse, error) { if token == "" { token = api.configToken } values := url.Values{ "token": {token}, "app_id": {appId}, } response := &SlackResponse{} err := api.postMethod(ctx, "apps.manifest.delete", values, response) if err != nil { return nil, err } return response, response.Err() } // ExportManifest exports an app manifest from an existing app func (api *Client) ExportManifest(token string, appId string) (*Manifest, error) { return api.ExportManifestContext(context.Background(), token, appId) } // ExportManifestContext exports an app manifest from an existing app with a custom context func (api *Client) ExportManifestContext(ctx context.Context, token string, appId string) (*Manifest, error) { if token == "" { token = api.configToken } values := url.Values{ "token": {token}, "app_id": {appId}, } response := &ExportManifestResponse{} err := api.postMethod(ctx, "apps.manifest.export", values, response) if err != nil { return nil, err } return &response.Manifest, response.Err() } // UpdateManifest updates an app from an app manifest func (api *Client) UpdateManifest(manifest *Manifest, token string, appId string) (*UpdateManifestResponse, error) { return api.UpdateManifestContext(context.Background(), manifest, token, appId) } // UpdateManifestContext updates an app from an app manifest with a custom context func (api *Client) UpdateManifestContext(ctx context.Context, manifest *Manifest, token string, appId string) (*UpdateManifestResponse, error) { if token == "" { token = api.configToken } jsonBytes, err := json.Marshal(manifest) if err != nil { return nil, err } values := url.Values{ "token": {token}, "app_id": {appId}, "manifest": {string(jsonBytes)}, } response := &UpdateManifestResponse{} err = api.postMethod(ctx, "apps.manifest.update", values, response) if err != nil { return nil, err } return response, response.Err() } // ValidateManifest sends a request to apps.manifest.validate to validate your app manifest func (api *Client) ValidateManifest(manifest *Manifest, token string, appId string) (*ManifestResponse, error) { return api.ValidateManifestContext(context.Background(), manifest, token, appId) } // ValidateManifestContext sends a request to apps.manifest.validate to validate your app manifest with a custom context func (api *Client) ValidateManifestContext(ctx context.Context, manifest *Manifest, token string, appId string) (*ManifestResponse, error) { if token == "" { token = api.configToken } // Marshal manifest into string jsonBytes, err := json.Marshal(manifest) if err != nil { return nil, err } values := url.Values{ "token": {token}, "manifest": {string(jsonBytes)}, } if appId != "" { values.Add("app_id", appId) } response := &ManifestResponse{} err = api.postMethod(ctx, "apps.manifest.validate", values, response) if err != nil { return nil, err } return response, response.Err() } // ManifestMetadata is a group of settings that describe the manifest type ManifestMetadata struct { MajorVersion int `json:"major_version,omitempty" yaml:"major_version,omitempty"` MinorVersion int `json:"minor_version,omitempty" yaml:"minor_version,omitempty"` } // Display is a group of settings that describe parts of an app's appearance within Slack type Display struct { Name string `json:"name" yaml:"name"` Description string `json:"description,omitempty" yaml:"description,omitempty"` LongDescription string `json:"long_description,omitempty" yaml:"long_description,omitempty"` BackgroundColor string `json:"background_color,omitempty" yaml:"background_color,omitempty"` } // Settings is a group of settings corresponding to the Settings section of the app config pages. type Settings struct { AllowedIPAddressRanges []string `json:"allowed_ip_address_ranges,omitempty" yaml:"allowed_ip_address_ranges,omitempty"` EventSubscriptions EventSubscriptions `json:"event_subscriptions,omitempty" yaml:"event_subscriptions,omitempty"` Interactivity Interactivity `json:"interactivity,omitempty" yaml:"interactivity,omitempty"` OrgDeployEnabled bool `json:"org_deploy_enabled,omitempty" yaml:"org_deploy_enabled,omitempty"` SocketModeEnabled bool `json:"socket_mode_enabled,omitempty" yaml:"socket_mode_enabled,omitempty"` } // EventSubscriptions is a group of settings that describe the Events API configuration type EventSubscriptions struct { RequestUrl string `json:"request_url,omitempty" yaml:"request_url,omitempty"` BotEvents []string `json:"bot_events,omitempty" yaml:"bot_events,omitempty"` UserEvents []string `json:"user_events,omitempty" yaml:"user_events,omitempty"` } // Interactivity is a group of settings that describe the interactivity configuration type Interactivity struct { IsEnabled bool `json:"is_enabled" yaml:"is_enabled"` RequestUrl string `json:"request_url,omitempty" yaml:"request_url,omitempty"` MessageMenuOptionsUrl string `json:"message_menu_options_url,omitempty" yaml:"message_menu_options_url,omitempty"` } // Features is a group of settings corresponding to the Features section of the app config pages type Features struct { AppHome AppHome `json:"app_home,omitempty" yaml:"app_home,omitempty"` BotUser BotUser `json:"bot_user,omitempty" yaml:"bot_user,omitempty"` Shortcuts []Shortcut `json:"shortcuts,omitempty" yaml:"shortcuts,omitempty"` SlashCommands []ManifestSlashCommand `json:"slash_commands,omitempty" yaml:"slash_commands,omitempty"` WorkflowSteps []WorkflowStep `json:"workflow_steps,omitempty" yaml:"workflow_steps,omitempty"` } // AppHome is a group of settings that describe the App Home configuration type AppHome struct { HomeTabEnabled bool `json:"home_tab_enabled,omitempty" yaml:"home_tab_enabled,omitempty"` MessagesTabEnabled bool `json:"messages_tab_enabled,omitempty" yaml:"messages_tab_enabled,omitempty"` MessagesTabReadOnlyEnabled bool `json:"messages_tab_read_only_enabled,omitempty" yaml:"messages_tab_read_only_enabled,omitempty"` } // BotUser is a group of settings that describe bot user configuration type BotUser struct { DisplayName string `json:"display_name" yaml:"display_name"` AlwaysOnline bool `json:"always_online,omitempty" yaml:"always_online,omitempty"` } // Shortcut is a group of settings that describes shortcut configuration type Shortcut struct { Name string `json:"name" yaml:"name"` CallbackID string `json:"callback_id" yaml:"callback_id"` Description string `json:"description" yaml:"description"` Type ShortcutType `json:"type" yaml:"type"` } // ShortcutType is a new string type for the available types of shortcuts type ShortcutType string const ( MessageShortcut ShortcutType = "message" GlobalShortcut ShortcutType = "global" ) // ManifestSlashCommand is a group of settings that describes slash command configuration type ManifestSlashCommand struct { Command string `json:"command" yaml:"command"` Description string `json:"description" yaml:"description"` ShouldEscape bool `json:"should_escape,omitempty" yaml:"should_escape,omitempty"` Url string `json:"url,omitempty" yaml:"url,omitempty"` UsageHint string `json:"usage_hint,omitempty" yaml:"usage_hint,omitempty"` } // WorkflowStep is a group of settings that describes workflow steps configuration type WorkflowStep struct { Name string `json:"name" yaml:"name"` CallbackID string `json:"callback_id" yaml:"callback_id"` } // OAuthConfig is a group of settings that describe OAuth configuration for the app type OAuthConfig struct { RedirectUrls []string `json:"redirect_urls,omitempty" yaml:"redirect_urls,omitempty"` Scopes OAuthScopes `json:"scopes,omitempty" yaml:"scopes,omitempty"` } // OAuthScopes is a group of settings that describe permission scopes configuration type OAuthScopes struct { Bot []string `json:"bot,omitempty" yaml:"bot,omitempty"` User []string `json:"user,omitempty" yaml:"user,omitempty"` } // ManifestResponse is the response returned by the API for apps.manifest.x endpoints type ManifestResponse struct { Errors []ManifestValidationError `json:"errors,omitempty"` SlackResponse } // ManifestValidationError is an error message returned for invalid manifests type ManifestValidationError struct { Message string `json:"message"` Pointer string `json:"pointer"` } type ExportManifestResponse struct { Manifest Manifest `json:"manifest,omitempty"` SlackResponse } type UpdateManifestResponse struct { AppId string `json:"app_id,omitempty"` PermissionsUpdated bool `json:"permissions_updated,omitempty"` ManifestResponse }