github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/model/outgoing_webhook.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package model
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"net/http"
    11  	"net/url"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  type OutgoingWebhook struct {
    17  	Id           string      `json:"id"`
    18  	Token        string      `json:"token"`
    19  	CreateAt     int64       `json:"create_at"`
    20  	UpdateAt     int64       `json:"update_at"`
    21  	DeleteAt     int64       `json:"delete_at"`
    22  	CreatorId    string      `json:"creator_id"`
    23  	ChannelId    string      `json:"channel_id"`
    24  	TeamId       string      `json:"team_id"`
    25  	TriggerWords StringArray `json:"trigger_words"`
    26  	TriggerWhen  int         `json:"trigger_when"`
    27  	CallbackURLs StringArray `json:"callback_urls"`
    28  	DisplayName  string      `json:"display_name"`
    29  	Description  string      `json:"description"`
    30  	ContentType  string      `json:"content_type"`
    31  	Username     string      `json:"username"`
    32  	IconURL      string      `json:"icon_url"`
    33  }
    34  
    35  type OutgoingWebhookPayload struct {
    36  	Token       string `json:"token"`
    37  	TeamId      string `json:"team_id"`
    38  	TeamDomain  string `json:"team_domain"`
    39  	ChannelId   string `json:"channel_id"`
    40  	ChannelName string `json:"channel_name"`
    41  	Timestamp   int64  `json:"timestamp"`
    42  	UserId      string `json:"user_id"`
    43  	UserName    string `json:"user_name"`
    44  	PostId      string `json:"post_id"`
    45  	Text        string `json:"text"`
    46  	TriggerWord string `json:"trigger_word"`
    47  	FileIds     string `json:"file_ids"`
    48  }
    49  
    50  type OutgoingWebhookResponse struct {
    51  	Text         *string            `json:"text"`
    52  	Username     string             `json:"username"`
    53  	IconURL      string             `json:"icon_url"`
    54  	Props        StringInterface    `json:"props"`
    55  	Attachments  []*SlackAttachment `json:"attachments"`
    56  	Type         string             `json:"type"`
    57  	ResponseType string             `json:"response_type"`
    58  }
    59  
    60  const OUTGOING_HOOK_RESPONSE_TYPE_COMMENT = "comment"
    61  
    62  func (o *OutgoingWebhookPayload) ToJSON() string {
    63  	b, _ := json.Marshal(o)
    64  	return string(b)
    65  }
    66  
    67  func (o *OutgoingWebhookPayload) ToFormValues() string {
    68  	v := url.Values{}
    69  	v.Set("token", o.Token)
    70  	v.Set("team_id", o.TeamId)
    71  	v.Set("team_domain", o.TeamDomain)
    72  	v.Set("channel_id", o.ChannelId)
    73  	v.Set("channel_name", o.ChannelName)
    74  	v.Set("timestamp", strconv.FormatInt(o.Timestamp/1000, 10))
    75  	v.Set("user_id", o.UserId)
    76  	v.Set("user_name", o.UserName)
    77  	v.Set("post_id", o.PostId)
    78  	v.Set("text", o.Text)
    79  	v.Set("trigger_word", o.TriggerWord)
    80  	v.Set("file_ids", o.FileIds)
    81  
    82  	return v.Encode()
    83  }
    84  
    85  func (o *OutgoingWebhook) ToJson() string {
    86  	b, _ := json.Marshal(o)
    87  	return string(b)
    88  }
    89  
    90  func OutgoingWebhookFromJson(data io.Reader) *OutgoingWebhook {
    91  	var o *OutgoingWebhook
    92  	json.NewDecoder(data).Decode(&o)
    93  	return o
    94  }
    95  
    96  func OutgoingWebhookListToJson(l []*OutgoingWebhook) string {
    97  	b, _ := json.Marshal(l)
    98  	return string(b)
    99  }
   100  
   101  func OutgoingWebhookListFromJson(data io.Reader) []*OutgoingWebhook {
   102  	var o []*OutgoingWebhook
   103  	json.NewDecoder(data).Decode(&o)
   104  	return o
   105  }
   106  
   107  func (o *OutgoingWebhookResponse) ToJson() string {
   108  	b, _ := json.Marshal(o)
   109  	return string(b)
   110  }
   111  
   112  func OutgoingWebhookResponseFromJson(data io.Reader) (*OutgoingWebhookResponse, error) {
   113  	var o *OutgoingWebhookResponse
   114  	err := json.NewDecoder(data).Decode(&o)
   115  	if err == io.EOF {
   116  		return nil, nil
   117  	}
   118  	return o, err
   119  }
   120  
   121  func (o *OutgoingWebhook) IsValid() *AppError {
   122  
   123  	if !IsValidId(o.Id) {
   124  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "", http.StatusBadRequest)
   125  	}
   126  
   127  	if len(o.Token) != 26 {
   128  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.token.app_error", nil, "", http.StatusBadRequest)
   129  	}
   130  
   131  	if o.CreateAt == 0 {
   132  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   133  	}
   134  
   135  	if o.UpdateAt == 0 {
   136  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest)
   137  	}
   138  
   139  	if !IsValidId(o.CreatorId) {
   140  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
   141  	}
   142  
   143  	if len(o.ChannelId) != 0 && !IsValidId(o.ChannelId) {
   144  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
   145  	}
   146  
   147  	if !IsValidId(o.TeamId) {
   148  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "", http.StatusBadRequest)
   149  	}
   150  
   151  	if len(fmt.Sprintf("%s", o.TriggerWords)) > 1024 {
   152  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "", http.StatusBadRequest)
   153  	}
   154  
   155  	if len(o.TriggerWords) != 0 {
   156  		for _, triggerWord := range o.TriggerWords {
   157  			if len(triggerWord) == 0 {
   158  				return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "", http.StatusBadRequest)
   159  			}
   160  		}
   161  	}
   162  
   163  	if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 {
   164  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "", http.StatusBadRequest)
   165  	}
   166  
   167  	for _, callback := range o.CallbackURLs {
   168  		if !IsValidHttpUrl(callback) {
   169  			return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.url.app_error", nil, "", http.StatusBadRequest)
   170  		}
   171  	}
   172  
   173  	if len(o.DisplayName) > 64 {
   174  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "", http.StatusBadRequest)
   175  	}
   176  
   177  	if len(o.Description) > 500 {
   178  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "", http.StatusBadRequest)
   179  	}
   180  
   181  	if len(o.ContentType) > 128 {
   182  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest)
   183  	}
   184  
   185  	if o.TriggerWhen > 1 {
   186  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest)
   187  	}
   188  
   189  	if len(o.Username) > 64 {
   190  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.username.app_error", nil, "", http.StatusBadRequest)
   191  	}
   192  
   193  	if len(o.IconURL) > 1024 {
   194  		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.icon_url.app_error", nil, "", http.StatusBadRequest)
   195  	}
   196  
   197  	return nil
   198  }
   199  
   200  func (o *OutgoingWebhook) PreSave() {
   201  	if o.Id == "" {
   202  		o.Id = NewId()
   203  	}
   204  
   205  	if o.Token == "" {
   206  		o.Token = NewId()
   207  	}
   208  
   209  	o.CreateAt = GetMillis()
   210  	o.UpdateAt = o.CreateAt
   211  }
   212  
   213  func (o *OutgoingWebhook) PreUpdate() {
   214  	o.UpdateAt = GetMillis()
   215  }
   216  
   217  func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool {
   218  	if len(word) == 0 {
   219  		return false
   220  	}
   221  
   222  	for _, trigger := range o.TriggerWords {
   223  		if trigger == word {
   224  			return true
   225  		}
   226  	}
   227  
   228  	return false
   229  }
   230  
   231  func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool {
   232  	if len(word) == 0 {
   233  		return false
   234  	}
   235  
   236  	for _, trigger := range o.TriggerWords {
   237  		if strings.HasPrefix(word, trigger) {
   238  			return true
   239  		}
   240  	}
   241  
   242  	return false
   243  }
   244  
   245  func (o *OutgoingWebhook) GetTriggerWord(word string, isExactMatch bool) (triggerWord string) {
   246  	if len(word) == 0 {
   247  		return
   248  	}
   249  
   250  	if isExactMatch {
   251  		for _, trigger := range o.TriggerWords {
   252  			if trigger == word {
   253  				triggerWord = trigger
   254  				break
   255  			}
   256  		}
   257  	} else {
   258  		for _, trigger := range o.TriggerWords {
   259  			if strings.HasPrefix(word, trigger) {
   260  				triggerWord = trigger
   261  				break
   262  			}
   263  		}
   264  	}
   265  
   266  	return triggerWord
   267  }