const initialData = { | |
servers: [ | |
{ | |
url: 'https://1.example.com/', | |
title: 'Server 1', | |
online: null, | |
}, | |
{ | |
url: 'https://2.example.com/', | |
title: 'Server 2', | |
online: null, | |
}, | |
{ | |
url: 'https://3.example.com/', | |
title: 'Server 3', | |
online: null, | |
}, | |
], | |
lastUpdate: null | |
} | |
// Refresh Interval in seconds | |
const refreshInterval = 300 | |
const widget = await createWidget() | |
if (!config.runsInWidget) { | |
await widget.presentSmall() | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
async function createWidget(items) { | |
const data = await refresh() | |
const list = new ListWidget() | |
// uncomment the lines below if you want to show the header (not working with more than ~5 servers) | |
// const header = list.addText("Server Status") | |
// header.font = Font.mediumSystemFont(13) | |
// list.addSpacer() | |
data.servers.forEach((server) => { | |
const label = list.addText((server.online ? '🟢' : (server.online === false ? '🔴' : '❔')) + ' ' + server.title) | |
label.font = Font.boldSystemFont(12) | |
label.textColor = Color.gray() | |
list.refreshAfterDate = new Date(Date.now() + refreshInterval) | |
list.addSpacer(3) | |
}) | |
if (data.lastUpdate) { | |
list.addSpacer() | |
const lastRefreshLabel = list.addText('Last refresh: ' + data.lastUpdate) | |
lastRefreshLabel.font = Font.mediumSystemFont(8) | |
} | |
return list | |
} | |
async function refresh() { | |
let data = initialData | |
for (let server of data.servers) { | |
try { | |
let response = await new Request(server.url).loadString() | |
server.online = response && response.length > 0 | |
} catch (e) { | |
server.online = false | |
} | |
} | |
let now = new Date() | |
let hours = now.getHours() | |
let mins = now.getMinutes() | |
data.lastUpdate = (hours > 9 ? hours : '0' + hours) + ':' + (mins > 9 ? mins : '0' + mins) | |
return data | |
} |
Thanks for sharing! A timeout would be great indeed, unfortunately I didn't find anything in the Scriptable docs at the first sight using the default methods… Not sure if it's possible to perform own http requests there, but I might check that out. Also the string response comparison is not really nice. I tried to check the http status code using load()
instead of loadString()
but couldn't get any useful response from there.
I a'm added push notifications for down servers and add HTTP status codes from response.
const initialData = {
servers: [
{
url: 'https://server1.com/',
title: 'server1',
online: null,
},
{
url: 'https://server2.com/',
title: 'server2',
online: null,
},
],
lastUpdate: null
}
// Refresh Interval in seconds
const refreshInterval = 300
const widget = await createWidget()
if (!config.runsInWidget) {
await widget.presentLarge()
}
Script.setWidget(widget)
Script.complete()
async function createWidget(items) {
const data = await refresh()
const list = new ListWidget()
// uncomment the lines below if you want to show the header (not working with more than ~5 servers)
// const header = list.addText("Server Status")
// header.font = Font.mediumSystemFont(13)
// list.addSpacer()
await data.servers.forEach((server) => {
let status = '';
if (String(server.online).indexOf('20') !== -1 || String(server.online).indexOf('30') !== -1) {
status = '🟢 ' + server.online + ' ' + server.title
} else {
status = '🔴 ' + server.online + ' ' + server.title
sendNotification(server)
}
const label = list.addText(status)
label.font = Font.boldSystemFont(12)
label.textColor = Color.gray()
list.refreshAfterDate = new Date(Date.now() + refreshInterval)
list.addSpacer(3)
})
if (data.lastUpdate) {
list.addSpacer()
const lastRefreshLabel = list.addText('Last refresh: ' + data.lastUpdate)
lastRefreshLabel.font = Font.mediumSystemFont(8)
}
return list
}
async function refresh() {
let data = initialData
for (let server of data.servers) {
let request = new Request(server.url)
request.method = 'GET'
try {
await request.load()
server.online = request.response.statusCode
} catch (response) {
server.online = 0
}
}
let now = new Date()
let hours = now.getHours()
let mins = now.getMinutes()
data.lastUpdate = (hours > 9 ? hours : '0' + hours) + ':' + (mins > 9 ? mins : '0' + mins)
return data
}
async function sendNotification(server) {
let alert = new Notification()
alert.sound = 'failure'
alert.title = 'Server down'
alert.body = 'Status of server "' + server.title + '" is ' + server.online
alert.openURL = server.url
await alert.schedule()
}
I a'm added push notifications for down servers and add HTTP status codes from response.
@MrTheFirst Thanks, this is a great extension to the initial script. Would you mind if I adopt your notification functionality in the gist?
@MrTheFirst Thanks, this is a great extension to the initial script. Would you mind if I adopt your notification functionality in the gist?
Of course use it! I just used the notification from the documentation. But I noticed an error in my script, if the server is not available, then a lot of notifications come (it seems as much as there are servers in the settings). This is because of the asynchronous functions in the loops.
I wanted to add ip addresses instead of http and for some reason it doesn't work. Help me how to do this?
@Sergey20482048 I used the above script with IP addresses by just using http://192.168.1.1/ in the server line , but my servers have a web page that you land on when you navigate to that IP. I'm not sure if yours are running a web server..
Does anyone know how to make this script use two columns so I can squeeze in two columns of 4 servers each?
hello, what struck me, a time out is missing ... if a page / server cannot be reached, the request runs for a very long time until the iOS time out comes. can you build in your own time out here and configure it with repetition?
for example: error if there is no answer for more than 15 seconds after 3 repetitions?
I adjusted the code a little ...
but I like it a lot and is simply built