package retailcrm import ( "encoding/json" "errors" "fmt" ) const ( // TemplateItemTypeText is a type for text chunk in template. TemplateItemTypeText uint8 = iota // TemplateItemTypeVar is a type for variable in template. TemplateItemTypeVar QuickReply ButtonType = "QUICK_REPLY" PhoneNumber ButtonType = "PHONE_NUMBER" URL ButtonType = "URL" ) const ( // TemplateVarCustom is a custom variable type. TemplateVarCustom = "custom" // TemplateVarName is a name variable type. TemplateVarName = "name" // TemplateVarFirstName is a first name variable type. TemplateVarFirstName = "first_name" // TemplateVarLastName is a last name variable type. TemplateVarLastName = "last_name" ) // templateVarAssoc for checking variable validity, only for internal use. var templateVarAssoc = map[string]interface{}{ TemplateVarCustom: nil, TemplateVarName: nil, TemplateVarFirstName: nil, TemplateVarLastName: nil, } type Text struct { Parts []TextTemplateItem `json:"parts"` Example []string `json:"example,omitempty"` } type Media struct { Example string `json:"example,omitempty"` } type Header struct { Text *Text `json:"text,omitempty"` Document *Media `json:"document,omitempty"` Image *Media `json:"image,omitempty"` Video *Media `json:"video,omitempty"` } type TemplateItemList []TextTemplateItem // TextTemplateItem is a part of template. type TextTemplateItem struct { Text string VarType string Type uint8 } // MarshalJSON controls how TextTemplateItem will be marshaled into JSON. func (t TextTemplateItem) MarshalJSON() ([]byte, error) { switch t.Type { case TemplateItemTypeText: return json.Marshal(t.Text) case TemplateItemTypeVar: return json.Marshal(map[string]interface{}{ "var": t.VarType, }) } return nil, errors.New("unknown TextTemplateItem type") } // UnmarshalJSON will correctly unmarshal TextTemplateItem. func (t *TextTemplateItem) UnmarshalJSON(b []byte) error { var obj interface{} err := json.Unmarshal(b, &obj) if err != nil { return err } switch bodyPart := obj.(type) { case string: t.Type = TemplateItemTypeText t.Text = bodyPart case map[string]interface{}: // {} case if len(bodyPart) == 0 { t.Type = TemplateItemTypeText t.Text = "{}" return nil } if varTypeCurr, ok := bodyPart["var"].(string); ok { if _, ok := templateVarAssoc[varTypeCurr]; !ok { return fmt.Errorf("invalid placeholder var '%s'", varTypeCurr) } t.Type = TemplateItemTypeVar t.VarType = varTypeCurr } else { return errors.New("invalid TextTemplateItem") } default: return errors.New("invalid TextTemplateItem") } return nil } type ButtonType string type Button struct { Type ButtonType `json:"type"` URL string `json:"url,omitempty"` Text string `json:"text,omitempty"` PhoneNumber string `json:"phoneNumber,omitempty"` Example []string `json:"example,omitempty"` }