+
Duplicati Backup Report
+
+
{{ParsedResult}}
+
+
+
Backup Details
+
+ | Operation | {{OperationName}} |
+ {{#if BackupName}}| Backup Name | {{BackupName}} |
{{/if}}
+ {{#if MachineName}}| Machine | {{MachineName}} |
{{/if}}
+ {{#if OperatingSystem}}| OS | {{OperatingSystem}} |
{{/if}}
+
+
+
+ {{#if Data}}
+
+
Statistics
+
+ {{#if Data.ExaminedFiles}}| Files Examined | {{Data.ExaminedFiles}} |
{{/if}}
+ {{#if Data.SizeOfExaminedFiles}}| Data Examined | {{formatSize Data.SizeOfExaminedFiles}} |
{{/if}}
+ {{#if Data.AddedFiles}}| Files Added | {{Data.AddedFiles}} |
{{/if}}
+ {{#if Data.SizeOfAddedFiles}}| Data Added | {{formatSize Data.SizeOfAddedFiles}} |
{{/if}}
+ {{#if Data.ModifiedFiles}}| Files Modified | {{Data.ModifiedFiles}} |
{{/if}}
+ {{#if Data.SizeOfModifiedFiles}}| Data Modified | {{formatSize Data.SizeOfModifiedFiles}} |
{{/if}}
+ {{#if Data.DeletedFiles}}| Files Deleted | {{Data.DeletedFiles}} |
{{/if}}
+ {{#if Data.Duration}}| Duration | {{formatDuration Data.Duration}} |
{{/if}}
+
+
+ {{/if}}
+
+ {{#if LogLines}}
+
+
Log Messages
+
+ {{#each LogLines}}
+
{{this}}
+ {{/each}}
+
+
+ {{/if}}
+
+ {{#if Exception}}
+
+ {{/if}}
+
+
+
+
+
diff --git a/Duplicati/Library/Modules/Builtin/Templates/slack.hbs b/Duplicati/Library/Modules/Builtin/Templates/slack.hbs
new file mode 100644
index 000000000..8e5819ad6
--- /dev/null
+++ b/Duplicati/Library/Modules/Builtin/Templates/slack.hbs
@@ -0,0 +1,86 @@
+{
+ "text": "Duplicati {{OperationName}} - {{ParsedResult}}",
+ "blocks": [
+ {
+ "type": "header",
+ "text": {
+ "type": "plain_text",
+ "text": "Duplicati {{OperationName}} Report"
+ }
+ },
+ {
+ "type": "section",
+ "fields": [
+ {
+ "type": "mrkdwn",
+ "text": "*Status:*\n{{ParsedResult}}"
+ },
+ {
+ "type": "mrkdwn",
+ "text": "*Backup:*\n{{BackupName}}"
+ },
+ {
+ "type": "mrkdwn",
+ "text": "*Machine:*\n{{MachineName}}"
+ },
+ {
+ "type": "mrkdwn",
+ "text": "*Operation:*\n{{OperationName}}"
+ }
+ ]
+ }{{#if Data}},
+ {
+ "type": "divider"
+ },
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": "*Statistics*"
+ }
+ },
+ {
+ "type": "section",
+ "fields": [
+ {{#if Data.ExaminedFiles}}
+ {
+ "type": "mrkdwn",
+ "text": "*Files Examined:* {{Data.ExaminedFiles}}"
+ },
+ {{/if}}
+ {{#if Data.AddedFiles}}
+ {
+ "type": "mrkdwn",
+ "text": "*Files Added:* {{Data.AddedFiles}}"
+ },
+ {{/if}}
+ {{#if Data.ModifiedFiles}}
+ {
+ "type": "mrkdwn",
+ "text": "*Files Modified:* {{Data.ModifiedFiles}}"
+ },
+ {{/if}}
+ {{#if Data.DeletedFiles}}
+ {
+ "type": "mrkdwn",
+ "text": "*Files Deleted:* {{Data.DeletedFiles}}"
+ },
+ {{/if}}
+ {
+ "type": "mrkdwn",
+ "text": " "
+ }
+ ]
+ }{{/if}}{{#if Exception}},
+ {
+ "type": "divider"
+ },
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": "*Error:* {{Exception}}"
+ }
+ }{{/if}}
+ ]
+}
diff --git a/Duplicati/UnitTest/TemplateSerializerTests.cs b/Duplicati/UnitTest/TemplateSerializerTests.cs
new file mode 100644
index 000000000..5af547f8b
--- /dev/null
+++ b/Duplicati/UnitTest/TemplateSerializerTests.cs
@@ -0,0 +1,205 @@
+// Copyright (C) 2025, The Duplicati Team
+// https://duplicati.com, hello@duplicati.com
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Duplicati.Library.Modules.Builtin;
+using Duplicati.Library.Modules.Builtin.ResultSerialization;
+using NUnit.Framework;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ public class TemplateSerializerTests : BasicSetupHelper
+ {
+ [Test]
+ [Category("Serialization")]
+ public void TestGetSerializerGivenTemplateReturnsTemplateSerializer()
+ {
+ IResultFormatSerializer serializer = ResultFormatSerializerProvider.GetSerializer(ResultExportFormat.Template);
+ Assert.That(serializer, Is.InstanceOf