diff --git a/i18n/en.json b/i18n/en.json index 17f1ba7c80..c730f57117 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2351,6 +2351,10 @@ "id": "model.outgoing_hook.is_valid.token.app_error", "translation": "Invalid token" }, + { + "id": "model.outgoing_hook.is_valid.trigger_words.app_error", + "translation": "Invalid trigger words" + }, { "id": "model.outgoing_hook.is_valid.update_at.app_error", "translation": "Update at must be a valid time" diff --git a/model/outgoing_webhook.go b/model/outgoing_webhook.go index e13de90800..ef1807e7aa 100644 --- a/model/outgoing_webhook.go +++ b/model/outgoing_webhook.go @@ -98,6 +98,14 @@ func (o *OutgoingWebhook) IsValid() *AppError { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "") } + if len(o.TriggerWords) != 0 { + for _, triggerWord := range o.TriggerWords { + if len(triggerWord) == 0 { + return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "") + } + } + } + if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "") } diff --git a/webapp/components/backstage/add_outgoing_webhook.jsx b/webapp/components/backstage/add_outgoing_webhook.jsx index acdd98ba8e..ff5e90e078 100644 --- a/webapp/components/backstage/add_outgoing_webhook.jsx +++ b/webapp/components/backstage/add_outgoing_webhook.jsx @@ -50,7 +50,18 @@ export default class AddOutgoingWebhook extends React.Component { clientError: '' }); - if (!this.state.channelId && !this.state.triggerWords) { + const triggerWords = []; + if (this.state.triggerWords) { + for (let triggerWord of this.state.triggerWords.split('\n')) { + triggerWord = triggerWord.trim(); + + if (triggerWord.length > 0) { + triggerWords.push(triggerWord); + } + } + } + + if (!this.state.channelId && triggerWords.length === 0) { this.setState({ saving: false, clientError: ( @@ -64,7 +75,16 @@ export default class AddOutgoingWebhook extends React.Component { return; } - if (!this.state.callbackUrls) { + const callbackUrls = []; + for (let callbackUrl of this.state.callbackUrls.split('\n')) { + callbackUrl = callbackUrl.trim(); + + if (callbackUrl.length > 0) { + callbackUrls.push(callbackUrl); + } + } + + if (callbackUrls.length === 0) { this.setState({ saving: false, clientError: ( @@ -80,8 +100,8 @@ export default class AddOutgoingWebhook extends React.Component { const hook = { channel_id: this.state.channelId, - trigger_words: this.state.triggerWords.split('\n').map((word) => word.trim()), - callback_urls: this.state.callbackUrls.split('\n').map((url) => url.trim()), + trigger_words: triggerWords, + callback_urls: callbackUrls, display_name: this.state.displayName, description: this.state.description }; diff --git a/webapp/components/backstage/installed_command.jsx b/webapp/components/backstage/installed_command.jsx index 8b56ed5950..c0c34bc78e 100644 --- a/webapp/components/backstage/installed_command.jsx +++ b/webapp/components/backstage/installed_command.jsx @@ -78,6 +78,11 @@ export default class InstalledCommand extends React.Component { ); } + let trigger = '- /' + command.trigger; + if (command.auto_complete && command.auto_complete_hint) { + trigger += ' ' + command.auto_complete_hint; + } + return (