Skip to content

Commit 33a5e18

Browse files
committed
CMS Zapier Integration.
1 parent 0580218 commit 33a5e18

20 files changed

+673
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.mb0 {
2+
margin-bottom: 0px !important;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<div ng-controller="Umbraco.Cms.Integrations.Automation.Zapier.ZapConfigController as vm">
2+
<umb-box>
3+
<umb-box-header title="Configuration"></umb-box-header>
4+
<umb-content>
5+
<div class="mt2 ml2">
6+
<input id="inWebHookUrl" type="text" ng-model="vm.webHookUrl" class="w-20 mb0" placeholder="WebHook URL"/>
7+
<select id="selContentTypes" ng-model="vm.selectedContentType" class="mb0">
8+
<option value="">Please select a content type</option>
9+
<option ng-repeat="item in vm.contentTypes" value="{{ item.alias }}">{{ item.name }}</option>
10+
</select>
11+
<umb-button action="vm.onAdd()"
12+
type="button"
13+
button-style="primary"
14+
label="Add">
15+
</umb-button>
16+
</div>
17+
<div class="mt2">
18+
<div class="umb-table" ng-if="vm.contentConfigs">
19+
<!-- Listviews head section -->
20+
<div class="umb-table-head">
21+
<div class="umb-table-row">
22+
<div class="umb-table-cell">
23+
</div>
24+
<div class="umb-table-cell">
25+
<a class="umb-table-head__link" href="#" prevent-default>
26+
<span>Content Type Alias</span>
27+
</a>
28+
</div>
29+
<div class="umb-table-cell">
30+
<a class="umb-table-head__link" href="#" prevent-default>
31+
<span>WebHook URL</span>
32+
</a>
33+
</div>
34+
<div class="umb-table-cell"></div>
35+
</div>
36+
</div>
37+
38+
<!-- Listview body section -->
39+
<div class="umb-table-body">
40+
<div class="umb-table-row"
41+
ng-repeat="row in vm.contentConfigs track by $index">
42+
<div class="umb-table-cell"></div>
43+
<div class="umb-table-cell">
44+
<span ng-bind="row.contentTypeAlias"></span>
45+
</div>
46+
<div class="umb-table-cell">
47+
<span ng-bind="row.webHookUrl"></span>
48+
</div>
49+
<div class="umb-table-cell">
50+
<div class="umb-forms-mapping-remove -no-margin-right">
51+
<a href="javascript:void(0)" ng-click="vm.onDelete(row.id)"><i class="icon-trash"></i></a>
52+
</div>
53+
</div>
54+
</div>
55+
</div>
56+
</div>
57+
</div>
58+
</umb-content>
59+
</umb-box>
60+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function zapierValidationService() {
2+
return {
3+
isValidConfig: (webHookUrl, contentTypeAlias) => {
4+
5+
if (webHookUrl === undefined || webHookUrl.length === 0) return false;
6+
7+
let url;
8+
9+
try {
10+
url = new URL(webHookUrl);
11+
}
12+
catch (_) {
13+
return false;
14+
}
15+
16+
if (!(url.protocol === "http:" || url.protocol === "https:")) return false;
17+
18+
if (contentTypeAlias === undefined || contentTypeAlias.length === 0) return false;
19+
20+
return true;
21+
}
22+
}
23+
}
24+
25+
angular.module("umbraco.services")
26+
.service("umbracoCmsIntegrationsAutomationZapierValidationService", zapierValidationService);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
function zapierController($scope, notificationsService, umbracoCmsIntegrationsAutomationZapierResource, umbracoCmsIntegrationsAutomationZapierValidationService) {
2+
3+
var vm = this;
4+
5+
vm.contentTypes = [];
6+
vm.contentConfigs = [];
7+
8+
getContentTypes();
9+
10+
getContentConfigs();
11+
12+
vm.onAdd = function () {
13+
14+
const isValid =
15+
umbracoCmsIntegrationsAutomationZapierValidationService.isValidConfig(vm.webHookUrl,
16+
vm.selectedContentType);
17+
18+
if (!isValid) {
19+
notificationsService.warning("Zapier Content Config", "Zapier configuration is invalid");
20+
return;
21+
}
22+
23+
umbracoCmsIntegrationsAutomationZapierResource.addConfig(vm.webHookUrl, vm.selectedContentType).then(function (r) {
24+
25+
getContentTypes(vm.selectedContentType);
26+
27+
getContentConfigs();
28+
29+
reset();
30+
});
31+
}
32+
33+
vm.onDelete = function(id) {
34+
umbracoCmsIntegrationsAutomationZapierResource.deleteConfig(id).then(function () {
35+
getContentTypes();
36+
37+
getContentConfigs();
38+
});
39+
}
40+
41+
function getContentTypes() {
42+
umbracoCmsIntegrationsAutomationZapierResource.getContentTypes().then(function (response) {
43+
vm.contentTypes = response;
44+
});
45+
}
46+
47+
function getContentConfigs() {
48+
umbracoCmsIntegrationsAutomationZapierResource.getAllConfigs().then(function (response) {
49+
vm.contentConfigs = response;
50+
});
51+
}
52+
53+
function reset() {
54+
vm.webHookUrl = "";
55+
vm.selectedContentType = "";
56+
}
57+
}
58+
59+
angular.module("umbraco")
60+
.controller("Umbraco.Cms.Integrations.Automation.Zapier.ZapConfigController", zapierController);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
angular.module('umbraco.resources').factory('umbracoCmsIntegrationsAutomationZapierResource',
2+
function ($http, umbRequestHelper) {
3+
4+
const apiEndpoint = "backoffice/UmbracoCmsIntegrationsAutomationZapier/ZapConfig";
5+
6+
return {
7+
getContentTypes: function () {
8+
return umbRequestHelper.resourcePromise(
9+
$http.get(`${apiEndpoint}/GetContentTypes`),
10+
"Failed to get resource");
11+
},
12+
addConfig: function (webHookUrl, contentTypeAlias) {
13+
return umbRequestHelper.resourcePromise(
14+
$http.post(`${apiEndpoint}/Add`, { contentTypeAlias: contentTypeAlias, webHookUrl: webHookUrl }), "Failed to get resource");
15+
},
16+
getAllConfigs: function () {
17+
return umbRequestHelper.resourcePromise(
18+
$http.get(`${apiEndpoint}/GetAll`), "Failed to get resource");
19+
},
20+
deleteConfig: function(id) {
21+
return umbRequestHelper.resourcePromise(
22+
$http.delete(`${apiEndpoint}/Delete?id=${id}`), "Failed to get resource");
23+
}
24+
};
25+
}
26+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<language>
3+
<area alias="dashboardTabs">
4+
<key alias="zapierDashboard">Zapier Settings</key>
5+
</area>
6+
</language>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"javascript": [
3+
"~/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier.controller.js",
4+
"~/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier.resource.js",
5+
"~/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/js/zapier-validation.service.js"
6+
],
7+
"css": [
8+
"~/App_Plugins/UmbracoCms.Integrations/Automation/Zapier/css/zapier.css"
9+
]
10+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net.Http;
4+
5+
using Umbraco.Cms.Integrations.Automation.Zapier.Services;
6+
using Umbraco.Core;
7+
using Umbraco.Core.Composing;
8+
using Umbraco.Core.Events;
9+
using Umbraco.Core.Logging;
10+
using Umbraco.Core.Models;
11+
using Umbraco.Core.Services;
12+
using Umbraco.Core.Services.Implement;
13+
14+
namespace Umbraco.Cms.Integrations.Automation.Zapier.Components
15+
{
16+
17+
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
18+
public class NewContentPublishedComposer : ComponentComposer<NewContentPublishedComponent>
19+
{ }
20+
21+
public class NewContentPublishedComponent : IComponent
22+
{
23+
private readonly ZapConfigService _zapConfigService;
24+
25+
private readonly ZapierService _zapierService;
26+
27+
private readonly ILogger _logger;
28+
29+
public NewContentPublishedComponent(ZapConfigService zapConfigService, ZapierService zapierService, ILogger logger)
30+
{
31+
_zapConfigService = zapConfigService;
32+
33+
_zapierService = zapierService;
34+
35+
_logger = logger;
36+
}
37+
38+
public void Initialize()
39+
{
40+
ContentService.Published += ContentServiceOnPublished;
41+
}
42+
43+
public void Terminate()
44+
{
45+
ContentService.Published -= ContentServiceOnPublished;
46+
}
47+
48+
private void ContentServiceOnPublished(IContentService sender, ContentPublishedEventArgs e)
49+
{
50+
foreach (var node in e.PublishedEntities)
51+
{
52+
var zapContentConfig = _zapConfigService.GetByAlias(node.ContentType.Alias);
53+
if (zapContentConfig == null) return;
54+
55+
var content = new Dictionary<string, string>
56+
{
57+
{ Constants.Content.Name, node.ContentType.Name },
58+
{ Constants.Content.PublishDate, DateTime.UtcNow.ToString() }
59+
};
60+
61+
var result = _zapierService.TriggerAsync(zapContentConfig.WebHookUrl, content);
62+
63+
if(!string.IsNullOrEmpty(result))
64+
_logger.Error<NewContentPublishedComponent>(result);
65+
}
66+
}
67+
}
68+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using Umbraco.Cms.Integrations.Automation.Zapier.Migrations;
2+
using Umbraco.Core;
3+
using Umbraco.Core.Composing;
4+
using Umbraco.Core.Logging;
5+
using Umbraco.Core.Migrations;
6+
using Umbraco.Core.Migrations.Upgrade;
7+
using Umbraco.Core.Scoping;
8+
using Umbraco.Core.Services;
9+
10+
namespace Umbraco.Cms.Integrations.Automation.Zapier.Components
11+
{
12+
13+
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
14+
public class ZapContentConfigComposer : ComponentComposer<ZapContentConfigComponent>
15+
{
16+
17+
}
18+
19+
public class ZapContentConfigComponent : IComponent
20+
{
21+
private IScopeProvider _scopeProvider;
22+
23+
private IMigrationBuilder _migrationBuilder;
24+
25+
private IKeyValueService _keyValueService;
26+
27+
private ILogger _logger;
28+
29+
public ZapContentConfigComponent(IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, ILogger logger)
30+
{
31+
_scopeProvider = scopeProvider;
32+
33+
_migrationBuilder = migrationBuilder;
34+
35+
_keyValueService = keyValueService;
36+
37+
_logger = logger;
38+
}
39+
40+
public void Initialize()
41+
{
42+
var migrationPlan = new MigrationPlan("ZapContentConfig");
43+
44+
migrationPlan.From(string.Empty)
45+
.To<ZapContentConfigTable>("zapiercontentconfigurations-db");
46+
47+
var upgrader = new Upgrader(migrationPlan);
48+
upgrader.Execute(_scopeProvider, _migrationBuilder, _keyValueService, _logger);
49+
}
50+
51+
public void Terminate()
52+
{
53+
}
54+
}
55+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+

2+
namespace Umbraco.Cms.Integrations.Automation.Zapier
3+
{
4+
public class Constants
5+
{
6+
public const string ZapContentConfigTable = "zapContentConfig";
7+
8+
public static class Content
9+
{
10+
public const string Name = "Name";
11+
12+
public const string PublishDate = "PublishDate";
13+
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)