forked from lug/matterbridge
		
	
		
			
				
	
	
		
			157 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package slack
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
)
 | 
						|
 | 
						|
// InteractionType type of interactions
 | 
						|
type InteractionType string
 | 
						|
 | 
						|
// ActionType type represents the type of action (attachment, block, etc.)
 | 
						|
type actionType string
 | 
						|
 | 
						|
// action is an interface that should be implemented by all callback action types
 | 
						|
type action interface {
 | 
						|
	actionType() actionType
 | 
						|
}
 | 
						|
 | 
						|
// Types of interactions that can be received.
 | 
						|
const (
 | 
						|
	InteractionTypeDialogCancellation = InteractionType("dialog_cancellation")
 | 
						|
	InteractionTypeDialogSubmission   = InteractionType("dialog_submission")
 | 
						|
	InteractionTypeDialogSuggestion   = InteractionType("dialog_suggestion")
 | 
						|
	InteractionTypeInteractionMessage = InteractionType("interactive_message")
 | 
						|
	InteractionTypeMessageAction      = InteractionType("message_action")
 | 
						|
	InteractionTypeBlockActions       = InteractionType("block_actions")
 | 
						|
	InteractionTypeBlockSuggestion    = InteractionType("block_suggestion")
 | 
						|
	InteractionTypeViewSubmission     = InteractionType("view_submission")
 | 
						|
	InteractionTypeViewClosed         = InteractionType("view_closed")
 | 
						|
)
 | 
						|
 | 
						|
// InteractionCallback is sent from slack when a user interactions with a button or dialog.
 | 
						|
type InteractionCallback struct {
 | 
						|
	Type            InteractionType `json:"type"`
 | 
						|
	Token           string          `json:"token"`
 | 
						|
	CallbackID      string          `json:"callback_id"`
 | 
						|
	ResponseURL     string          `json:"response_url"`
 | 
						|
	TriggerID       string          `json:"trigger_id"`
 | 
						|
	ActionTs        string          `json:"action_ts"`
 | 
						|
	Team            Team            `json:"team"`
 | 
						|
	Channel         Channel         `json:"channel"`
 | 
						|
	User            User            `json:"user"`
 | 
						|
	OriginalMessage Message         `json:"original_message"`
 | 
						|
	Message         Message         `json:"message"`
 | 
						|
	Name            string          `json:"name"`
 | 
						|
	Value           string          `json:"value"`
 | 
						|
	MessageTs       string          `json:"message_ts"`
 | 
						|
	AttachmentID    string          `json:"attachment_id"`
 | 
						|
	ActionCallback  ActionCallbacks `json:"actions"`
 | 
						|
	View            View            `json:"view"`
 | 
						|
	ActionID        string          `json:"action_id"`
 | 
						|
	APIAppID        string          `json:"api_app_id"`
 | 
						|
	BlockID         string          `json:"block_id"`
 | 
						|
	Container       Container       `json:"container"`
 | 
						|
	DialogSubmissionCallback
 | 
						|
	ViewSubmissionCallback
 | 
						|
	ViewClosedCallback
 | 
						|
}
 | 
						|
 | 
						|
type Container struct {
 | 
						|
	Type   string `json:"type"`
 | 
						|
	ViewID string `json:"view_id"`
 | 
						|
}
 | 
						|
 | 
						|
// ActionCallback is a convenience struct defined to allow dynamic unmarshalling of
 | 
						|
// the "actions" value in Slack's JSON response, which varies depending on block type
 | 
						|
type ActionCallbacks struct {
 | 
						|
	AttachmentActions []*AttachmentAction
 | 
						|
	BlockActions      []*BlockAction
 | 
						|
}
 | 
						|
 | 
						|
// MarshalJSON implements the Marshaller interface in order to combine both
 | 
						|
// action callback types back into a single array, like how the api responds.
 | 
						|
// This makes Marshaling and Unmarshaling an InteractionCallback symmetrical
 | 
						|
func (a ActionCallbacks) MarshalJSON() ([]byte, error) {
 | 
						|
	count := 0
 | 
						|
	length := len(a.AttachmentActions) + len(a.BlockActions)
 | 
						|
	buffer := bytes.NewBufferString("[")
 | 
						|
 | 
						|
	f := func(obj interface{}) error {
 | 
						|
		js, err := json.Marshal(obj)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		_, err = buffer.Write(js)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		count++
 | 
						|
		if count < length {
 | 
						|
			_, err = buffer.WriteString(",")
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	for _, act := range a.AttachmentActions {
 | 
						|
		err := f(act)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	for _, blk := range a.BlockActions {
 | 
						|
		err := f(blk)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	buffer.WriteString("]")
 | 
						|
	return buffer.Bytes(), nil
 | 
						|
}
 | 
						|
 | 
						|
// UnmarshalJSON implements the Marshaller interface in order to delegate
 | 
						|
// marshalling and allow for proper type assertion when decoding the response
 | 
						|
func (a *ActionCallbacks) UnmarshalJSON(data []byte) error {
 | 
						|
	var raw []json.RawMessage
 | 
						|
	err := json.Unmarshal(data, &raw)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	for _, r := range raw {
 | 
						|
		var obj map[string]interface{}
 | 
						|
		err := json.Unmarshal(r, &obj)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		if _, ok := obj["block_id"].(string); ok {
 | 
						|
			action, err := unmarshalAction(r, &BlockAction{})
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			a.BlockActions = append(a.BlockActions, action.(*BlockAction))
 | 
						|
			return nil
 | 
						|
		}
 | 
						|
 | 
						|
		action, err := unmarshalAction(r, &AttachmentAction{})
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		a.AttachmentActions = append(a.AttachmentActions, action.(*AttachmentAction))
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func unmarshalAction(r json.RawMessage, callbackAction action) (action, error) {
 | 
						|
	err := json.Unmarshal(r, callbackAction)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return callbackAction, nil
 | 
						|
}
 |