1package slack
2
3import (
4	"context"
5	"encoding/json"
6	"strings"
7)
8
9// InputType is the type of the dialog input type
10type InputType string
11
12const (
13	// InputTypeText textfield input
14	InputTypeText InputType = "text"
15	// InputTypeTextArea textarea input
16	InputTypeTextArea InputType = "textarea"
17	// InputTypeSelect select menus input
18	InputTypeSelect InputType = "select"
19)
20
21// DialogInput for dialogs input type text or menu
22type DialogInput struct {
23	Type        InputType `json:"type"`
24	Label       string    `json:"label"`
25	Name        string    `json:"name"`
26	Placeholder string    `json:"placeholder"`
27	Optional    bool      `json:"optional"`
28	Hint        string    `json:"hint"`
29}
30
31// DialogTrigger ...
32type DialogTrigger struct {
33	TriggerID string `json:"trigger_id"` //Required. Must respond within 3 seconds.
34	Dialog    Dialog `json:"dialog"`     //Required.
35}
36
37// Dialog as in Slack dialogs
38// https://api.slack.com/dialogs#option_element_attributes#top-level_dialog_attributes
39type Dialog struct {
40	TriggerID      string          `json:"trigger_id"`      // Required
41	CallbackID     string          `json:"callback_id"`     // Required
42	State          string          `json:"state,omitempty"` // Optional
43	Title          string          `json:"title"`
44	SubmitLabel    string          `json:"submit_label,omitempty"`
45	NotifyOnCancel bool            `json:"notify_on_cancel"`
46	Elements       []DialogElement `json:"elements"`
47}
48
49// DialogElement abstract type for dialogs.
50type DialogElement interface{}
51
52// DialogCallback DEPRECATED use InteractionCallback
53type DialogCallback InteractionCallback
54
55// DialogSubmissionCallback is sent from Slack when a user submits a form from within a dialog
56type DialogSubmissionCallback struct {
57	// NOTE: State is only used with the dialog_submission type.
58	// You should use InteractionCallback.BlockActionsState for block_actions type.
59	State      string            `json:"-"`
60	Submission map[string]string `json:"submission"`
61}
62
63// DialogOpenResponse response from `dialog.open`
64type DialogOpenResponse struct {
65	SlackResponse
66	DialogResponseMetadata DialogResponseMetadata `json:"response_metadata"`
67}
68
69// DialogResponseMetadata lists the error messages
70type DialogResponseMetadata struct {
71	Messages []string `json:"messages"`
72}
73
74// DialogInputValidationError is an error when user inputs incorrect value to form from within a dialog
75type DialogInputValidationError struct {
76	Name  string `json:"name"`
77	Error string `json:"error"`
78}
79
80// DialogInputValidationErrors lists the name of field and that error messages
81type DialogInputValidationErrors struct {
82	Errors []DialogInputValidationError `json:"errors"`
83}
84
85// OpenDialog opens a dialog window where the triggerID originated from.
86// EXPERIMENTAL: dialog functionality is currently experimental, api is not considered stable.
87func (api *Client) OpenDialog(triggerID string, dialog Dialog) (err error) {
88	return api.OpenDialogContext(context.Background(), triggerID, dialog)
89}
90
91// OpenDialogContext opens a dialog window where the triggerId originated from with a custom context
92// EXPERIMENTAL: dialog functionality is currently experimental, api is not considered stable.
93func (api *Client) OpenDialogContext(ctx context.Context, triggerID string, dialog Dialog) (err error) {
94	if triggerID == "" {
95		return ErrParametersMissing
96	}
97
98	req := DialogTrigger{
99		TriggerID: triggerID,
100		Dialog:    dialog,
101	}
102
103	encoded, err := json.Marshal(req)
104	if err != nil {
105		return err
106	}
107
108	response := &DialogOpenResponse{}
109	endpoint := api.endpoint + "dialog.open"
110	if err := postJSON(ctx, api.httpclient, endpoint, api.token, encoded, response, api); err != nil {
111		return err
112	}
113
114	if len(response.DialogResponseMetadata.Messages) > 0 {
115		response.Ok = false
116		response.Error += "\n" + strings.Join(response.DialogResponseMetadata.Messages, "\n")
117	}
118
119	return response.Err()
120}
121