slack-go/slack

Receiving no payload on websocket based events

talaniz opened this issue · 2 comments

I'm not certain this is a bug, it seems more like maybe I'm not implementing something correctly. But I've been through the documentation and have been unable to find anything that directly talks about handling a slack interactive event over a websocket.

What happened

When I use websockets, I'm not receiving any data in response, just a slack.InteractionCallback with only the type populated.

Expected behavior

I would expect to receive a payload with the ActionID, Name, Value and Type messages populated. This is what I receive from the print statements in the code below:

2024/03/05 17:04:20 ******** Name: 
2024/03/05 17:04:20 The action called is 
2024/03/05 17:04:20 The response was of type: interactive_message
2024/03/05 17:04:20 ******** Channel Name: 
2024/03/05 17:04:20 ******** ResponseURL: https://hooks.slack.com/actions/T015M2ZDW58/6774396088240/b19qOY06tSeqf0LL5BisCkTZ
2024/03/05 17:04:20 ******** Value: 
2024/03/05 17:04:20 ******** Type: interactive_message
2024/03/05 17:04:20 ************{{       %!s(bool=false) [] [] %!s(*slack.Edited=<nil>)  %!s(bool=false) %!s(int=0)  %!s(bool=false)     %!s(*slack.Icon=<nil>) %!s(*slack.BotProfile=<nil>)      [] %!s(int=0) [] []   [] %!s(bool=false) %!s(*slack.Comment=<nil>)  %!s(int=0)  []  %!s(bool=false) %!s(bool=false) { map[]} {[]} } %!s(*slack.Msg=<nil>) %!s(*slack.Msg=<nil>)}
{"replace_original":false,"delete_original":false,"metadata":{"event_type":"","event_payload":null},"blocks":null}
**** {"replace_original":false,"delete_original":false,"metadata":{"event_type":"","event_payload":null},"blocks":null}socketmode: 2024/03/05 17:04:20 socket_mode_managed_conn.go:483: Scheduling Socket Mode response (error: <nil>) for envelope ID e436eaa0-4f17-41b3-bbb7-b22bf12baa97: {"envelope_id":"e436eaa0-4f17-41b3-bbb7-b22bf12baa97"}

Steps to reproduce

If I run a switch statement on the incoming socketClient.Events and print the various attributes, they should be populated. I'll include the code in the next section.

reproducible code

main.go

go func(ctx context.Context, client *slack.Client, socketClient *socketmode.Client) {
		for {
			select {
			case <-ctx.Done():
				log.Println("Shutting down socketmode listener")
				return
			case event := <-socketClient.Events:
				switch event.Type {
				// Slack events
				case socketmode.EventTypeEventsAPI:
					eventsApiEvent, ok := event.Data.(slackevents.EventsAPIEvent)
					if !ok {
						log.Printf("Could not type case the event to the EventsAPIEvent: %v\n", event)
						continue
					}
					log.Println("Received API event: ", event.Type)
					socketClient.Ack(*event.Request)
					err := handlers.HandleEventMessage(eventsApiEvent, client)
					if err != nil {
						log.Fatal(err)
					}
				// Slash command
				case socketmode.EventTypeSlashCommand:
					command, ok := event.Data.(slack.SlashCommand)
					if !ok {
						log.Printf("Could not type case the message to a SlashCommand: %v\n", command)
						continue
					}

					// consider removing the client parameter as it's unused
					payload, err := handlers.HandleSlashCommand(command, client)
					if err != nil {
						log.Fatal(err)
					}
					socketClient.Ack(*event.Request, payload)
				case socketmode.EventTypeInteractive:
					interaction, ok := event.Data.(slack.InteractionCallback)
					if !ok {
						log.Printf("Could not type cast the message to an Interaction callback: %v\n", interaction)
						continue
					}

					err := handlers.HandleInteractionEvent(interaction, client)
					if err != nil {
						log.Fatal(err)
					}
					socketClient.Ack(*event.Request)
				default:
					log.Println("****** Received Event: ", event)
				}
			}
		}

handlers.go

func handleIsArticleGood(command slack.SlashCommand, client *slack.Client) error {

	attachment := slack.Attachment{
		Pretext:    "pretext",
		Fallback:   "We don't currently support your client",
		CallbackID: "accept_or_reject",
		Color:      "#3AA3E3",
		Actions: []slack.AttachmentAction{
			slack.AttachmentAction{
				Name:  "accept",
				Text:  "Accept",
				Type:  "button",
				Value: "accept",
			},
			slack.AttachmentAction{
				Name:  "reject",
				Text:  "Reject",
				Type:  slack.ActionType("button"),
				Value: "reject",
				Style: "danger",
			},
		},
	}
	_, _, err := client.PostMessage(command.ChannelID, slack.MsgOptionAttachments(attachment))
	if err != nil {
		return fmt.Errorf("failed to post message: %w", err)
	}
	return nil
}

// HandleInteractionEvent determines actions for interactive event types
func HandleInteractionEvent(interaction slack.InteractionCallback, client *slack.Client) error {
	log.Printf("******** Name: %s\n", interaction.Name)
	log.Printf("The action called is %s\n", interaction.ActionID)
	log.Printf("The response was of type: %s\n", interaction.Type)
	log.Printf("******** Channel Name: %s\n", interaction.Message.Channel)
	log.Printf("******** ResponseURL: %s\n", interaction.ResponseURL)
	log.Printf("******** Value: %s\n", interaction.Value)
	log.Printf("******** Type: %s\n", interaction.Type)
	switch interaction.Type {
	case slack.InteractionTypeBlockActions:
		for _, action := range interaction.ActionCallback.BlockActions {
			log.Printf("%+v", action)
			log.Println("Selected option: ", action.SelectedOptions)
		}
	case slack.InteractionTypeInteractionMessage:
		log.Printf("************%s\n", interaction.Message)
		d, _ := json.Marshal(interaction.Message)
		fmt.Println(string(d))
		var payload slack.InteractionCallback
		err := json.Unmarshal([]byte(d), &payload)
		if err != nil {
			fmt.Printf("Could not parse action response JSON: %v", err)
		}
		fmt.Printf("**** %s", d)
	default:

	}
	return nil
}

Versions

  • Go: 1.21.0
  • slack-go/slack: v0.12.5

I suspect that it might be because of the Slack client I used looking at the example vs the tutorial I used. I'll try an example with the RTM client and follow up on this ticket.

Were you able to resolve this? I'm running into the same issue.