-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
handlers.go
166 lines (137 loc) · 4.67 KB
/
handlers.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package handlers
import (
"context"
"fmt"
"net/http"
"strings"
"github.com/nekomeowww/insights-bot/internal/services/smr"
"github.com/nekomeowww/insights-bot/internal/services/smr/smrqueue"
"github.com/gin-gonic/gin"
"github.com/nekomeowww/insights-bot/ent"
"github.com/nekomeowww/insights-bot/ent/slackoauthcredentials"
"github.com/nekomeowww/insights-bot/internal/configs"
"github.com/nekomeowww/insights-bot/internal/datastore"
"github.com/nekomeowww/insights-bot/pkg/bots/slackbot"
"github.com/nekomeowww/insights-bot/pkg/bots/slackbot/services"
"github.com/nekomeowww/insights-bot/pkg/logger"
"github.com/nekomeowww/insights-bot/pkg/types/bot"
types "github.com/nekomeowww/insights-bot/pkg/types/smr"
"github.com/slack-go/slack"
"go.uber.org/fx"
"go.uber.org/zap"
)
func NewModules() fx.Option {
return fx.Options(
fx.Provide(NewHandlers()),
)
}
type NewHandlersParam struct {
fx.In
Config *configs.Config
Logger *logger.Logger
Ent *datastore.Ent
SmrQueue *smrqueue.Queue
Services *services.Services
}
type Handlers struct {
config *configs.Config
logger *logger.Logger
ent *datastore.Ent
smrQueue *smrqueue.Queue
services *services.Services
}
func NewHandlers() func(param NewHandlersParam) *Handlers {
return func(param NewHandlersParam) *Handlers {
return &Handlers{
config: param.Config,
ent: param.Ent,
logger: param.Logger,
smrQueue: param.SmrQueue,
services: param.Services,
}
}
}
type receivedCommandInfo struct {
Command string `form:"command"`
Text string `form:"text"`
ResponseUrl string `form:"response_url"`
UserID string `form:"user_id"`
ChannelID string `form:"channel_id"`
TeamID string `form:"team_id"`
}
func (h *Handlers) PostCommandInfo(ctx *gin.Context) {
var body receivedCommandInfo
if err := ctx.Bind(&body); err != nil {
ctx.AbortWithStatus(http.StatusBadRequest)
h.logger.Warn("failed to bind request body, type definition of slack request body may have changed", zap.Error(err))
return
}
h.logger.Debug(fmt.Sprintf("slack: command received: /smr %s", body.Text),
zap.String("user_id", body.UserID),
zap.String("channel_id", body.ChannelID),
)
urlString := body.Text
urlString = strings.TrimSpace(urlString)
if !strings.HasPrefix(urlString, "http://") && !strings.HasPrefix(urlString, "https://") {
urlString = "https://" + urlString
}
err, originErr := smr.CheckUrl(urlString)
if err != nil {
if smr.IsUrlCheckError(err) {
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage(smr.FormatUrlCheckError(err, bot.FromPlatformSlack)))
return
}
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage("出现了一些问题,可以再试试?"))
h.logger.Warn("discord: failed to send error message", zap.Error(err), zap.NamedError("original_error", originErr))
return
}
// check permissions
_, err = h.ent.SlackOAuthCredentials.Query().Where(
slackoauthcredentials.TeamID(body.TeamID),
).First(context.Background())
if err != nil {
h.logger.Warn("slack: failed to get team's access token", zap.Error(err))
if ent.IsNotFound(err) {
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage("本应用没有权限向这个频道发送消息,尝试重新安装一下?"))
return
}
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage("出现了一些问题,可以再试试?"))
return
}
// add task
err = h.smrQueue.AddTask(types.TaskInfo{
Platform: bot.FromPlatformSlack,
URL: urlString,
ChannelID: body.ChannelID,
TeamID: body.TeamID,
})
if err != nil {
h.logger.Warn("slack: failed to add task", zap.Error(err))
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage("量子速读请求发送失败了,可以再试试?"))
return
}
// response
ctx.JSON(http.StatusOK, slackbot.NewSlackWebhookMessage("请稍等,量子速读中..."))
}
// GetInstallAuth Receive auth code and request for access token.
func (h *Handlers) GetInstallAuth(ctx *gin.Context) {
code := ctx.Query("code")
if code == "" {
ctx.AbortWithStatus(http.StatusBadRequest)
return
}
resp, err := slack.GetOAuthV2Response(&http.Client{}, h.config.Slack.ClientID, h.config.Slack.ClientSecret, code, "")
if err != nil {
h.logger.Error("slack: failed to get access token, interrupt", zap.Error(err))
ctx.AbortWithStatus(http.StatusServiceUnavailable)
return
}
err = h.services.CreateOrUpdateSlackCredential(resp.Team.ID, resp.AccessToken, resp.RefreshToken)
if err != nil {
ctx.AbortWithStatus(http.StatusInternalServerError)
return
}
ctx.Header("content-type", "text/html")
_, _ = ctx.Writer.Write([]byte("<h1 style=\"text-align:center\">Success! Now you can close this page<h1>"))
ctx.Status(http.StatusOK)
}