mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-27 09:15:15 +00:00
interact: support slack modal view request
This commit is contained in:
parent
16688be64d
commit
08241bffbd
|
@ -52,7 +52,11 @@ func (it *AuthInteract) Commands(interact *Interact) {
|
|||
it.OneTimePasswordKey = key
|
||||
}
|
||||
interact.Command("/auth", "authorize", func(reply Reply, session Session) error {
|
||||
reply.Message("Enter your authentication token")
|
||||
reply.InputText("Authentication Token", TextField{
|
||||
Label: "Authentication Token",
|
||||
Name: "token",
|
||||
PlaceHolder: "Enter Your Authentication Token",
|
||||
})
|
||||
session.SetAuthorizing(true)
|
||||
return nil
|
||||
}).Next(func(token string, reply Reply) error {
|
||||
|
|
|
@ -1,8 +1,30 @@
|
|||
package interact
|
||||
|
||||
type Button struct {
|
||||
Text string
|
||||
Text string
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type TextField struct {
|
||||
// Name is the form field name
|
||||
Name string
|
||||
|
||||
// Label is the field label
|
||||
Label string
|
||||
|
||||
// PlaceHolder is the sample text in the text input
|
||||
PlaceHolder string
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
// Name is the form field name
|
||||
Name string
|
||||
|
||||
// Label is the option label for display
|
||||
Label string
|
||||
|
||||
// Value is the option value
|
||||
Value string
|
||||
}
|
||||
|
||||
|
@ -16,7 +38,12 @@ type Reply interface {
|
|||
// AddButton adds the button to the reply
|
||||
AddButton(text string, name, value string)
|
||||
|
||||
RequireTextInput(title, message string, textFields ...TextField)
|
||||
InputText(prompt string, textFields ...TextField)
|
||||
|
||||
Choose(prompt string, options ...Option)
|
||||
|
||||
// Confirm shows the confirm dialog or confirm button in the user interface
|
||||
// Confirm(prompt string)
|
||||
|
||||
// RemoveKeyboard hides the keyboard from the client user interface
|
||||
RemoveKeyboard()
|
||||
|
|
|
@ -25,6 +25,8 @@ type SlackReply struct {
|
|||
message string
|
||||
|
||||
buttons []Button
|
||||
|
||||
textInputModalViewRequest *slack.ModalViewRequest
|
||||
}
|
||||
|
||||
func (reply *SlackReply) Send(message string) {
|
||||
|
@ -39,10 +41,18 @@ func (reply *SlackReply) Send(message string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (reply *SlackReply) Choose(prompt string, options ...Option) {
|
||||
}
|
||||
|
||||
func (reply *SlackReply) Message(message string) {
|
||||
reply.message = message
|
||||
}
|
||||
|
||||
func (reply *SlackReply) InputText(prompt string, textFields ...TextField) {
|
||||
reply.message = prompt
|
||||
reply.textInputModalViewRequest = generateTextInputModalRequest(prompt, prompt, textFields...)
|
||||
}
|
||||
|
||||
// RemoveKeyboard is not supported by Slack
|
||||
func (reply *SlackReply) RemoveKeyboard() {}
|
||||
|
||||
|
@ -54,7 +64,15 @@ func (reply *SlackReply) AddButton(text string, name string, value string) {
|
|||
})
|
||||
}
|
||||
|
||||
func (reply *SlackReply) build() map[string]interface{} {
|
||||
func (reply *SlackReply) build() interface{} {
|
||||
if reply.textInputModalViewRequest != nil {
|
||||
return reply.textInputModalViewRequest
|
||||
}
|
||||
|
||||
if len(reply.message) > 0 {
|
||||
return reply.message
|
||||
}
|
||||
|
||||
var blocks []slack.Block
|
||||
|
||||
blocks = append(blocks, slack.NewSectionBlock(
|
||||
|
@ -247,28 +265,37 @@ func (s *Slack) listen() {
|
|||
}
|
||||
|
||||
log.Debugf("slash command received: %+v", slashCmd)
|
||||
if responder, exists := s.commandResponders[slashCmd.Command]; exists {
|
||||
session := s.findSession(evt, slashCmd.UserID)
|
||||
reply := s.newReply(session)
|
||||
if err := responder(session, slashCmd.Text, reply); err != nil {
|
||||
log.WithError(err).Errorf("responder returns error")
|
||||
continue
|
||||
}
|
||||
responder, exists := s.commandResponders[slashCmd.Command]
|
||||
if !exists {
|
||||
log.Errorf("command %s does not exist", slashCmd.Command)
|
||||
s.socket.Ack(*evt.Request)
|
||||
continue
|
||||
}
|
||||
|
||||
req := generateTextInputModalRequest("Authentication", "Please enter your code", TextField{
|
||||
Label: "First Name",
|
||||
Name: "first_name",
|
||||
PlaceHolder: "Enter your first name",
|
||||
})
|
||||
// s.socket.Ack(*evt.Request, req)
|
||||
if resp, err := s.client.OpenView(slashCmd.TriggerID, req); err != nil {
|
||||
session := s.findSession(evt, slashCmd.UserID)
|
||||
reply := s.newReply(session)
|
||||
if err := responder(session, slashCmd.Text, reply); err != nil {
|
||||
log.WithError(err).Errorf("responder returns error")
|
||||
s.socket.Ack(*evt.Request)
|
||||
continue
|
||||
}
|
||||
|
||||
payload := reply.build()
|
||||
if payload == nil {
|
||||
log.Warnf("reply returns nil payload")
|
||||
// ack with empty payload
|
||||
s.socket.Ack(*evt.Request)
|
||||
continue
|
||||
}
|
||||
|
||||
switch o := payload.(type) {
|
||||
case *slack.ModalViewRequest:
|
||||
if resp, err := s.client.OpenView(slashCmd.TriggerID, *o); err != nil {
|
||||
log.WithError(err).Error("view open error, resp: %+v", resp)
|
||||
}
|
||||
|
||||
payload := reply.build()
|
||||
s.socket.Ack(*evt.Request, payload)
|
||||
} else {
|
||||
log.Errorf("command %s does not exist", slashCmd.Command)
|
||||
s.socket.Ack(*evt.Request)
|
||||
default:
|
||||
s.socket.Ack(*evt.Request, o)
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -301,18 +328,7 @@ func (s *Slack) Start(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
type TextField struct {
|
||||
// Label is the field label
|
||||
Label string
|
||||
|
||||
// Name is the form field name
|
||||
Name string
|
||||
|
||||
// PlaceHolder is the sample text in the text input
|
||||
PlaceHolder string
|
||||
}
|
||||
|
||||
func generateTextInputModalRequest(title string, prompt string, textFields ...TextField) slack.ModalViewRequest {
|
||||
func generateTextInputModalRequest(title string, prompt string, textFields ...TextField) *slack.ModalViewRequest {
|
||||
// create a ModalViewRequest with a header and two inputs
|
||||
titleText := slack.NewTextBlockObject("plain_text", title, false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
|
@ -328,12 +344,12 @@ func generateTextInputModalRequest(title string, prompt string, textFields ...Te
|
|||
}
|
||||
|
||||
for _, textField := range textFields {
|
||||
firstNameText := slack.NewTextBlockObject("plain_text", textField.Label, false, false)
|
||||
firstNamePlaceholder := slack.NewTextBlockObject("plain_text", textField.PlaceHolder, false, false)
|
||||
firstNameElement := slack.NewPlainTextInputBlockElement(firstNamePlaceholder, textField.Name)
|
||||
labelObject := slack.NewTextBlockObject("plain_text", textField.Label, false, false)
|
||||
placeHolderObject := slack.NewTextBlockObject("plain_text", textField.PlaceHolder, false, false)
|
||||
textInputObject := slack.NewPlainTextInputBlockElement(placeHolderObject, textField.Name)
|
||||
// Notice that blockID is a unique identifier for a block
|
||||
firstName := slack.NewInputBlock(textField.Name, firstNameText, firstNameElement)
|
||||
blocks.BlockSet = append(blocks.BlockSet, firstName)
|
||||
inputBlock := slack.NewInputBlock(textField.Name, labelObject, textInputObject)
|
||||
blocks.BlockSet = append(blocks.BlockSet, inputBlock)
|
||||
}
|
||||
|
||||
var modalRequest slack.ModalViewRequest
|
||||
|
@ -342,5 +358,5 @@ func generateTextInputModalRequest(title string, prompt string, textFields ...Te
|
|||
modalRequest.Close = closeText
|
||||
modalRequest.Submit = submitText
|
||||
modalRequest.Blocks = blocks
|
||||
return modalRequest
|
||||
return &modalRequest
|
||||
}
|
||||
|
|
|
@ -57,11 +57,10 @@ type TelegramReply struct {
|
|||
|
||||
message string
|
||||
menu *telebot.ReplyMarkup
|
||||
buttons [][]telebot.Btn
|
||||
buttons []telebot.Btn
|
||||
set bool
|
||||
}
|
||||
|
||||
|
||||
func (r *TelegramReply) Send(message string) {
|
||||
checkSendErr(r.bot.Send(r.session.Chat, message))
|
||||
}
|
||||
|
@ -71,8 +70,12 @@ func (r *TelegramReply) Message(message string) {
|
|||
r.set = true
|
||||
}
|
||||
|
||||
func (r *TelegramReply) RequireTextInput(title, message string, textFields ...TextField) {
|
||||
r.message = message
|
||||
func (r *TelegramReply) Choose(prompt string, options ...Option) {
|
||||
|
||||
}
|
||||
|
||||
func (r *TelegramReply) InputText(prompt string, textFields ...TextField) {
|
||||
r.message = prompt
|
||||
}
|
||||
|
||||
func (r *TelegramReply) RemoveKeyboard() {
|
||||
|
@ -82,17 +85,16 @@ func (r *TelegramReply) RemoveKeyboard() {
|
|||
|
||||
func (r *TelegramReply) AddButton(text string, name string, value string) {
|
||||
var button = r.menu.Text(text)
|
||||
if len(r.buttons) == 0 {
|
||||
r.buttons = append(r.buttons, []telebot.Btn{})
|
||||
}
|
||||
r.buttons[len(r.buttons)-1] = append(r.buttons[len(r.buttons)-1], button)
|
||||
r.buttons = append(r.buttons, button)
|
||||
r.set = true
|
||||
}
|
||||
|
||||
func (r *TelegramReply) build() {
|
||||
var rows []telebot.Row
|
||||
for _, buttons := range r.buttons {
|
||||
rows = append(rows, telebot.Row(buttons))
|
||||
for _, button := range r.buttons {
|
||||
rows = append(rows, telebot.Row{
|
||||
button,
|
||||
})
|
||||
}
|
||||
r.menu.Reply(rows...)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user