Skip to content

Commit 54ac38b

Browse files
committed
Merge branch 'release/2.2.0'
2 parents a9ac446 + d33aa10 commit 54ac38b

File tree

13 files changed

+159
-11
lines changed

13 files changed

+159
-11
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Release Notes for Webhooks for Craft CMS
22

3+
## 2.2.0 - 2019-07-29
4+
5+
### Added
6+
- Webhooks can now specify custom request headers. ([#12](https://github.com/craftcms/webhooks/issues/12))
7+
38
## 2.1.0 - 2019-07-26
49

510
### Added

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ class ArticleFilter implements FilterInterface
132132
}
133133
```
134134

135+
#### Sending Custom Headers
136+
137+
You can send custom headers along with webhook requests using the Custom Headers setting.
138+
139+
<img src="./images/custom-headers.png" width="696" height="292" alt="Screenshot of the Custom Headers setting">
140+
141+
Header values can be set to an environment variable using the `$VARIABLE_NAME` syntax, or a Twig template.
142+
143+
An `event` variable will be available to the Twig template, set to the event that triggered the webhook.
144+
145+
You can have multiple headers that have the same name, and if a header value takes up multiple lines (after any empty lines have been discarded), each line will be sent as its own header, all using the same header name.
146+
135147
#### Sending More Data
136148

137149
If you need more data than what’s in the default POST request payload, you can fill in the “Extra User Attributes”, “Extra Sender Attributes”, and “Extra Event Attributes” fields.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "craftcms/webhooks",
33
"description": "Post webhooks when events are triggered in Craft CMS.",
4-
"version": "2.1.0",
4+
"version": "2.2.0",
55
"type": "craft-plugin",
66
"keywords": [
77
"html",

images/custom-headers.png

17.4 KB
Loading

src/Plugin.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Plugin extends \craft\base\Plugin
7979
/**
8080
* @inheritdoc
8181
*/
82-
public $schemaVersion = '2.1.0';
82+
public $schemaVersion = '2.2.0';
8383

8484
// Public Methods
8585
// =========================================================================
@@ -118,10 +118,12 @@ public function init()
118118
}
119119
}
120120

121+
$view = Craft::$app->getView();
122+
121123
if ($webhook->method === 'post') {
122124
// Build out the body data
123125
if ($webhook->payloadTemplate) {
124-
$json = Craft::$app->getView()->renderString($webhook->payloadTemplate, [
126+
$json = $view->renderString($webhook->payloadTemplate, [
125127
'event' => $e,
126128
]);
127129
$data = Json::decodeIfJson($json);
@@ -147,15 +149,39 @@ public function init()
147149
}
148150
}
149151

150-
// Queue the send request up
152+
// Set the headers and body
151153
$headers = [];
154+
155+
foreach ($webhook->headers as $header) {
156+
$header['value'] = Craft::parseEnv($header['value']);
157+
if (strpos($header['value'], '{') !== false) {
158+
$header['value'] = $view->renderString($header['value'], [
159+
'event' => $e,
160+
]);
161+
}
162+
// Get the trimmed lines
163+
$lines = array_filter(array_map('trim', preg_split('/[\r\n]+/', $header['value'])));
164+
// Add to the header array one-by-one, ensuring that we don't overwrite existing values
165+
foreach ($lines as $line) {
166+
if (!isset($headers[$header['name']])) {
167+
$headers[$header['name']] = $line;
168+
} else {
169+
if (!is_array($headers[$header['name']])) {
170+
$headers[$header['name']] = [$headers[$header['name']]];
171+
}
172+
$headers[$header['name']][] = $line;
173+
}
174+
}
175+
}
176+
152177
if (isset($data) && is_array($data)) {
153178
$body = Json::encode($data);
154179
$headers['Content-Type'] = 'application/json';
155180
} else {
156181
$body = $data ?? null;
157182
}
158183

184+
// Queue the send request up
159185
$this->request($webhook->method, $webhook->url, $headers, $body, $webhook->id);
160186
});
161187
}

src/Webhook.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ class Webhook extends Model
6262
*/
6363
public $url;
6464

65+
/**
66+
* @var array
67+
*/
68+
public $headers = [];
69+
6570
/**
6671
* @var string|null
6772
*/
@@ -149,7 +154,7 @@ function(string $attribute, array $params = null, Validator $validator) {
149154
],
150155
[
151156
['filters'],
152-
function(string $attribute) {
157+
function() {
153158
foreach ($this->filters as $class => &$value) {
154159
if ($value === 'yes') {
155160
$value = true;
@@ -162,6 +167,12 @@ function(string $attribute) {
162167
}
163168
}
164169
],
170+
[
171+
['headers'],
172+
function() {
173+
$this->headers = $this->headers ? array_values($this->headers) : [];
174+
}
175+
],
165176
[['userAttributes', 'senderAttributes'], 'validateAttributeList'],
166177
[['eventAttributes'], 'validateAttributeList', 'params' => ['regex' => '/^[a-z]\w*\.[a-z]\w*(?:\.[a-z]\w*)*$/i']],
167178
[['payloadTemplate'], 'validatePayloadTemplate'],

src/WebhookManager.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,10 @@ public function saveWebhook(Webhook $webhook, bool $runValidation = true): bool
197197
'name' => $name,
198198
'class' => $webhook->class,
199199
'event' => $webhook->event,
200-
'filters' => Json::encode($webhook->filters),
200+
'filters' => $webhook->filters ? Json::encode($webhook->filters) : null,
201201
'method' => $webhook->method,
202202
'url' => $webhook->url,
203+
'headers' => $webhook->headers ? Json::encode($webhook->headers) : null,
203204
'userAttributes' => $webhook->userAttributes,
204205
'senderAttributes' => $webhook->senderAttributes,
205206
'eventAttributes' => $webhook->eventAttributes,
@@ -238,7 +239,22 @@ public function deleteWebhookById(int $id)
238239
private function _createWebhookQuery(): Query
239240
{
240241
return (new Query())
241-
->select(['id', 'groupId', 'enabled', 'name', 'class', 'event', 'filters', 'method', 'url', 'userAttributes', 'senderAttributes', 'eventAttributes', 'payloadTemplate'])
242+
->select([
243+
'id',
244+
'groupId',
245+
'enabled',
246+
'name',
247+
'class',
248+
'event',
249+
'filters',
250+
'method',
251+
'url',
252+
'headers',
253+
'userAttributes',
254+
'senderAttributes',
255+
'eventAttributes',
256+
'payloadTemplate',
257+
])
242258
->from(['{{%webhooks}}']);
243259
}
244260

@@ -259,6 +275,12 @@ private function _createWebhook(array $result, bool $isMysql = null): Webhook
259275
$result['filters'] = [];
260276
}
261277

278+
if ($result['headers']) {
279+
$result['headers'] = Json::decode($result['headers']);
280+
} else {
281+
$result['headers'] = [];
282+
}
283+
262284
return new Webhook($result);
263285
}
264286

src/assets/edit/dist/css/edit-webhook.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
display: inline-block;
44
}
55

6+
#filter-pane {
7+
position: relative;
8+
}
9+
610
#no-filters {
711
margin: 0;
812
}
@@ -41,3 +45,16 @@
4145
#filters .filter-ignore .status {
4246
margin: 0;
4347
}
48+
49+
#filter-spinner {
50+
position: absolute;
51+
display: flex;
52+
justify-content: center;
53+
align-items: center;
54+
top: 0;
55+
left: 0;
56+
width: 100%;
57+
height: 100%;
58+
background: rgba(255,255,255,0.85);
59+
z-index: 1;
60+
}

src/assets/edit/dist/js/EditWebhook.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@
6464
return;
6565
}
6666
this.$filterSpinner.removeClass('hidden');
67-
this.$noFiltersMessage.addClass('hidden');
68-
this.$filtersTable.addClass('hidden');
6967
Craft.postActionRequest('webhooks/webhooks/filters', {
7068
senderClass: this.classVal,
7169
event: this.eventVal,
@@ -74,12 +72,14 @@
7472
if (textStatus === 'success') {
7573
this.resetFilters();
7674
if (response.filters.length) {
75+
this.$noFiltersMessage.addClass('hidden');
7776
this.$filtersTable.removeClass('hidden');
7877
for (var i = 0; i < response.filters.length; i++) {
7978
this.filters[response.filters[i]].$tr.removeClass('hidden');
8079
}
8180
} else {
8281
this.$noFiltersMessage.removeClass('hidden');
82+
this.$filtersTable.addClass('hidden');
8383
}
8484
}
8585
}.bind(this));

src/migrations/Install.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function safeUp()
3636
'filters' => $this->text(),
3737
'method' => $this->string(10)->notNull(),
3838
'url' => $this->string()->notNull(),
39+
'headers' => $this->text(),
3940
'userAttributes' => $this->text(),
4041
'senderAttributes' => $this->text(),
4142
'eventAttributes' => $this->text(),

0 commit comments

Comments
 (0)