
by Snuggle Chat
Manage and Monitor your services with Uptime Robot https://uptimerobot.com/
README
UptimeRobot is a super useful free service monitoring service. This skill is the beginning of support for querying/configuring the monitors in your UptimeRobot account.
Required Secrets
api-key
API key from UptimeRobot. Full read/write permissions expected. Get an API key from My Settings page → API Settings section → Main API Key.
Triggers
This skill can respond to post to channels when UptimeRobot detects that a monitor has gone up/down. To do this a Webhook Alert needs to be added to UptimeRobot and configured in a specific way that Abbot can recognize it.
Add a Trigger
- In a channel in your chat platform ask Abbot to attach to the channel.
@abbot attach uptimerobot
Abbot will respond with a link to manage your triggers. Follow the link and note the trigger url for the channel you just attached. - In the My Settings page of UptimeRobot, Add Alert Contact in the Alert Contacts section. And fill out the following details:
- Alert Contact Type: Webhook
- Friendly Name: < Whatever you want to call this alert >
- URL to Notify: < The url noted from step 1 >
- POST Value:
{"stat":"ok"}
(This was the only way I could find to convince UptimeRobot to trigger the Webhook with POST rather than GET. Abbot only listens for POST requests.) - Check “Send as JSON …”
- Enable notifications for: < Select your preference >
- Get SSL expiration reminder notifications: Unchecked (this isn’t supported by the skill yet).
- Create Alert Contact!
- In the My Settings page of UptimeRobot add the new Webhook alert to all the Minitors that you wish to have trigger this skill. (Note: There’s a Bulk Actions link towards the top of the Monitor list that allows you to add the alert to all your Monitors at once.)
Usage
@abbot uptimerobot list
– Lists all monitors and their current status.
@abbot uptimerobot new {type} {url/ip} {name}
– Create a new monitor. Currently only supports type 3 (PING). Do not include protocol in URL.
@abbot uptimerobot delete {id}
– Delete monitor. WARNING: Minimal error protection, be careful!
@abbot uptimerobot set {id} {key} {value}
– Edit the some property of a monitor. (Note: Monitor type cannot be changed.)
Code
readonly Dictionary<Status, string> StatusEmoji = new Dictionary<Status, string> {
{Status.Unknown, “❔”},
{Status.Paused, “⏸”},
{Status.NotChecked, “⌛”},
{Status.Up, “🟢”},
{Status.SeemsDown, “❗”},
{Status.Down, “❌”}
};
// Handle HTTP Triggers for up/down alerts from Uptime Robot
// TODO: check queries has all the data that is expected
if (Bot.IsRequest)
{
var queries = Bot.Request.Query;
Status status = String.Join(“”, queries[“alertType”]) switch {
“1” => Status.Down,
“2” => Status.Up,
_ => Status.Unknown,
};
var friendlyStatus = String.Join(“”, queries[“alertTypeFriendlyName”]);
var friendlyName = String.Join(“”, queries[“monitorFriendlyName”]);
var url = String.Join(“”, queries[“monitorURL”]);
var builder = new System.Text.StringBuilder();
builder.Append($”{StatusEmoji[status]} Monitor is {friendlyStatus}: {friendlyName} ( {url} ) {StatusEmoji[status]}”);
switch (status) {
case Status.Up:
var duration = String.Join(“”, queries[“alertFriendlyDuration”]);
builder.AppendLine($”Monitor was down for {duration}.”);
break;
case Status.Down:
var details = String.Join(“”, queries[“alertDetails”]);
builder.AppendLine($”Details: {details}”);
break;
}
await Bot.ReplyAsync(builder.ToString());
return;
}
var (command, arguments) = Bot.Arguments.Pop();
string output = command switch {
“list” => await ListMonitors(),
“new” => await NewMonitor(arguments),
“delete” => await DeleteMonitor(arguments),
“set” => await SetMonitor(arguments),
_ => “Unrecognized command.”,
};
await Bot.ReplyAsync(output);
class GetMonitorsData {
public string api_key;
}
async Task<dynamic> GetMonitors() {
var key = await Bot.Secrets.GetAsync(“api-key”);
return await Bot.Http.PostJsonAsync(“https://api.uptimerobot.com/v2/getMonitors”, new GetMonitorsData(){api_key = key});
}
async Task<string> ListMonitors() {
IEnumerable<dynamic> monitors = (await GetMonitors()).monitors;
var output = $”Monitors ({monitors.Count()})\n”;
output += String.Join(“\n”, monitors.Select(mon => $”{StatusEmoji[(Status)mon.status]} – {mon.friendly_name} (id: {mon.id})”));
return output;
}
class NewMonitorData {
public string api_key;
public string friendly_name;
public string url;
public string type;
}
async Task<string> NewMonitor(IArguments args) {
var (montype, url, name) = args;
// TODO: Support more than PING type
if (montype.Value != “3”)
return “Unsupported type.”;
// TODO: Check for http/https schemes and strip them if PING type. CheckHostName will fail if it sees them.
if (Uri.CheckHostName(url.Value) is not (UriHostNameType.IPv4 or UriHostNameType.IPv6 or UriHostNameType.Dns))
return “Invalid url.”;
if (String.IsNullOrEmpty(name.Value))
return “Invalid name.”;
var key = await Bot.Secrets.GetAsync(“api-key”);
var response = await Bot.Http.PostJsonAsync(“https://api.uptimerobot.com/v2/newMonitor”, new NewMonitorData(){api_key = key, friendly_name = name.Value, type = montype.Value, url = url.Value});
if (response.stat == “fail”)
return $”Failed to create monitor.\n{response.error.message}”;
return “Monitor Created”;
}
class DeleteMonitorData {
public string api_key;
public string id;
}
async Task<string> DeleteMonitor(IArguments args) {
var (id, _) = args.Pop();
if (String.IsNullOrEmpty(id))
return “Invalid id.”;
var key = await Bot.Secrets.GetAsync(“api-key”);
var response = await Bot.Http.PostJsonAsync(“https://api.uptimerobot.com/v2/deleteMonitor”, new DeleteMonitorData(){api_key = key, id = id});
if (response.stat == “fail”)
return $”Failed to delete monitor ‘{id}’.\n{response.error.message}”;
return “Monitor Deleted”;
}
async Task<string> SetMonitor(IArguments args) {
var (id, key, val) = args;
dynamic data = new ExpandoObject();
data.api_key = await Bot.Secrets.GetAsync(“api-key”);
data.id = id.Value;
// TODO: Check for keys supported by the uptimerobot api
(data as IDictionary<string, Object>).Add(key.Value, val.Value);
var response = await Bot.Http.PostJsonAsync(“https://api.uptimerobot.com/v2/editMonitor”, data as Object);
if (response.stat == “fail”)
return $”Failed to set ‘{key}’ to ‘{val}’ on monitor ‘{id}’.\n{response.error.message}”;
return $”‘{key}’ set to ‘{val}’ on monitor ‘{id}’.”;
}
Version History
Version | Created | Author | Release Notes | Installs |
---|---|---|---|---|
1.0.0 | 8/3/2021 |
![]() CapnRat |
Initial release. Support for listing/creating/deleting/modifying monitors. Support for http triggers. |
2 |
You need an account to install this package with Abbot. Signing in with Slack or Discord will create an account if you don’t have one already.
Details
-
Last updated -
Installs - 2 total installs
-
Language - CSharp
-
License - MIT License