diff --git a/README.md b/README.md index ef1aa9c..cc54c51 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ conditions. ZNC Push current supports the following services: * [Pushover][] * [Prowl][] * [Supertoasty][] +* Custom URL GET requests This project is still a Work In Progress, but should be functional enough and stable enough for everyday usage. Users are more than welcome to submit feature requests or patches for @@ -189,6 +190,7 @@ to something similar to "http://domain/#channel/2011-03-09 14:25:09", or * "pushover" * "prowl" * "supertoasty" + * "url" * `username = ""` @@ -209,6 +211,12 @@ to something similar to "http://domain/#channel/2011-03-09 14:25:09", or When using Pushover, this option allows you to specify a single device name to send notifications to; if blank or unset, notifications will be sent to all devices. + When using URL, this options allows you to specify the URL to send a GET request + to, and has keyword expansion performed on portions of it, including the path and + any query parameter values. + + This option must be set when using URL. + ### Conditions diff --git a/push.cpp b/push.cpp index 07f2b68..39b604b 100644 --- a/push.cpp +++ b/push.cpp @@ -350,6 +350,71 @@ class CPushMod : public CModule params["image"] = "https://github.com/jreese/znc-push/raw/supertoasty/logo.png"; params["sender"] = "ZNC Push"; } + else if (service == "url") + { + if (options["target"] == "") + { + PutModule("Error: target (url) not set"); + return; + } + + int count; + VCString parts; + CString url = options["target"]; + + // Verify that the URL begins with either http:// or https:// + count = url.Split("://", parts, false); + + if (count != 2) + { + PutModule("Error: invalid url format"); + return; + } + + use_post = false; + + if (parts[0] == "https") + { + use_ssl = true; + use_port = 443; + } + else if (parts[0] == "http") + { + use_ssl = false; + use_port = 80; + } + else + { + PutModule("Error: invalid url schema"); + return; + } + + // Process the remaining portion of the URL + url = parts[1]; + + // Split out the host and optional port number; this breaks with raw IPv6 addresses + CString host = url.Token(0, false, "/"); + count = host.Split(":", parts, false); + + if (count > 1) + { + use_port = parts[1].ToInt(); + } + + service_host = parts[0]; + + // Split remaining URL into path and query components + url = "/" + url.Token(1, true, "/"); + service_url = expand(url.Token(0, false, "?"), replace); + + // Parse and expand query parameter values + url = url.Token(1, true, "?"); + url.URLSplit(params); + + for (MCString::iterator i = params.begin(); i != params.end(); i++) { + i->second = expand(i->second, replace); + } + } else { PutModule("Error: service type not selected"); @@ -977,6 +1042,10 @@ class CPushMod : public CModule { PutModule("Note: Supertoasty requires setting the 'secret' option with device id"); } + else if (value == "url") + { + PutModule("Note: URL requires setting the 'target' option with the full URL"); + } else { PutModule("Error: unknown service name");