Skip to content

Commit 7bf9bdf

Browse files
committed
Subscription hooks integration
1 parent fca0541 commit 7bf9bdf

18 files changed

+302
-534
lines changed

src/Umbraco.Cms.Integrations.Automation.Zapier/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/dashboard.html

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,50 +22,39 @@
2222
You can initiate your automation when a content item of a particular document type is published in Umbraco.
2323
</p>
2424
<p>
25-
Using the filters below, map content items with Zap triggered webhooks. This will:
25+
The integration uses Zapier subscription hook triggers, allowing Zapier to set up and remove hook subscriptions through Subscribe/Unsubscribe API requests.
2626
</p>
27-
<ul>
28-
<li>Enable Zap invocations when content of the specified document type is published.</li>
29-
<li>Trigger a sample request using the webhook URL to review when creating the Zap trigger.</li>
30-
</ul>
31-
</div>
32-
<div class="mt3">
33-
<input id="inWebHookUrl" type="text" ng-model="vm.webHookUrl" class="w-20 mb0" placeholder="WebHook URL" no-dirty-check />
34-
<select id="selContentTypes" ng-model="vm.selectedContentType" class="mb0" no-dirty-check>
35-
<option value="">Please select a content type</option>
36-
<option ng-repeat="item in vm.contentTypes" value="{{ item.name }}">{{ item.name }}</option>
37-
</select>
38-
<umb-button action="vm.onAdd()"
39-
type="button"
40-
button-style="primary"
41-
label="Add">
42-
</umb-button>
4327
</div>
4428
</umb-box-content>
4529
</umb-box>
4630
<umb-box>
47-
<umb-box-header title="Registered Webhooks"></umb-box-header>
31+
<umb-box-header title="Registered Subscription Hooks"></umb-box-header>
4832
<umb-content>
4933
<div class="mt2">
5034

35+
<!-- If list is empty, then display -->
36+
<umb-empty-state ng-if="vm.contentConfigs.length == 0"
37+
position="center" class="mb-3">
38+
There are no subscription hooks.
39+
</umb-empty-state>
40+
5141
<umb-load-indicator ng-show="vm.loading"></umb-load-indicator>
5242

53-
<div class="umb-table" ng-if="vm.contentConfigs">
43+
<div class="umb-table" ng-if="vm.contentConfigs.length > 0">
5444
<!-- Listviews head section -->
5545
<div class="umb-table-head">
5646
<div class="umb-table-row">
5747
<div class="umb-table-cell"></div>
5848
<div class="umb-table-cell umb-table__name">
5949
<a class="umb-table-head__link" href="#" prevent-default>
60-
<span>Content Type Name</span>
50+
<span>Content Type Alias</span>
6151
</a>
6252
</div>
6353
<div class="umb-table-cell">
6454
<a class="umb-table-head__link" href="#" prevent-default>
65-
<span>WebHook URL</span>
55+
<span>Hook URL</span>
6656
</a>
6757
</div>
68-
<div class="umb-table-cell"></div>
6958
</div>
7059
</div>
7160

@@ -75,22 +64,10 @@
7564
ng-repeat="row in vm.contentConfigs track by $index">
7665
<div class="umb-table-cell"></div>
7766
<div class="umb-table-cell umb-table__name">
78-
<span ng-bind="row.contentTypeName"></span>
79-
</div>
80-
<div class="umb-table-cell">
81-
<span ng-bind="row.webHookUrl"></span>
67+
<span ng-bind="row.contentTypeAlias"></span>
8268
</div>
8369
<div class="umb-table-cell">
84-
<umb-button action="vm.onTrigger(row.webHookUrl, row.contentTypeName)"
85-
label="Trigger Webhook"
86-
type="button"
87-
button-style="info">
88-
</umb-button>
89-
<umb-button action="vm.onDelete(row.id)"
90-
label="Delete"
91-
type="button"
92-
button-style="danger">
93-
</umb-button>
70+
<span ng-bind="row.hookUrl"></span>
9471
</div>
9572
</div>
9673
</div>

