diff --git a/Duplicati/Library/Modules/Builtin/ReportHelper.cs b/Duplicati/Library/Modules/Builtin/ReportHelper.cs
index e37ee17ac..5d8b35fac 100644
--- a/Duplicati/Library/Modules/Builtin/ReportHelper.cs
+++ b/Duplicati/Library/Modules/Builtin/ReportHelper.cs
@@ -83,6 +83,10 @@ namespace Duplicati.Library.Modules.Builtin
/// Name of the option used to the output format
///
protected abstract string ResultFormatOptionName { get; }
+ ///
+ /// Name of the option used to specify extra data to include in the report
+ ///
+ protected abstract string ExtraDataOptionName { get; }
///
/// The default subject or title line
@@ -184,13 +188,17 @@ namespace Duplicati.Library.Modules.Builtin
///
private bool m_sendAll;
///
+ /// The extra values to include in the report
+ ///
+ private Dictionary m_extraValues;
+ ///
/// The log scope that should be disposed
///
private IDisposable m_logscope;
///
/// The log storage
///
- private Utility.FileBackedStringList m_logstorage;
+ private FileBackedStringList m_logstorage;
///
/// Serializer to use when serializing the message.
///
@@ -224,6 +232,21 @@ namespace Duplicati.Library.Modules.Builtin
m_isConfigured = true;
m_options.TryGetValue(SubjectOptionName, out m_subject);
m_options.TryGetValue(BodyOptionName, out m_body);
+ m_options.TryGetValue(ExtraDataOptionName, out var extraData);
+ if (!string.IsNullOrWhiteSpace(extraData))
+ {
+ if (extraData.Trim().StartsWith("{") && extraData.Trim().EndsWith("}"))
+ {
+ m_extraValues = System.Text.Json.JsonSerializer.Deserialize>(extraData);
+ }
+ else
+ {
+ var values = Utility.Uri.ParseQueryString(extraData);
+ m_extraValues = values.AllKeys
+ .Where(x => !string.IsNullOrWhiteSpace(x))
+ .ToDictionary(key => key, key => values[key]);
+ }
+ }
string tmp;
m_options.TryGetValue(ActionLevelOptionName, out tmp);
@@ -263,7 +286,7 @@ namespace Duplicati.Library.Modules.Builtin
m_body = DEFAULT_BODY;
m_options.TryGetValue(LogFilterOptionName, out var logfilterstring);
- var filter = Utility.FilterExpression.ParseLogFilter(logfilterstring);
+ var filter = FilterExpression.ParseLogFilter(logfilterstring);
var logLevel = Utility.Utility.ParseEnumOption(m_options, LogLevelOptionName, DEFAULT_LOG_LEVEL);
m_logstorage = new FileBackedStringList();
@@ -439,7 +462,7 @@ namespace Duplicati.Library.Modules.Builtin
extra[key] = GetDefaultValue(key);
// Add any options that are whitelisted or used in the template
- foreach (KeyValuePair kv in m_options)
+ foreach (var kv in m_options)
if (EXTRA_TEMPLATE_KEYS.Contains(kv.Key) || input.IndexOf($"%{kv.Key}%", StringComparison.OrdinalIgnoreCase) >= 0)
extra[kv.Key] = kv.Value;
@@ -448,6 +471,10 @@ namespace Duplicati.Library.Modules.Builtin
if (!extra.ContainsKey(key))
extra[key] = GetDefaultValue(key);
+ if (m_extraValues != null)
+ foreach (var v in m_extraValues)
+ extra[v.Key] = v.Value;
+
return resultFormatSerializer.Serialize(result, exception, LogLines, extra);
}
else
@@ -473,6 +500,11 @@ namespace Duplicati.Library.Modules.Builtin
if (!m_options.ContainsKey(key))
input = Regex.Replace(input, $"%{key}%", GetDefaultValue(key) ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+ if (m_extraValues != null)
+ foreach (var v in m_extraValues)
+ input = Regex.Replace(input, $"%{v.Key}%", v.Value, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+
// Remove any remaining template keys
input = Regex.Replace(input, "\\%[^\\%]+\\%", "");
return input;
diff --git a/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
index 6bd57fdec..1f16ac323 100644
--- a/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
+++ b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
@@ -211,36 +211,31 @@ namespace Duplicati.Library.Modules.Builtin
///
/// Gets a list of supported commandline arguments
///
- public override IList SupportedCommands
- {
- get
- {
- return new List(new ICommandLineArgument[] {
- new CommandLineArgument(OPTION_URL, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlShort, Strings.SendHttpMessage.SendhttpurlLong),
- new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageShort, Strings.SendHttpMessage.SendhttpmessageLong, DEFAULT_BODY),
- new CommandLineArgument(OPTION_MESSAGE_PARAMETER_NAME, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageparameternameShort, Strings.SendHttpMessage.SendhttpmessageparameternameLong, DEFAULT_MESSAGE_PARAMETER_NAME),
- new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpextraparametersShort, Strings.SendHttpMessage.SendhttpextraparametersLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttplevelShort, Strings.SendHttpMessage.SendhttplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
- new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.SendhttpanyoperationShort, Strings.SendHttpMessage.SendhttpanyoperationLong),
+ public override IList SupportedCommands =>
+ [
+ new CommandLineArgument(OPTION_URL, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlShort, Strings.SendHttpMessage.SendhttpurlLong),
+ new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageShort, Strings.SendHttpMessage.SendhttpmessageLong, DEFAULT_BODY),
+ new CommandLineArgument(OPTION_MESSAGE_PARAMETER_NAME, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpmessageparameternameShort, Strings.SendHttpMessage.SendhttpmessageparameternameLong, DEFAULT_MESSAGE_PARAMETER_NAME),
+ new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpextraparametersShort, Strings.SendHttpMessage.SendhttpextraparametersLong),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttplevelShort, Strings.SendHttpMessage.SendhttplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
+ new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.SendhttpanyoperationShort, Strings.SendHttpMessage.SendhttpanyoperationLong),
- new CommandLineArgument(OPTION_VERB, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.HttpverbShort, Strings.SendHttpMessage.HttpverbLong, "POST"),
- new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
- new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
- new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
+ new CommandLineArgument(OPTION_VERB, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.HttpverbShort, Strings.SendHttpMessage.HttpverbLong, "POST"),
+ new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
+ new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
+ new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
- new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
+ new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
- new CommandLineArgument(OPTION_URL_FORM, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlsformShort, Strings.SendHttpMessage.SendhttpurlsformLong),
- new CommandLineArgument(OPTION_URL_JSON, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlsjsonShort, Strings.SendHttpMessage.SendhttpurlsjsonLong),
+ new CommandLineArgument(OPTION_URL_FORM, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlsformShort, Strings.SendHttpMessage.SendhttpurlsformLong),
+ new CommandLineArgument(OPTION_URL_JSON, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.SendhttpurlsjsonShort, Strings.SendHttpMessage.SendhttpurlsjsonLong),
- new CommandLineArgument(OPTION_ACCEPT_ANY_CERTIFICATE, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.AcceptAnyCertificateShort, Strings.SendHttpMessage.AcceptAnyCertificateLong),
- new CommandLineArgument(OPTION_ACCEPT_SPECIFIED_CERTIFICATE, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.AcceptSpecifiedCertificateShort, Strings.SendHttpMessage.AcceptSpecifiedCertificateLong),
+ new CommandLineArgument(OPTION_ACCEPT_ANY_CERTIFICATE, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.AcceptAnyCertificateShort, Strings.SendHttpMessage.AcceptAnyCertificateLong),
+ new CommandLineArgument(OPTION_ACCEPT_SPECIFIED_CERTIFICATE, CommandLineArgument.ArgumentType.String, Strings.SendHttpMessage.AcceptSpecifiedCertificateShort, Strings.SendHttpMessage.AcceptSpecifiedCertificateLong),
- new CommandLineArgument(OPTION_SEND_HTTP_RETRIES, CommandLineArgument.ArgumentType.Integer, Strings.SendHttpMessage.SendHttpRetriesShort, Strings.SendHttpMessage.SendHttpRetriesLong, DEFAULT_RETRIES.ToString()),
- new CommandLineArgument(OPTION_SEND_HTTP_RETRY_DELAY, CommandLineArgument.ArgumentType.Integer, Strings.SendHttpMessage.SendHttpRetryDelayShort, Strings.SendHttpMessage.SendHttpRetryDelayLong, DEFAULT_RETRY_DELAY),
- });
- }
- }
+ new CommandLineArgument(OPTION_SEND_HTTP_RETRIES, CommandLineArgument.ArgumentType.Integer, Strings.SendHttpMessage.SendHttpRetriesShort, Strings.SendHttpMessage.SendHttpRetriesLong, DEFAULT_RETRIES.ToString()),
+ new CommandLineArgument(OPTION_SEND_HTTP_RETRY_DELAY, CommandLineArgument.ArgumentType.Integer, Strings.SendHttpMessage.SendHttpRetryDelayShort, Strings.SendHttpMessage.SendHttpRetryDelayLong, DEFAULT_RETRY_DELAY),
+ ];
protected override string SubjectOptionName => OPTION_MESSAGE;
protected override string BodyOptionName => OPTION_MESSAGE;
@@ -250,6 +245,7 @@ namespace Duplicati.Library.Modules.Builtin
protected override string LogFilterOptionName => OPTION_LOG_FILTER;
protected override string LogLinesOptionName => OPTION_MAX_LOG_LINES;
protected override string ResultFormatOptionName => OPTION_RESULT_FORMAT;
+ protected override string ExtraDataOptionName => OPTION_EXTRA_PARAMETERS;
///
/// This method is the interception where the module can interact with the execution environment and modify the settings.
diff --git a/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs b/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
index 81c54e07b..c740bd613 100644
--- a/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
+++ b/Duplicati/Library/Modules/Builtin/SendJabberMessage.cs
@@ -50,6 +50,11 @@ namespace Duplicati.Library.Modules.Builtin
/// Option used to specify report body
///
private const string OPTION_MESSAGE = "send-xmpp-message";
+ ///
+ /// Option used to specify extra parameters
+ ///
+ private const string OPTION_EXTRA_PARAMETERS = "send-xmpp-extra-parameters";
+
///
/// Option used to specify report level
///
@@ -133,26 +138,23 @@ namespace Duplicati.Library.Modules.Builtin
///
/// Gets a list of supported commandline arguments
///
- public override IList SupportedCommands
- {
- get
- {
- return new List(new ICommandLineArgument[] {
- new CommandLineArgument(OPTION_RECIPIENT, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpptoShort, Strings.SendJabberMessage.SendxmpptoLong),
- new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppmessageShort, Strings.SendJabberMessage.SendxmppmessageLong, DEFAULT_BODY),
- new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppusernameShort, Strings.SendJabberMessage.SendxmppusernameLong),
- new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpppasswordShort, Strings.SendJabberMessage.SendxmpppasswordLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpplevelShort, Strings.SendJabberMessage.SendxmpplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
- new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendJabberMessage.SendxmppanyoperationShort, Strings.SendJabberMessage.SendxmppanyoperationLong),
+ public override IList SupportedCommands =>
+ [
+ new CommandLineArgument(OPTION_RECIPIENT, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpptoShort, Strings.SendJabberMessage.SendxmpptoLong),
+ new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppmessageShort, Strings.SendJabberMessage.SendxmppmessageLong, DEFAULT_BODY),
+ new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppextraparametersShort, Strings.SendJabberMessage.SendxmppextraparametersLong),
+ new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmppusernameShort, Strings.SendJabberMessage.SendxmppusernameLong),
+ new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpppasswordShort, Strings.SendJabberMessage.SendxmpppasswordLong),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendJabberMessage.SendxmpplevelShort, Strings.SendJabberMessage.SendxmpplevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
+ new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendJabberMessage.SendxmppanyoperationShort, Strings.SendJabberMessage.SendxmppanyoperationLong),
- new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
- new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
- new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
+ new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
+ new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
+ new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
+
+ new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
+ ];
- new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
- });
- }
- }
protected override string SubjectOptionName => OPTION_MESSAGE;
protected override string BodyOptionName => OPTION_MESSAGE;
@@ -162,6 +164,7 @@ namespace Duplicati.Library.Modules.Builtin
protected override string LogFilterOptionName => OPTION_LOG_FILTER;
protected override string LogLinesOptionName => OPTION_MAX_LOG_LINES;
protected override string ResultFormatOptionName => OPTION_RESULT_FORMAT;
+ protected override string ExtraDataOptionName => OPTION_EXTRA_PARAMETERS;
///
/// This method is the interception where the module can interact with the execution environment and modify the settings.
diff --git a/Duplicati/Library/Modules/Builtin/SendMail.cs b/Duplicati/Library/Modules/Builtin/SendMail.cs
index 9dc2b9e03..d33b7964b 100644
--- a/Duplicati/Library/Modules/Builtin/SendMail.cs
+++ b/Duplicati/Library/Modules/Builtin/SendMail.cs
@@ -79,6 +79,11 @@ namespace Duplicati.Library.Modules.Builtin
/// Option used to specify what format the result is sent in.
///
private const string OPTION_RESULT_FORMAT = "send-mail-result-output-format";
+ ///
+ /// Option used to specify extra parameters
+ ///
+ private const string OPTION_EXTRA_PARAMETERS = "send-mail-extra-parameters";
+
///
/// Option used to set the log level for mail reports
///
@@ -150,29 +155,25 @@ namespace Duplicati.Library.Modules.Builtin
///
/// Gets a list of supported commandline arguments
///
- public override IList SupportedCommands
- {
- get
- {
- return new List(new ICommandLineArgument[] {
- new CommandLineArgument(OPTION_RECIPIENT, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionRecipientShort, Strings.SendMail.OptionRecipientLong),
- new CommandLineArgument(OPTION_SENDER, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSenderShort, Strings.SendMail.OptionSenderLong, DEFAULT_SENDER),
- new CommandLineArgument(OPTION_SUBJECT, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSubjectShort, Strings.SendMail.OptionSubjectLong(OPTION_BODY), DEFAULT_SUBJECT),
- new CommandLineArgument(OPTION_BODY, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionBodyShort, Strings.SendMail.OptionBodyLong, DEFAULT_BODY),
- new CommandLineArgument(OPTION_SERVER, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionServerShort, Strings.SendMail.OptionServerLong),
- new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionUsernameShort, Strings.SendMail.OptionUsernameLong),
- new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionPasswordShort, Strings.SendMail.OptionPasswordLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSendlevelShort, Strings.SendMail.OptionSendlevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string [] { "All" }).ToArray()),
- new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.SendhttpanyoperationShort, Strings.SendHttpMessage.SendhttpanyoperationLong),
+ public override IList SupportedCommands =>
+ [
+ new CommandLineArgument(OPTION_RECIPIENT, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionRecipientShort, Strings.SendMail.OptionRecipientLong),
+ new CommandLineArgument(OPTION_SENDER, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSenderShort, Strings.SendMail.OptionSenderLong, DEFAULT_SENDER),
+ new CommandLineArgument(OPTION_SUBJECT, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSubjectShort, Strings.SendMail.OptionSubjectLong(OPTION_BODY), DEFAULT_SUBJECT),
+ new CommandLineArgument(OPTION_BODY, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionBodyShort, Strings.SendMail.OptionBodyLong, DEFAULT_BODY),
+ new CommandLineArgument(OPTION_SERVER, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionServerShort, Strings.SendMail.OptionServerLong),
+ new CommandLineArgument(OPTION_USERNAME, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionUsernameShort, Strings.SendMail.OptionUsernameLong),
+ new CommandLineArgument(OPTION_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionPasswordShort, Strings.SendMail.OptionPasswordLong),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendMail.OptionSendlevelShort, Strings.SendMail.OptionSendlevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string [] { "All" }).ToArray()),
+ new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendHttpMessage.SendhttpanyoperationShort, Strings.SendHttpMessage.SendhttpanyoperationLong),
+ new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendMail.SendmailextraparametersShort, Strings.SendMail.SendmailextraparametersLong),
- new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
- new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
- new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
+ new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
+ new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
+ new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
- new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
- });
- }
- }
+ new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
+ ];
protected override string SubjectOptionName => OPTION_SUBJECT;
protected override string BodyOptionName => OPTION_BODY;
@@ -182,6 +183,7 @@ namespace Duplicati.Library.Modules.Builtin
protected override string LogFilterOptionName => OPTION_LOG_FILTER;
protected override string LogLinesOptionName => OPTION_MAX_LOG_LINES;
protected override string ResultFormatOptionName => OPTION_RESULT_FORMAT;
+ protected override string ExtraDataOptionName => OPTION_EXTRA_PARAMETERS;
///
/// This method is the interception where the module can interact with the execution environment and modify the settings.
diff --git a/Duplicati/Library/Modules/Builtin/SendTelegramMessage.cs b/Duplicati/Library/Modules/Builtin/SendTelegramMessage.cs
index b4a73948a..5f7323f5c 100644
--- a/Duplicati/Library/Modules/Builtin/SendTelegramMessage.cs
+++ b/Duplicati/Library/Modules/Builtin/SendTelegramMessage.cs
@@ -75,6 +75,10 @@ public class SendTelegramMessage : ReportHelper
/// Option used to specify what format the result is sent in.
///
private const string OPTION_RESULT_FORMAT = "send-telegram-result-output-format";
+ ///
+ /// Option used to specify extra parameters
+ ///
+ private const string OPTION_EXTRA_PARAMETERS = "send-telegram-extra-parameters";
///
/// Option used to set the log level
@@ -88,7 +92,7 @@ public class SendTelegramMessage : ReportHelper
/// Option used to set the maximum number of log lines
///
private const string OPTION_MAX_LOG_LINES = "send-telegram-max-log-lines";
-
+
///
/// Telegram message maximum length.
///
@@ -135,21 +139,22 @@ public class SendTelegramMessage : ReportHelper
///
/// Gets a list of supported commandline arguments
///
- public override IList SupportedCommands
- => [
- new CommandLineArgument(OPTION_CHANNEL, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramChannelShort, Strings.SendTelegramMessage.SendTelegramChannelLong),
- new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramMessageShort, Strings.SendTelegramMessage.SendTelegramMessageLong, DEFAULT_BODY),
- new CommandLineArgument(OPTION_BOTID, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramBotIdShort, Strings.SendTelegramMessage.SendTelegramBotIdLong),
- new CommandLineArgument(OPTION_APIKEY, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramApiKeyShort, Strings.SendTelegramMessage.SendTelegramApiKeyLong),
- new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramLevelShort, Strings.SendTelegramMessage.SendTelegramlevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
- new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendTelegramMessage.SendTelegramManyOperationShort, Strings.SendTelegramMessage.SendTelegramManyOperationLong),
- new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
- new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
- new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
- new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
- new CommandLineArgument(OPTION_TOPICID, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramTopicShort, Strings.SendTelegramMessage.SendTelegramTopicLong),
- ];
-
+ public override IList SupportedCommands =>
+ [
+ new CommandLineArgument(OPTION_CHANNEL, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramChannelShort, Strings.SendTelegramMessage.SendTelegramChannelLong),
+ new CommandLineArgument(OPTION_MESSAGE, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramMessageShort, Strings.SendTelegramMessage.SendTelegramMessageLong, DEFAULT_BODY),
+ new CommandLineArgument(OPTION_EXTRA_PARAMETERS, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramExtraParametersShort, Strings.SendTelegramMessage.SendTelegramExtraParametersLong),
+ new CommandLineArgument(OPTION_BOTID, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramBotIdShort, Strings.SendTelegramMessage.SendTelegramBotIdLong),
+ new CommandLineArgument(OPTION_APIKEY, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramApiKeyShort, Strings.SendTelegramMessage.SendTelegramApiKeyLong),
+ new CommandLineArgument(OPTION_SENDLEVEL, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramLevelShort, Strings.SendTelegramMessage.SendTelegramlevelLong(ParsedResultType.Success.ToString(), ParsedResultType.Warning.ToString(), ParsedResultType.Error.ToString(), ParsedResultType.Fatal.ToString(), "All"), DEFAULT_LEVEL, null, Enum.GetNames(typeof(ParsedResultType)).Union(new string[] { "All" } ).ToArray()),
+ new CommandLineArgument(OPTION_SENDALL, CommandLineArgument.ArgumentType.Boolean, Strings.SendTelegramMessage.SendTelegramManyOperationShort, Strings.SendTelegramMessage.SendTelegramManyOperationLong),
+ new CommandLineArgument(OPTION_LOG_LEVEL, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.OptionLoglevelShort, Strings.ReportHelper.OptionLoglevelLong, DEFAULT_LOG_LEVEL.ToString(), null, Enum.GetNames(typeof(Logging.LogMessageType))),
+ new CommandLineArgument(OPTION_LOG_FILTER, CommandLineArgument.ArgumentType.String, Strings.ReportHelper.OptionLogfilterShort, Strings.ReportHelper.OptionLogfilterLong),
+ new CommandLineArgument(OPTION_MAX_LOG_LINES, CommandLineArgument.ArgumentType.Integer, Strings.ReportHelper.OptionmaxloglinesShort, Strings.ReportHelper.OptionmaxloglinesLong, DEFAULT_LOGLINES.ToString()),
+ new CommandLineArgument(OPTION_RESULT_FORMAT, CommandLineArgument.ArgumentType.Enumeration, Strings.ReportHelper.ResultFormatShort, Strings.ReportHelper.ResultFormatLong(Enum.GetNames(typeof(ResultExportFormat))), DEFAULT_EXPORT_FORMAT.ToString(), null, Enum.GetNames(typeof(ResultExportFormat))),
+ new CommandLineArgument(OPTION_TOPICID, CommandLineArgument.ArgumentType.String, Strings.SendTelegramMessage.SendTelegramTopicShort, Strings.SendTelegramMessage.SendTelegramTopicLong),
+ ];
+
protected override string SubjectOptionName => OPTION_MESSAGE;
protected override string BodyOptionName => OPTION_MESSAGE;
protected override string ActionLevelOptionName => OPTION_SENDLEVEL;
@@ -158,6 +163,7 @@ public class SendTelegramMessage : ReportHelper
protected override string LogFilterOptionName => OPTION_LOG_FILTER;
protected override string LogLinesOptionName => OPTION_MAX_LOG_LINES;
protected override string ResultFormatOptionName => OPTION_RESULT_FORMAT;
+ protected override string ExtraDataOptionName => OPTION_EXTRA_PARAMETERS;
///
/// The server username
@@ -195,14 +201,14 @@ public class SendTelegramMessage : ReportHelper
}
#endregion
-
+
///
protected override string ReplaceTemplate(string input, object result, Exception exception, bool subjectline)
{
// No need to do the expansion as we throw away the result
return subjectline ? string.Empty : base.ReplaceTemplate(input, result, exception, subjectline);
}
-
+
///
/// Sends message to telegram
///
@@ -213,13 +219,13 @@ public class SendTelegramMessage : ReportHelper
try
{
if (string.IsNullOrEmpty(body))
- return;
-
+ return;
+
// Combine subject and body
body = string.Join(Environment.NewLine, subject, body);
// Split message into chunks if needed
- var messages = body.Length <= TELEGRAM_MAX_LENGTH
+ var messages = body.Length <= TELEGRAM_MAX_LENGTH
? [body]
: Enumerable.Range(0, (body.Length + TELEGRAM_MAX_LENGTH - 1) / TELEGRAM_MAX_LENGTH)
.Select(i => body.Substring(
@@ -233,11 +239,11 @@ public class SendTelegramMessage : ReportHelper
}
catch (Exception e)
{
- Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", e,
+ Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", e,
"Failed to process message for telegram: {0}", e.Message);
}
}
-
+
///
/// Sends the message/partial message to telegram
///
@@ -252,13 +258,13 @@ public class SendTelegramMessage : ReportHelper
throw new Exception("Telegram Bot ID is required and not set");
if (string.IsNullOrWhiteSpace(m_apikey))
throw new Exception("Telegram API Key is required and not set");
-
+
var p = new
{
chat_id = Uri.EscapeDataString(m_channelId),
message_thread_id = string.IsNullOrWhiteSpace(m_topicId) ? null : Uri.EscapeDataString(m_topicId),
parse_mode = "Markdown",
- text = Uri.EscapeDataString(totalParts > 1
+ text = Uri.EscapeDataString(totalParts > 1
? $"Part {partNumber}/{totalParts}:\n{message}"
: message),
botId = Uri.EscapeDataString(m_botid),
@@ -268,7 +274,7 @@ public class SendTelegramMessage : ReportHelper
var baseUrl = $"https://api.telegram.org/bot{p.botId}:{p.apiKey}/sendMessage";
var url = $"{baseUrl}?chat_id={p.chat_id}&parse_mode={p.parse_mode}&text={p.text}" +
$"{(!string.IsNullOrWhiteSpace(m_topicId) ? $"&message_thread_id={m_topicId}" : string.Empty)}";
-
+
using var timeoutToken = new CancellationTokenSource();
timeoutToken.CancelAfter(REQUEST_TIMEOUT);
@@ -277,14 +283,14 @@ public class SendTelegramMessage : ReportHelper
var responseContent = await response.Content.ReadAsStringAsync(timeoutToken.Token).ConfigureAwait(false);
if (!responseContent.Contains("\"ok\":true"))
- Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", null,
- "Failed to send to telegram messages part {0}/{1}: {2}",
+ Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", null,
+ "Failed to send to telegram messages part {0}/{1}: {2}",
partNumber, totalParts, responseContent);
}
catch (Exception e)
{
- Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", e,
- "Failed to send to telegram messages part {0}/{1}: {2}",
+ Logging.Log.WriteWarningMessage(LOGTAG, "telegramSendError", e,
+ "Failed to send to telegram messages part {0}/{1}: {2}",
partNumber, totalParts, e.Message);
}
}
diff --git a/Duplicati/Library/Modules/Builtin/Strings.cs b/Duplicati/Library/Modules/Builtin/Strings.cs
index bcd66b666..b89368802 100644
--- a/Duplicati/Library/Modules/Builtin/Strings.cs
+++ b/Duplicati/Library/Modules/Builtin/Strings.cs
@@ -136,6 +136,8 @@ To enable SMTP over SSL, use the format smtps://example.com. To enable SMTP STAR
public static string SendMailLog(string message) { return LC.L(@"Whole SMTP communication: {0}", message); }
public static string SendMailFailedRetryError(string failedserver, string message, string retryserver) { return LC.L(@"Failed to send email with server: {0}, message: {1}, retrying with {2}", failedserver, message, retryserver); }
public static string SendMailSuccess(string server) { return LC.L(@"Email sent successfully using server: {0}", server); }
+ public static string SendmailextraparametersLong { get { return LC.L(@"Use this option to set extra parameters for the message body. This parameter can either be a querystring (e.g. 'parameter1=value1¶meter2=value2') or a JSON key/value object."); } }
+ public static string SendmailextraparametersShort { get { return LC.L(@"Extra parameters for the message sent"); } }
}
internal static class SendJabberMessage
{
@@ -163,6 +165,8 @@ You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The sp
public static string SendxmppanyoperationLong { get { return LC.L(@"By default, messages will only be sent after a backup operation. Use this option to send messages for all operations."); } }
public static string SendxmppanyoperationShort { get { return LC.L(@"Send messages for all operations"); } }
public static string LoginTimeoutError { get { return LC.L(@"Timeout occurred while logging in to jabber server"); } }
+ public static string SendxmppextraparametersLong { get { return LC.L(@"Use this option to set extra parameters for the message body. This parameter can either be a querystring (e.g. 'parameter1=value1¶meter2=value2') or a JSON key/value object."); } }
+ public static string SendxmppextraparametersShort { get { return LC.L(@"Extra parameters for the message sent"); } }
}
internal static class SendTelegramMessage
@@ -194,6 +198,8 @@ You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The sp
public static string SendTelegramLevelShort => LC.L(@"The messages to send");
public static string SendTelegramManyOperationLong => LC.L(@"By default, messages will only be sent after a backup operation. Use this option to send messages for all operations.");
public static string SendTelegramManyOperationShort => LC.L(@"Send messages for all operations");
+ public static string SendTelegramExtraParametersLong { get { return LC.L(@"Use this option to set extra parameters for the message body. This parameter can either be a querystring (e.g. 'parameter1=value1¶meter2=value2') or a JSON key/value object."); } }
+ public static string SendTelegramExtraParametersShort { get { return LC.L(@"Extra parameters for the message sent"); } }
}
internal static class SendHttpMessage
@@ -214,8 +220,8 @@ All command line options are also reported within %value%, e.g. %volsize%. Any u
public static string SendhttpmessageShort { get { return LC.L(@"The message template"); } }
public static string SendhttpmessageparameternameLong { get { return LC.L(@"Use this option to set a name of the parameter to send the message as."); } }
public static string SendhttpmessageparameternameShort { get { return LC.L(@"The name of the parameter to send the message as"); } }
- public static string SendhttpextraparametersLong { get { return LC.L(@"Use this option to set extra parameters to add to the http message, e.g. ""parameter1=value1¶meter2=value2"""); } }
- public static string SendhttpextraparametersShort { get { return LC.L(@"Extra parameters to add to the http message"); } }
+ public static string SendhttpextraparametersLong { get { return LC.L(@"Use this option to set extra parameters for the message body. This parameter can either be a querystring (e.g. 'parameter1=value1¶meter2=value2') or a JSON key/value object."); } }
+ public static string SendhttpextraparametersShort { get { return LC.L(@"Extra parameters for the message sent"); } }
public static string SendhttplevelLong(string success, string warning, string error, string fatal, string all) { return LC.L(@"You can specify one of ""{0}"", ""{1}"", ""{2}"", ""{3}"".
You can supply multiple options with a comma separator, e.g. ""{0},{1}"". The special value ""{4}"" is a shorthand for ""{0},{1},{2},{3}"" and will cause all backup operations to send a message.", success, warning, error, fatal, all); }
public static string SendhttplevelShort { get { return LC.L(@"The messages to send"); } }