
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