summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/post.go15
-rw-r--r--model/outgoing_webhook.go20
-rw-r--r--model/outgoing_webhook_test.go11
-rw-r--r--store/sql_webhook_store.go2
-rw-r--r--webapp/components/integrations/components/add_outgoing_webhook.jsx44
-rw-r--r--webapp/components/integrations/components/installed_outgoing_webhook.jsx30
-rw-r--r--webapp/i18n/en.json4
-rw-r--r--webapp/sass/routes/_backstage.scss1
8 files changed, 123 insertions, 4 deletions
diff --git a/api/post.go b/api/post.go
index 9bf6cff40..c363ff076 100644
--- a/api/post.go
+++ b/api/post.go
@@ -25,6 +25,11 @@ import (
"github.com/mattermost/platform/utils"
)
+const (
+ TRIGGERWORDS_FULL = 0
+ TRIGGERWORDS_STARTSWITH = 1
+)
+
func InitPost() {
l4g.Debug(utils.T("api.post.init.debug"))
@@ -383,12 +388,14 @@ func handleWebhookEvents(c *Context, post *model.Post, team *model.Team, channel
relevantHooks := []*model.OutgoingWebhook{}
for _, hook := range hooks {
- if hook.ChannelId == post.ChannelId {
- if len(hook.TriggerWords) == 0 || hook.HasTriggerWord(firstWord) {
+ if hook.ChannelId == post.ChannelId || len(hook.ChannelId) == 0 {
+ if hook.ChannelId == post.ChannelId && len(hook.TriggerWords) == 0 {
+ relevantHooks = append(relevantHooks, hook)
+ } else if hook.TriggerWhen == TRIGGERWORDS_FULL && hook.HasTriggerWord(firstWord) {
+ relevantHooks = append(relevantHooks, hook)
+ } else if hook.TriggerWhen == TRIGGERWORDS_STARTSWITH && hook.TriggerWordStartsWith(firstWord) {
relevantHooks = append(relevantHooks, hook)
}
- } else if len(hook.ChannelId) == 0 && hook.HasTriggerWord(firstWord) {
- relevantHooks = append(relevantHooks, hook)
}
}
diff --git a/model/outgoing_webhook.go b/model/outgoing_webhook.go
index ee7a32f1f..ec2ed75c7 100644
--- a/model/outgoing_webhook.go
+++ b/model/outgoing_webhook.go
@@ -9,6 +9,7 @@ import (
"io"
"net/url"
"strconv"
+ "strings"
)
type OutgoingWebhook struct {
@@ -21,6 +22,7 @@ type OutgoingWebhook struct {
ChannelId string `json:"channel_id"`
TeamId string `json:"team_id"`
TriggerWords StringArray `json:"trigger_words"`
+ TriggerWhen int `json:"trigger_when"`
CallbackURLs StringArray `json:"callback_urls"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
@@ -171,6 +173,10 @@ func (o *OutgoingWebhook) IsValid() *AppError {
return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "")
}
+ if o.TriggerWhen > 1 {
+ return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "")
+ }
+
return nil
}
@@ -204,3 +210,17 @@ func (o *OutgoingWebhook) HasTriggerWord(word string) bool {
return false
}
+
+func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool {
+ if len(o.TriggerWords) == 0 || len(word) == 0 {
+ return false
+ }
+
+ for _, trigger := range o.TriggerWords {
+ if strings.HasPrefix(word, trigger) {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/model/outgoing_webhook_test.go b/model/outgoing_webhook_test.go
index 24b81d221..2458c62e4 100644
--- a/model/outgoing_webhook_test.go
+++ b/model/outgoing_webhook_test.go
@@ -163,3 +163,14 @@ func TestOutgoingWebhookPreUpdate(t *testing.T) {
o := OutgoingWebhook{}
o.PreUpdate()
}
+
+func TestOutgoingWebhookTriggerWordStartsWith(t *testing.T) {
+ o := OutgoingWebhook{Id: NewId()}
+ o.TriggerWords = append(o.TriggerWords, "foo")
+ if !o.TriggerWordStartsWith("foobar") {
+ t.Fatal("Should return true")
+ }
+ if o.TriggerWordStartsWith("barfoo") {
+ t.Fatal("Should return false")
+ }
+}
diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go
index 72897771d..74432b541 100644
--- a/store/sql_webhook_store.go
+++ b/store/sql_webhook_store.go
@@ -34,6 +34,7 @@ func NewSqlWebhookStore(sqlStore *SqlStore) WebhookStore {
tableo.ColMap("DisplayName").SetMaxSize(64)
tableo.ColMap("Description").SetMaxSize(128)
tableo.ColMap("ContentType").SetMaxSize(128)
+ tableo.ColMap("TriggerWhen").SetMaxSize(1)
}
return s
@@ -46,6 +47,7 @@ func (s SqlWebhookStore) UpgradeSchemaIfNeeded() {
s.CreateColumnIfNotExists("OutgoingWebhooks", "DisplayName", "varchar(64)", "varchar(64)", "")
s.CreateColumnIfNotExists("OutgoingWebhooks", "Description", "varchar(128)", "varchar(128)", "")
s.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "")
+ s.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "tinyint", "0")
}
func (s SqlWebhookStore) CreateIndexesIfNotExists() {
diff --git a/webapp/components/integrations/components/add_outgoing_webhook.jsx b/webapp/components/integrations/components/add_outgoing_webhook.jsx
index d6c0242a5..6f9750a90 100644
--- a/webapp/components/integrations/components/add_outgoing_webhook.jsx
+++ b/webapp/components/integrations/components/add_outgoing_webhook.jsx
@@ -29,6 +29,7 @@ export default class AddOutgoingWebhook extends React.Component {
this.updateContentType = this.updateContentType.bind(this);
this.updateChannelId = this.updateChannelId.bind(this);
this.updateTriggerWords = this.updateTriggerWords.bind(this);
+ this.updateTriggerWhen = this.updateTriggerWhen.bind(this);
this.updateCallbackUrls = this.updateCallbackUrls.bind(this);
this.state = {
@@ -37,6 +38,7 @@ export default class AddOutgoingWebhook extends React.Component {
contentType: 'application/x-www-form-urlencoded',
channelId: '',
triggerWords: '',
+ triggerWhen: 0,
callbackUrls: '',
saving: false,
serverError: '',
@@ -108,6 +110,7 @@ export default class AddOutgoingWebhook extends React.Component {
const hook = {
channel_id: this.state.channelId,
trigger_words: triggerWords,
+ trigger_when: parseInt(this.state.triggerWhen, 10),
callback_urls: callbackUrls,
display_name: this.state.displayName,
content_type: this.state.contentType,
@@ -158,6 +161,12 @@ export default class AddOutgoingWebhook extends React.Component {
});
}
+ updateTriggerWhen(e) {
+ this.setState({
+ triggerWhen: e.target.value
+ });
+ }
+
updateCallbackUrls(e) {
this.setState({
callbackUrls: e.target.value
@@ -300,6 +309,41 @@ export default class AddOutgoingWebhook extends React.Component {
<div className='form-group'>
<label
className='control-label col-sm-4'
+ htmlFor='triggerWords'
+ >
+ <FormattedMessage
+ id='add_outgoing_webhook.triggerWordsTriggerWhen'
+ defaultMessage='Trigger When'
+ />
+ </label>
+ <div className='col-md-5 col-sm-8'>
+ <select
+ className='form-control'
+ value={this.state.triggerWhen}
+ onChange={this.updateTriggerWhen}
+ >
+ <option
+ value='0'
+ >
+ <FormattedMessage
+ id='add_outgoing_webhook.triggerWordsTriggerWhenFullWord'
+ defaultMessage='First word matches a trigger word exactly'
+ />
+ </option>
+ <option
+ value='1'
+ >
+ <FormattedMessage
+ id='add_outgoing_webhook.triggerWordsTriggerWhenStartsWith'
+ defaultMessage='First word starts with a trigger word'
+ />
+ </option>
+ </select>
+ </div>
+ </div>
+ <div className='form-group'>
+ <label
+ className='control-label col-sm-4'
htmlFor='callbackUrls'
>
<FormattedMessage
diff --git a/webapp/components/integrations/components/installed_outgoing_webhook.jsx b/webapp/components/integrations/components/installed_outgoing_webhook.jsx
index 852231823..4b478255c 100644
--- a/webapp/components/integrations/components/installed_outgoing_webhook.jsx
+++ b/webapp/components/integrations/components/installed_outgoing_webhook.jsx
@@ -66,6 +66,8 @@ export default class InstalledOutgoingWebhook extends React.Component {
const outgoingWebhook = this.props.outgoingWebhook;
const channel = ChannelStore.get(outgoingWebhook.channel_id);
const filter = this.props.filter ? this.props.filter.toLowerCase() : '';
+ const triggerWordsFull = 0;
+ const triggerWordsStartsWith = 1;
if (!this.matchesFilter(outgoingWebhook, channel, filter)) {
return null;
@@ -127,6 +129,23 @@ export default class InstalledOutgoingWebhook extends React.Component {
</div>
);
+ let triggerWhen;
+ if (outgoingWebhook.trigger_when === triggerWordsFull) {
+ triggerWhen = (
+ <FormattedMessage
+ id='add_outgoing_webhook.triggerWordsTriggerWhenFullWord'
+ defaultMessage='First word matches a trigger word exactly'
+ />
+ );
+ } else if (outgoingWebhook.trigger_when === triggerWordsStartsWith) {
+ triggerWhen = (
+ <FormattedMessage
+ id='add_outgoing_webhook.triggerWordsTriggerWhenStartsWith'
+ defaultMessage='First word starts with a trigger word'
+ />
+ );
+ }
+
return (
<div className='backstage-list__item'>
<div className='item-details'>
@@ -149,6 +168,17 @@ export default class InstalledOutgoingWebhook extends React.Component {
</div>
{triggerWords}
<div className='item-details__row'>
+ <span className='item-details__trigger-when'>
+ <FormattedMessage
+ id='installed_integrations.triggerWhen'
+ defaultMessage='Trigger When: {triggerWhen}'
+ values={{
+ triggerWhen
+ }}
+ />
+ </span>
+ </div>
+ <div className='item-details__row'>
<span className='item-details__token'>
<FormattedMessage
id='installed_integrations.token'
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 371f471cd..1b13a1c59 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -98,6 +98,9 @@
"add_outgoing_webhook.save": "Save",
"add_outgoing_webhook.triggerWords": "Trigger Words (One Per Line)",
"add_outgoing_webhook.triggerWordsOrChannelRequired": "A valid channel or a list of trigger words is required",
+ "add_outgoing_webhook.triggerWordsTriggerWhen": "Trigger When",
+ "add_outgoing_webhook.triggerWordsTriggerWhenFullWord": "First word matches a trigger word exactly",
+ "add_outgoing_webhook.triggerWordsTriggerWhenStartsWith": "First word starts with a trigger word",
"admin.audits.reload": "Reload User Activity Logs",
"admin.audits.title": "User Activity Logs",
"admin.authentication.email": "Email Auth",
@@ -1109,6 +1112,7 @@
"installed_integrations.regenToken": "Regenerate Token",
"installed_integrations.token": "Token: {token}",
"installed_integrations.triggerWords": "Trigger Words: {triggerWords}",
+ "installed_integrations.triggerWhen": "Trigger When: {triggerWhen}",
"installed_integrations.url": "URL: {url}",
"installed_outgoing_webhooks.add": "Add Outgoing Webhook",
"installed_outgoing_webhooks.empty": "No outgoing webhooks found",
diff --git a/webapp/sass/routes/_backstage.scss b/webapp/sass/routes/_backstage.scss
index 5edba2660..4b8c6ff6c 100644
--- a/webapp/sass/routes/_backstage.scss
+++ b/webapp/sass/routes/_backstage.scss
@@ -247,6 +247,7 @@
.item-details__content_type,
.item-details__token,
.item-details__trigger-words,
+ .item-details__trigger-when,
.item-details__url,
.item-details__creation {
display: inline-block;