src/Umbraco.Cms.Integrations.Automation.Zapier/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier-validation.service.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/Umbraco.Cms.Integrations.Automation.Zapier/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier.controller.js

Lines changed: 3 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -3,100 +3,18 @@
33
var vm = this;
44

55
vm.loading = false;
6-
vm.contentTypes = [];
76
vm.contentConfigs = [];
87

9-
getContentTypes();
10-
118
getContentConfigs();
129

13-
vm.onAdd = function () {
14-
const validationResult =
15-
umbracoCmsIntegrationsAutomationZapierValidationService.validateConfiguration(vm.webHookUrl,
16-
vm.selectedContentType);
17-
18-
if (validationResult.length > 0) {
19-
notificationsService.warning("Zapier Content Config", validationResult);
20-
return;
21-
}
22-
23-
umbracoCmsIntegrationsAutomationZapierResource.addConfig(vm.webHookUrl, vm.selectedContentType).then(function (response) {
24-
25-
if (response.length > 0) {
26-
notificationsService.warning("Zapier Content Config", response);
27-
return;
28-
}
29-
30-
getContentTypes();
31-
32-
getContentConfigs();
33-
34-
reset();
35-
});
36-
}
37-
38-
vm.onTrigger = function (webHookUrl, contentTypeName) {
39-
40-
vm.loading = true;
41-
42-
umbracoCmsIntegrationsAutomationZapierResource.triggerWebHook(webHookUrl, contentTypeName).then(function (response) {
43-
44-
vm.loading = false;
45-
46-
if (response.length > 0)
47-
notificationsService.warning("WebHook Trigger", response);
48-
else
49-
notificationsService.success("WebHook Trigger", "WebHook triggered successfully. Please check your Zap trigger for the newly submitted request.");
50-
});
51-
}
52-
53-
vm.onDelete = function (id) {
54-
55-
localizationService.localizeMany(["zapierDashboard_promptDeleteTitle", "zapierDashboard_promptDeleteContent", "general_yes", "general_no"])
56-
.then(function (labels) {
57-
var overlay = {
58-
view: "confirm",
59-
title: labels[0],
60-
content: labels[1],
61-
closeButtonLabel: labels[3],
62-
submitButtonLabel: labels[2],
63-
submitButtonStyle: "danger",
64-
close: function () {
65-
overlayService.close();
66-
},
67-
submit: function () {
68-
69-
umbracoCmsIntegrationsAutomationZapierResource.deleteConfig(id).then(function () {
70-
getContentTypes();
71-
72-
getContentConfigs();
73-
});
74-
75-
overlayService.close();
76-
}
77-
};
78-
overlayService.open(overlay);
79-
});
80-
}
81-
82-
function getContentTypes() {
83-
umbracoCmsIntegrationsAutomationZapierResource.getContentTypes().then(function (response) {
84-
vm.contentTypes = response;
85-
});
86-
}
87-
8810
function getContentConfigs() {
89-
umbracoCmsIntegrationsAutomationZapierResource.getAllConfigs().then(function (response) {
11+
vm.loading = true;
12+
umbracoCmsIntegrationsAutomationZapierResource.getAllContentConfigs().then(function (response) {
9013
vm.contentConfigs = response;
14+
vm.loading = false;
9115
});
9216
}
9317

94-
function reset() {
95-
vm.webHookUrl = "";
96-
vm.selectedContentType = "";
97-
}
98-
99-
10018
}
10119

10220
angular.module("umbraco")

src/Umbraco.Cms.Integrations.Automation.Zapier/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier.resource.js

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
11
angular.module('umbraco.resources').factory('umbracoCmsIntegrationsAutomationZapierResource',
22
function ($http, umbRequestHelper) {
33

4-
const apiEndpoint = "backoffice/UmbracoCmsIntegrationsAutomationZapier/ZapConfig";
4+
const apiEndpoint = "backoffice/UmbracoCmsIntegrationsAutomationZapier/ZapierConfig";
55

66
return {
7-
getContentTypes: function () {
8-
return umbRequestHelper.resourcePromise(
9-
$http.get(`${apiEndpoint}/GetContentTypes`),
10-
"Failed to get resource");
11-
},
12-
addConfig: function (webHookUrl, contentTypeName) {
13-
return umbRequestHelper.resourcePromise(
14-
$http.post(`${apiEndpoint}/Add`, { contentTypeName: contentTypeName, webHookUrl: webHookUrl }), "Failed to get resource");
15-
},
16-
getAllConfigs: function () {
7+
getAllContentConfigs: function () {
178
return umbRequestHelper.resourcePromise(
189
$http.get(`${apiEndpoint}/GetAll`), "Failed to get resource");
19-
},
20-
triggerWebHook: function (webHookUrl, contentTypeName) {
21-
return umbRequestHelper.resourcePromise(
22-
$http.post(`${apiEndpoint}/TriggerWebHook`, { contentTypeName: contentTypeName, webHookUrl: webHookUrl }), "Failed to get resource");
23-
},
24-
deleteConfig: function (id) {
25-
return umbRequestHelper.resourcePromise(
26-
$http.delete(`${apiEndpoint}/Delete?id=${id}`), "Failed to get resource");
2710
}
2811
};
2912
}

src/Umbraco.Cms.Integrations.Automation.Zapier/Components/NewContentPublishedComponent.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ public class NewContentPublishedComposer : ComponentComposer<NewContentPublished
2020

2121
public class NewContentPublishedComponent : IComponent
2222
{
23-
private readonly ZapConfigService _zapConfigService;
23+
private readonly ZapierSubscriptionHookService _zapierSubscriptionHookService;
2424

2525
private readonly ZapierService _zapierService;
2626

2727
private readonly ILogger _logger;
2828

29-
public NewContentPublishedComponent(ZapConfigService zapConfigService, ZapierService zapierService, ILogger logger)
29+
public NewContentPublishedComponent(ZapierSubscriptionHookService zapierSubscriptionHookService, ZapierService zapierService, ILogger logger)
3030
{
31-
_zapConfigService = zapConfigService;
31+
_zapierSubscriptionHookService = zapierSubscriptionHookService;
3232

3333
_zapierService = zapierService;
3434

@@ -49,22 +49,23 @@ private void ContentServiceOnPublished(IContentService sender, ContentPublishedE
4949
{
5050
foreach (var node in e.PublishedEntities)
5151
{
52-
var zapContentConfig = _zapConfigService.GetByName(node.ContentType.Name);
53-
if (zapContentConfig == null || !zapContentConfig.IsEnabled) continue;
54-
55-
var content = new Dictionary<string, string>
52+
if (_zapierSubscriptionHookService.TryGetByAlias(node.ContentType.Alias, out var zapContentConfig))
5653
{
57-
{ Constants.Content.Id, node.Id.ToString() },
58-
{ Constants.Content.Name, node.Name },
59-
{ Constants.Content.PublishDate, DateTime.UtcNow.ToString() }
60-
};
54+
var content = new Dictionary<string, string>
55+
{
56+
{Constants.Content.Id, node.Id.ToString()},
57+
{Constants.Content.Name, node.Name},
58+
{Constants.Content.PublishDate, DateTime.UtcNow.ToString()}
59+
};
6160

62-
var t = Task.Run(async () => await _zapierService.TriggerAsync(zapContentConfig.WebHookUrl, content));
61+
var t = Task.Run(
62+
async () => await _zapierService.TriggerAsync(zapContentConfig.HookUrl, content));
6363

64-
var result = t.Result;
64+
var result = t.Result;
6565

66-
if(!string.IsNullOrEmpty(result))
67-
_logger.Error<NewContentPublishedComponent>(result);
66+
if (!string.IsNullOrEmpty(result))
67+
_logger.Error<NewContentPublishedComponent>(result);
68+
}
6869
}
6970
}
7071
}

src/Umbraco.Cms.Integrations.Automation.Zapier/Components/NewContentPublishedNotification.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace Umbraco.Cms.Integrations.Automation.Zapier.Components
1313
{
1414
public class NewContentPublishedNotification : INotificationHandler<ContentPublishedNotification>
1515
{
16-
private readonly ZapConfigService _zapConfigService;
16+
private readonly ZapierSubscriptionHookService _zapierSubscriptionHookService;
1717

1818
private readonly ZapierService _zapierService;
1919

2020
private readonly ILogger<NewContentPublishedNotification> _logger;
2121

22-
public NewContentPublishedNotification(ZapConfigService zapConfigService, ZapierService zapierService, ILogger<NewContentPublishedNotification> logger)
22+
public NewContentPublishedNotification(ZapierSubscriptionHookService zapierSubscriptionHookService, ZapierService zapierService, ILogger<NewContentPublishedNotification> logger)
2323
{
24-
_zapConfigService = zapConfigService;
24+
_zapierSubscriptionHookService = zapierSubscriptionHookService;
2525

2626
_zapierService = zapierService;
2727

@@ -32,22 +32,23 @@ public void Handle(ContentPublishedNotification notification)
3232
{
3333
foreach (var node in notification.PublishedEntities)
3434
{
35-
var zapContentConfig = _zapConfigService.GetByName(node.ContentType.Name);
36-
if (zapContentConfig == null || !zapContentConfig.IsEnabled) continue;
37-
38-
var content = new Dictionary<string, string>
35+
if (_zapierSubscriptionHookService.TryGetByAlias(node.ContentType.Alias, out var zapContentConfig))
3936
{
40-
{ Constants.Content.Id, node.Id.ToString() },
41-
{ Constants.Content.Name, node.Name },
42-
{ Constants.Content.PublishDate, DateTime.UtcNow.ToString() }
43-
};
37+
var content = new Dictionary<string, string>
38+
{
39+
{Constants.Content.Id, node.Id.ToString()},
40+
{Constants.Content.Name, node.Name},
41+
{Constants.Content.PublishDate, DateTime.UtcNow.ToString()}
42+
};
4443

45-
var t = Task.Run(async () => await _zapierService.TriggerAsync(zapContentConfig.WebHookUrl, content));
44+
var t = Task.Run(
45+
async () => await _zapierService.TriggerAsync(zapContentConfig.HookUrl, content));
4646

47-
var result = t.Result;
47+
var result = t.Result;
4848

49-
if (!string.IsNullOrEmpty(result))
50-
_logger.LogError(result);
49+
if (!string.IsNullOrEmpty(result))
50+
_logger.LogError(result);
51+
}
5152
}
5253
}
5354
}

src/Umbraco.Cms.Integrations.Automation.Zapier/Constants.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ namespace Umbraco.Cms.Integrations.Automation.Zapier
33
{
44
public class Constants
55
{
6-
public const string ZapContentConfigTable = "zapContentConfig";
6+
public const string ZapierSubscriptionHookTable = "zapierSubscriptionHook";
77

8-
public const string MigrationPlanName = "ZapContentConfig";
8+
public const string MigrationPlanName = "ZapierSubscriptionHook";
99

10-
public const string TargetStateName = "zapiercontentconfigurations-db";
10+
public const string TargetStateName = "zapiersubscriptionhook-db";
1111

1212
public const string UmbracoCmsIntegrationsAutomationZapierUserGroup = "Umbraco.Cms.Integrations.Automation.Zapier.UserGroup";
1313

0 commit comments

Comments
 (0)