-
Notifications
You must be signed in to change notification settings - Fork 2
/
slash_command.go
101 lines (86 loc) · 2.67 KB
/
slash_command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package websockets
import (
"context"
"fmt"
"github.com/slack-go/slack"
"github.com/slack-go/slack/socketmode"
"go.uber.org/zap"
"go.autokitteh.dev/autokitteh/integrations/slack/api/chat"
"go.autokitteh.dev/autokitteh/integrations/slack/webhooks"
"go.autokitteh.dev/autokitteh/internal/kittehs"
"go.autokitteh.dev/autokitteh/sdk/sdktypes"
)
// HandleSlashCommand dispatches and acknowledges a user's slash command registered by our
// Slack app. See https://api.slack.com/interactivity/slash-commands#responding_to_commands.
// Compare this function with the [webhooks.HandleSlashCommand] implementation.
func (h handler) handleSlashCommand(e *socketmode.Event, c *socketmode.Client) {
// This data casting is guaranteed to work, so no need to check it
d := e.Data.(slack.SlashCommand)
// Transform the received Slack event into an autokitteh slash command struct.
cmd := webhooks.SlashCommand{
TeamID: d.TeamID,
TeamDomain: d.TeamDomain,
IsEnterpriseInstall: d.IsEnterpriseInstall,
EnterpriseID: d.EnterpriseID,
EnterpriseName: d.EnterpriseName,
APIAppID: d.APIAppID,
ChannelID: d.ChannelID,
ChannelName: d.ChannelName,
UserID: d.UserID,
Command: d.Command,
Text: d.Text,
ResponseURL: d.ResponseURL,
TriggerID: d.TriggerID,
}
// Transform the slash command struct into an autokitteh event.
wrapped, err := sdktypes.DefaultValueWrapper.Wrap(cmd)
if err != nil {
h.logger.Error("Failed to wrap Slack event",
zap.Any("cmd", cmd),
zap.Error(err),
)
c.Ack(*e.Request)
return
}
m, err := wrapped.ToStringValuesMap()
if err != nil {
h.logger.Error("Failed to convert wrapped Slack event",
zap.Any("cmd", cmd),
zap.Error(err),
)
c.Ack(*e.Request)
return
}
pb := kittehs.TransformMapValues(m, sdktypes.ToProto)
akEvent := &sdktypes.EventPB{
IntegrationId: h.integrationID.String(),
EventType: "slash_command",
Data: pb,
}
// Retrieve all the relevant connections for this event.
connTokens, err := h.secrets.List(context.Background(), h.scope, "websockets")
if err != nil {
h.logger.Error("Failed to retrieve connection tokens", zap.Error(err))
c.Ack(*e.Request)
return
}
// Dispatch the event to all of them, for asynchronous handling.
h.dispatchAsyncEventsToConnections(connTokens, akEvent)
// https://api.slack.com/apis/connections/socket#acknowledge
if len(cmd.Text) == 0 {
c.Ack(*e.Request)
return
}
// https://api.slack.com/apis/connections/socket#command
c.Ack(*e.Request, map[string][]*chat.Block{
"blocks": {
{
Type: "section",
Text: &chat.Text{
Type: "mrkdwn",
Text: fmt.Sprintf("Your command: `%s`", cmd.Text),
},
},
},
})
}