func (a *Accessory) UnmarshalJSON(data []byte) error {
	var r json.RawMessage
	if string(data) == "{\"accessory\":null}" {
		return nil
	}
	err := json.Unmarshal(data, &r)
	if err != nil {
		return err
	}
	s := sumtype{}
	err = json.Unmarshal(r, &s)
	if err != nil {
		return err
	}
	var blockElementType string
	if s.TypeVal != "" {
		blockElementType = s.TypeVal
	}
	switch blockElementType {
	case "image":
		element, err := unmarshalBlockElement(r, &ImageBlockElement{})
		if err != nil {
			return err
		}
		a.ImageElement = element.(*ImageBlockElement)
	case "button":
		element, err := unmarshalBlockElement(r, &ButtonBlockElement{})
		if err != nil {
			return err
		}
		a.ButtonElement = element.(*ButtonBlockElement)
	case "overflow":
		element, err := unmarshalBlockElement(r, &OverflowBlockElement{})
		if err != nil {
			return err
		}
		a.OverflowElement = element.(*OverflowBlockElement)
	case "datepicker":
		element, err := unmarshalBlockElement(r, &DatePickerBlockElement{})
		if err != nil {
			return err
		}
		a.DatePickerElement = element.(*DatePickerBlockElement)
	case "plain_text_input":
		element, err := unmarshalBlockElement(r, &PlainTextInputBlockElement{})
		if err != nil {
			return err
		}
		a.PlainTextInputElement = element.(*PlainTextInputBlockElement)
	case "radio_buttons":
		element, err := unmarshalBlockElement(r, &RadioButtonsBlockElement{})
		if err != nil {
			return err
		}
		a.RadioButtonsElement = element.(*RadioButtonsBlockElement)
	case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
		element, err := unmarshalBlockElement(r, &SelectBlockElement{})
		if err != nil {
			return err
		}
		a.SelectElement = element.(*SelectBlockElement)
	case "multi_static_select", "multi_external_select", "multi_users_select", "multi_conversations_select", "multi_channels_select":
		element, err := unmarshalBlockElement(r, &MultiSelectBlockElement{})
		if err != nil {
			return err
		}
		a.MultiSelectElement = element.(*MultiSelectBlockElement)
	default:
		element, err := unmarshalBlockElement(r, &UnknownBlockElement{})
		if err != nil {
			return err
		}
		a.UnknownElement = element.(*UnknownBlockElement)
	}
	return nil
}
UnmarshalJSON implements the Unmarshaller interface for Accessory, so that any JSON
unmarshalling is delegated and proper type determination can be made before unmarshal
package slack
import (
	"encoding/json"
	"github.com/pkg/errors"
)
type sumtype struct {
	TypeVal string `json:"type"`
}
func (b Blocks) MarshalJSON() ([]byte, error) {
	bytes, err := json.Marshal(b.BlockSet)
	if err != nil {
		return nil, err
	}
	return bytes, nil
}
func (b *Blocks) UnmarshalJSON(data []byte) error {
	var raw []json.RawMessage
	if string(data) == "{}" {
		return nil
	}
	err := json.Unmarshal(data, &raw)
	if err != nil {
		return err
	}
	var blocks Blocks
	for _, r := range raw {
		s := sumtype{}
		err := json.Unmarshal(r, &s)
		if err != nil {
			return err
		}
		var blockType string
		if s.TypeVal != "" {
			blockType = s.TypeVal
		}
		var block Block
		switch blockType {
		case "actions":
			block = &ActionBlock{}
		case "context":
			block = &ContextBlock{}
		case "divider":
			block = &DividerBlock{}
		case "file":
			block = &FileBlock{}
		case "image":
			block = &ImageBlock{}
		case "input":
			block = &InputBlock{}
		case "section":
			block = &SectionBlock{}
		default:
			block = &UnknownBlock{}
		}
		err = json.Unmarshal(r, block)
		if err != nil {
			return err
		}
		blocks.BlockSet = append(blocks.BlockSet, block)
	}
	*b = blocks
	return nil
}
func (b *InputBlock) UnmarshalJSON(data []byte) error {
	type alias InputBlock
	a := struct {
		Element json.RawMessage `json:"element"`
		*alias
	}{
		alias: (*alias)(b),
	}
	if err := json.Unmarshal(data, &a); err != nil {
		return err
	}
	s := sumtype{}
	if err := json.Unmarshal(a.Element, &s); err != nil {
		return nil
	}
	var e BlockElement
	switch s.TypeVal {
	case "datepicker":
		e = &DatePickerBlockElement{}
	case "plain_text_input":
		e = &PlainTextInputBlockElement{}
	case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
		e = &SelectBlockElement{}
	case "multi_static_select", "multi_external_select", "multi_users_select", "multi_conversations_select", "multi_channels_select":
		e = &MultiSelectBlockElement{}
	default:
		return errors.New("unsupported block element type")
	}
	if err := json.Unmarshal(a.Element, e); err != nil {
		return err
	}
	b.Element = e
	return nil
}
func (b *BlockElements) MarshalJSON() ([]byte, error) {
	bytes, err := json.Marshal(b.ElementSet)
	if err != nil {
		return nil, err
	}
	return bytes, nil
}
func (b *BlockElements) UnmarshalJSON(data []byte) error {
	var raw []json.RawMessage
	if string(data) == "{}" {
		return nil
	}
	err := json.Unmarshal(data, &raw)
	if err != nil {
		return err
	}
	var blockElements BlockElements
	for _, r := range raw {
		s := sumtype{}
		err := json.Unmarshal(r, &s)
		if err != nil {
			return err
		}
		var blockElementType string
		if s.TypeVal != "" {
			blockElementType = s.TypeVal
		}
		var blockElement BlockElement
		switch blockElementType {
		case "image":
			blockElement = &ImageBlockElement{}
		case "button":
			blockElement = &ButtonBlockElement{}
		case "overflow":
			blockElement = &OverflowBlockElement{}
		case "datepicker":
			blockElement = &DatePickerBlockElement{}
		case "plain_text_input":
			blockElement = &PlainTextInputBlockElement{}
		case "static_select", "external_select", "users_select", "conversations_select", "channels_select":
			blockElement = &SelectBlockElement{}
		default:
			return errors.New("unsupported block element type")
		}
		err = json.Unmarshal(r, blockElement)
		if err != nil {
			return err
		}
		blockElements.ElementSet = append(blockElements.ElementSet, blockElement)
	}
	*b = blockElements
	return nil
}
func (a *Accessory) MarshalJSON() ([]byte, error) {
	bytes, err := json.Marshal(toBlockElement(a))
	if err != nil {
		return nil, err
	}
	return bytes, nil
}