diff --git a/21a49e2b.22741553.js b/21a49e2b.22741553.js deleted file mode 100644 index 164698d..0000000 --- a/21a49e2b.22741553.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{66:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return l})),a.d(t,"metadata",(function(){return c})),a.d(t,"rightToc",(function(){return O})),a.d(t,"default",(function(){return j}));var b=a(2),n=a(6),r=(a(0),a(96)),l={title:"Notifications"},c={unversionedId:"notifications",id:"notifications",isDocsHomePage:!1,title:"Notifications",description:"Using notifications, you can alert your team when an endpoint goes down or experiences degraded performance. To add notifications, you have to add environment variables as GitHub repository secrets (Settings -> Secrets -> Actions) and add Environment variable as your Secret name and Value in environment variable as value in secret. DO NOT select Variables select Secret(see Creating and storing encrypted secrets).",source:"@site/docs/notifications.md",slug:"/notifications",permalink:"/docs/notifications",editUrl:"https://github.com/upptime/upptime.js.org/blob/master/docs/notifications.md",version:"current",sidebar:"sidebar",previous:{title:"Triggers",permalink:"/docs/triggers"},next:{title:"Badges",permalink:"/docs/badges"}},O=[{value:"Strategy",id:"strategy",children:[]},{value:"Providers",id:"providers",children:[{value:"Slack",id:"slack",children:[]},{value:"Telegram",id:"telegram",children:[]},{value:"Discord",id:"discord",children:[]},{value:"Zulip",id:"zulip",children:[]},{value:"Microsoft Teams",id:"microsoft-teams",children:[]},{value:"Email",id:"email",children:[]},{value:"SMS",id:"sms",children:[]}]}],i={rightToc:O};function j(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(b.a)({},i,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)("p",null,"Using notifications, you can alert your team when an endpoint goes down or experiences degraded performance. To add notifications, you have to add environment variables as ",Object(r.b)("strong",{parentName:"p"},"GitHub repository secrets")," (",Object(r.b)("em",{parentName:"p"},"Settings")," -> ",Object(r.b)("em",{parentName:"p"},"Secrets")," -> ",Object(r.b)("em",{parentName:"p"},"Actions"),") and add ",Object(r.b)("em",{parentName:"p"},"Environment variable")," as your ",Object(r.b)("em",{parentName:"p"},"Secret name")," and ",Object(r.b)("em",{parentName:"p"},"Value")," in environment variable as ",Object(r.b)("em",{parentName:"p"},"value")," in secret. DO NOT select ",Object(r.b)("inlineCode",{parentName:"p"},"Variables")," select ",Object(r.b)("strong",{parentName:"p"},"Secret"),"(see ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets"}),"Creating and storing encrypted secrets"),")."),Object(r.b)("p",null,Object(r.b)("img",Object(b.a)({parentName:"p"},{src:"https://user-images.githubusercontent.com/22931360/232315630-59689bdd-6c88-4454-9fd8-8eb64844f968.png",alt:"Secrets"}))),Object(r.b)("p",null,"Every time an endpoint goes down, a notification with the following text is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe5 Example Site (",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://example.koj.co"}),"https://example.koj.co"),") is ",Object(r.b)("strong",{parentName:"p"},"down"),": ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/upptime/upptime/issues/4"}),"https://github.com/upptime/upptime/issues/4"))),Object(r.b)("p",null,"If it experiences degraded performance, a notification with the following text is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe8 Example Site (",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://example.koj.co"}),"https://example.koj.co"),") has ",Object(r.b)("strong",{parentName:"p"},"degraded performance"),": ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/upptime/upptime/issues/4"}),"https://github.com/upptime/upptime/issues/4"))),Object(r.b)("p",null,"When it comes back up, another notification is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe9 Example Site is back up.")),Object(r.b)("h2",{id:"strategy"},"Strategy"),Object(r.b)("p",null,"If you have more than one configurations of each provider (say multiple email configurations, both SMTP and SES), you can choose the strategy. For each notification provider (Slack, email, etc.), you can specify the strategy using the ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_{PROVIDER}_STRATEGY")," environment variable, where ",Object(r.b)("inlineCode",{parentName:"p"},"{PROVIDER}")," is the constant-case service name, for example ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_SLACK_STRATEGY"),". The strategy can be any one of:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Description"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"fallback")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"If one provider returns an error, try the next")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"roundrobin")," (default)"),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Use every provider in turns")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"no-fallback")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Deactivates fallback strategy")))),Object(r.b)("p",null,"More information is available on the ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/notifme/notifme-sdk#multi-provider-strategies"}),"Multi-provider strategies")," page in the documentation."),Object(r.b)("h2",{id:"providers"},"Providers"),Object(r.b)("p",null,"For each notification type (Slack, email, etc.), you need to first enable it by setting the ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_{PROVIDER}")," to ",Object(r.b)("inlineCode",{parentName:"p"},"true"),", where ",Object(r.b)("inlineCode",{parentName:"p"},"{PROVIDER}")," is the constant-case service name, for example ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_SLACK"),". Each notification type also requires additional environment variables. See the examples below."),Object(r.b)("h3",{id:"slack"},"Slack"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK_WEBHOOK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Slack webhook URL")))),Object(r.b)("p",null,"To create a Slack webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://slack.com/intl/en-in/help/articles/115005265063-Incoming-webhooks-for-Slack"}),"Incoming webhooks for Slack")," on the Slack website."),Object(r.b)("h3",{id:"telegram"},"Telegram"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM_BOT_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Your bot key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM_CHAT_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Your chat ID")))),Object(r.b)("p",null,"To create a Telegram bot key, see the documentation for ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://core.telegram.org/bots#6-botfather"}),"Botfather")," on the Telegram Support website."),Object(r.b)("h3",{id:"discord"},"Discord"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD_WEBHOOK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Discord webhook URL")))),Object(r.b)("p",null,"To create a Discord webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"}),"Intro to Webhooks")," on the Discord Support website."),Object(r.b)("h3",{id:"zulip"},"Zulip"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_MESSAGE_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Zulip Message API URL")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_API_EMAIL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Email of the Zulip bot")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"API Key of the Zulip bot")))),Object(r.b)("p",null,"To create a Zulip Incoming Webhook bot, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://zulip.com/help/add-a-bot-or-integration"}),"Add a bot or integration")," in the Zulip docs.\nThe ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_ZULIP_MESSAGE_URL")," should include the ",Object(r.b)("inlineCode",{parentName:"p"},"type"),", ",Object(r.b)("inlineCode",{parentName:"p"},"to")," and ",Object(r.b)("inlineCode",{parentName:"p"},"topic")," query params and would look something like this:\n",Object(r.b)("inlineCode",{parentName:"p"},"https://domain.zulipchat.com/api/v1/messages?type=stream&to=general&topic=Upptime%20notifications"),"."),Object(r.b)("h3",{id:"microsoft-teams"},"Microsoft Teams"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TEAMS")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TEAMS_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Teams webhook URL")))),Object(r.b)("p",null,"To create a Microsoft Teams webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook"}),"Create Incoming Webhooks")," on the Microsoft Learn website."),Object(r.b)("h3",{id:"email"},"Email"),Object(r.b)("p",null,"To send an email, you can use SMTP or a hosted service such as AWS SES, Sendgrid, Sparkpost, or Mailgun."),Object(r.b)("p",null,"All services require you to specify the email address from and to:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_FROM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"From" email address')),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_TO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"To" email address')))),Object(r.b)("h4",{id:"sendgrid"},"Sendgrid"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SENDGRID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SENDGRID_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Sendgrid API key")))),Object(r.b)("h4",{id:"aws-ses"},"AWS SES"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_REGION")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS region")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_ACCESS_KEY_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS access key ID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS secret access key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_SESSION_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS session token")))),Object(r.b)("h4",{id:"sparkpost"},"Sparkpost"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SPARKPOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SPARKPOST_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Sparkpost API key")))),Object(r.b)("h4",{id:"mailgun"},"Mailgun"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Mailgun API key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Mailgun domain name")))),Object(r.b)("h4",{id:"smtp"},"SMTP"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_PORT")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Port")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_HOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Host")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Password")))),Object(r.b)("h3",{id:"sms"},"SMS"),Object(r.b)("p",null,"To send a text message, you can any one of several services: Callr, Clickatell, Infobip, Nexmo, OVH, Plivo, Twilio, or 46elks. You'll have to create an account at the service of your choice and provide authentication information as specified below."),Object(r.b)("p",null,"All services require you to specify the phone number from and to:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_FROM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"From" phone number')),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"To" phone number')))),Object(r.b)("h4",{id:"46elks"},"46elks"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS_API_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"46elks username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS_API_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"46elks password")))),Object(r.b)("h4",{id:"callr"},"Callr"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR_LOGIN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Callr login")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Callr password")))),Object(r.b)("h4",{id:"clickatell"},"Clickatell"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CLICKATELL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CLICKATELL_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Clickatell API key")))),Object(r.b)("h4",{id:"infobip"},"Infobip"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Infobip username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Infobip password")))),Object(r.b)("h4",{id:"nexmo"},"Nexmo"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Nexmo API key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO_API_SECRET")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Nexmo API secret")))),Object(r.b)("h4",{id:"ovh"},"OVH"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_APP_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH app key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_APP_SECRET")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH app secret")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_CONSUMER_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH consumer key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_ACCOUNT")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH account")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_HOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH host")))),Object(r.b)("h4",{id:"plivo"},"Plivo"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO_AUTH_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Plivo auth ID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO_AUTH_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Plivo auth token")))),Object(r.b)("h4",{id:"twilio"},"Twilio"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO_ACCOUNT_SID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Twilio account SID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO_AUTH_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Twilio auth token")))))}j.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/21a49e2b.a60d00d0.js b/21a49e2b.a60d00d0.js new file mode 100644 index 0000000..2dbf76b --- /dev/null +++ b/21a49e2b.a60d00d0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{66:function(e,t,a){"use strict";a.r(t),a.d(t,"frontMatter",(function(){return l})),a.d(t,"metadata",(function(){return c})),a.d(t,"rightToc",(function(){return O})),a.d(t,"default",(function(){return j}));var b=a(2),n=a(6),r=(a(0),a(96)),l={title:"Notifications"},c={unversionedId:"notifications",id:"notifications",isDocsHomePage:!1,title:"Notifications",description:"Using notifications, you can alert your team when an endpoint goes down or experiences degraded performance. To add notifications, you have to add environment variables as GitHub repository secrets (Settings -> Secrets -> Actions) and add Environment variable as your Secret name and Value in environment variable as value in secret. DO NOT select Variables select Secret(see Creating and storing encrypted secrets).",source:"@site/docs/notifications.md",slug:"/notifications",permalink:"/docs/notifications",editUrl:"https://github.com/upptime/upptime.js.org/blob/master/docs/notifications.md",version:"current",sidebar:"sidebar",previous:{title:"Triggers",permalink:"/docs/triggers"},next:{title:"Badges",permalink:"/docs/badges"}},O=[{value:"Strategy",id:"strategy",children:[]},{value:"Providers",id:"providers",children:[{value:"Slack",id:"slack",children:[]},{value:"Telegram",id:"telegram",children:[]},{value:"Discord",id:"discord",children:[]},{value:"Zulip",id:"zulip",children:[]},{value:"Microsoft Teams",id:"microsoft-teams",children:[]},{value:"Email",id:"email",children:[]},{value:"SMS",id:"sms",children:[]}]},{value:"Custom Notifications",id:"custom-notifications",children:[{value:"Environment Variables",id:"environment-variables",children:[]},{value:"Message Variables",id:"message-variables",children:[]}]}],i={rightToc:O};function j(e){var t=e.components,a=Object(n.a)(e,["components"]);return Object(r.b)("wrapper",Object(b.a)({},i,a,{components:t,mdxType:"MDXLayout"}),Object(r.b)("p",null,"Using notifications, you can alert your team when an endpoint goes down or experiences degraded performance. To add notifications, you have to add environment variables as ",Object(r.b)("strong",{parentName:"p"},"GitHub repository secrets")," (",Object(r.b)("em",{parentName:"p"},"Settings")," -> ",Object(r.b)("em",{parentName:"p"},"Secrets")," -> ",Object(r.b)("em",{parentName:"p"},"Actions"),") and add ",Object(r.b)("em",{parentName:"p"},"Environment variable")," as your ",Object(r.b)("em",{parentName:"p"},"Secret name")," and ",Object(r.b)("em",{parentName:"p"},"Value")," in environment variable as ",Object(r.b)("em",{parentName:"p"},"value")," in secret. DO NOT select ",Object(r.b)("inlineCode",{parentName:"p"},"Variables")," select ",Object(r.b)("strong",{parentName:"p"},"Secret"),"(see ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets"}),"Creating and storing encrypted secrets"),")."),Object(r.b)("p",null,Object(r.b)("img",Object(b.a)({parentName:"p"},{src:"https://user-images.githubusercontent.com/22931360/232315630-59689bdd-6c88-4454-9fd8-8eb64844f968.png",alt:"Secrets"}))),Object(r.b)("p",null,"Every time an endpoint goes down, a notification with the following text is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe5 Example Site (",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://example.koj.co"}),"https://example.koj.co"),") is ",Object(r.b)("strong",{parentName:"p"},"down"),": ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/upptime/upptime/issues/4"}),"https://github.com/upptime/upptime/issues/4"))),Object(r.b)("p",null,"If it experiences degraded performance, a notification with the following text is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe8 Example Site (",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://example.koj.co"}),"https://example.koj.co"),") has ",Object(r.b)("strong",{parentName:"p"},"degraded performance"),": ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/upptime/upptime/issues/4"}),"https://github.com/upptime/upptime/issues/4"))),Object(r.b)("p",null,"When it comes back up, another notification is sent:"),Object(r.b)("blockquote",null,Object(r.b)("p",{parentName:"blockquote"},"\ud83d\udfe9 Example Site is back up.")),Object(r.b)("h2",{id:"strategy"},"Strategy"),Object(r.b)("p",null,"If you have more than one configurations of each provider (say multiple email configurations, both SMTP and SES), you can choose the strategy. For each notification provider (Slack, email, etc.), you can specify the strategy using the ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_{PROVIDER}_STRATEGY")," environment variable, where ",Object(r.b)("inlineCode",{parentName:"p"},"{PROVIDER}")," is the constant-case service name, for example ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_SLACK_STRATEGY"),". The strategy can be any one of:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Description"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"fallback")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"If one provider returns an error, try the next")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"roundrobin")," (default)"),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Use every provider in turns")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"no-fallback")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Deactivates fallback strategy")))),Object(r.b)("p",null,"More information is available on the ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://github.com/notifme/notifme-sdk#multi-provider-strategies"}),"Multi-provider strategies")," page in the documentation."),Object(r.b)("h2",{id:"providers"},"Providers"),Object(r.b)("p",null,"For each notification type (Slack, email, etc.), you need to first enable it by setting the ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_{PROVIDER}")," to ",Object(r.b)("inlineCode",{parentName:"p"},"true"),", where ",Object(r.b)("inlineCode",{parentName:"p"},"{PROVIDER}")," is the constant-case service name, for example ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_SLACK"),". Each notification type also requires additional environment variables. See the examples below."),Object(r.b)("h3",{id:"slack"},"Slack"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK_WEBHOOK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SLACK_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Slack webhook URL")))),Object(r.b)("p",null,"To create a Slack webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://slack.com/intl/en-in/help/articles/115005265063-Incoming-webhooks-for-Slack"}),"Incoming webhooks for Slack")," on the Slack website."),Object(r.b)("h3",{id:"telegram"},"Telegram"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM_BOT_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Your bot key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TELEGRAM_CHAT_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Your chat ID")))),Object(r.b)("p",null,"To create a Telegram bot key, see the documentation for ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://core.telegram.org/bots#6-botfather"}),"Botfather")," on the Telegram Support website."),Object(r.b)("h3",{id:"discord"},"Discord"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD_WEBHOOK")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_DISCORD_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Discord webhook URL")))),Object(r.b)("p",null,"To create a Discord webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"}),"Intro to Webhooks")," on the Discord Support website."),Object(r.b)("h3",{id:"zulip"},"Zulip"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_MESSAGE_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Zulip Message API URL")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_API_EMAIL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Email of the Zulip bot")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_ZULIP_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"API Key of the Zulip bot")))),Object(r.b)("p",null,"To create a Zulip Incoming Webhook bot, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://zulip.com/help/add-a-bot-or-integration"}),"Add a bot or integration")," in the Zulip docs.\nThe ",Object(r.b)("inlineCode",{parentName:"p"},"NOTIFICATION_ZULIP_MESSAGE_URL")," should include the ",Object(r.b)("inlineCode",{parentName:"p"},"type"),", ",Object(r.b)("inlineCode",{parentName:"p"},"to")," and ",Object(r.b)("inlineCode",{parentName:"p"},"topic")," query params and would look something like this:\n",Object(r.b)("inlineCode",{parentName:"p"},"https://domain.zulipchat.com/api/v1/messages?type=stream&to=general&topic=Upptime%20notifications"),"."),Object(r.b)("h3",{id:"microsoft-teams"},"Microsoft Teams"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TEAMS")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_TEAMS_WEBHOOK_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Teams webhook URL")))),Object(r.b)("p",null,"To create a Microsoft Teams webhook URL, see the article ",Object(r.b)("a",Object(b.a)({parentName:"p"},{href:"https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook"}),"Create Incoming Webhooks")," on the Microsoft Learn website."),Object(r.b)("h3",{id:"email"},"Email"),Object(r.b)("p",null,"To send an email, you can use SMTP or a hosted service such as AWS SES, Sendgrid, Sparkpost, or Mailgun."),Object(r.b)("p",null,"All services require you to specify the email address from and to:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_FROM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"From" email address')),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_TO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"To" email address')))),Object(r.b)("h4",{id:"sendgrid"},"Sendgrid"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SENDGRID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SENDGRID_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Sendgrid API key")))),Object(r.b)("h4",{id:"aws-ses"},"AWS SES"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_REGION")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS region")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_ACCESS_KEY_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS access key ID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS secret access key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SES_SESSION_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"AWS session token")))),Object(r.b)("h4",{id:"sparkpost"},"Sparkpost"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SPARKPOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SPARKPOST_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Sparkpost API key")))),Object(r.b)("h4",{id:"mailgun"},"Mailgun"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Mailgun API key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Mailgun domain name")))),Object(r.b)("h4",{id:"smtp"},"SMTP"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_PORT")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Port")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_HOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Host")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_EMAIL_SMTP_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"SMTP Password")))),Object(r.b)("h3",{id:"sms"},"SMS"),Object(r.b)("p",null,"To send a text message, you can any one of several services: Callr, Clickatell, Infobip, Nexmo, OVH, Plivo, Twilio, or 46elks. You'll have to create an account at the service of your choice and provide authentication information as specified below."),Object(r.b)("p",null,"All services require you to specify the phone number from and to:"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_FROM")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"From" phone number')),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),'"To" phone number')))),Object(r.b)("h4",{id:"46elks"},"46elks"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS_API_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"46elks username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_46ELKS_API_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"46elks password")))),Object(r.b)("h4",{id:"callr"},"Callr"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR_LOGIN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Callr login")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CALLR_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Callr password")))),Object(r.b)("h4",{id:"clickatell"},"Clickatell"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CLICKATELL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_CLICKATELL_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Clickatell API key")))),Object(r.b)("h4",{id:"infobip"},"Infobip"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP_USERNAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Infobip username")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_INFOBIP_PASSWORD")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Infobip password")))),Object(r.b)("h4",{id:"nexmo"},"Nexmo"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO_API_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Nexmo API key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_NEXMO_API_SECRET")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Nexmo API secret")))),Object(r.b)("h4",{id:"ovh"},"OVH"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_APP_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH app key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_APP_SECRET")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH app secret")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_CONSUMER_KEY")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH consumer key")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_ACCOUNT")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH account")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_OVH_HOST")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"OVH host")))),Object(r.b)("h4",{id:"plivo"},"Plivo"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO_AUTH_ID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Plivo auth ID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_PLIVO_AUTH_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Plivo auth token")))),Object(r.b)("h4",{id:"twilio"},"Twilio"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Environment variable"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Set to ",Object(r.b)("inlineCode",{parentName:"td"},"true"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO_ACCOUNT_SID")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Twilio account SID")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATION_SMS_TWILIO_AUTH_TOKEN")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Twilio auth token")))),Object(r.b)("h2",{id:"custom-notifications"},"Custom Notifications"),Object(r.b)("p",null,"Both the up and down/degraded performance notifications can be customized with your preferred message, configured as an environment variable.\nMultiple variables are available to use within the message, relating to the site and status."),Object(r.b)("h3",{id:"environment-variables"},"Environment Variables"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Description"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATIONS_DOWN_MESSAGE")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Down/degraded performance message")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"NOTIFICATIONS_UP_MESSAGE")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Up message")))),Object(r.b)("h3",{id:"message-variables"},"Message Variables"),Object(r.b)("table",null,Object(r.b)("thead",{parentName:"table"},Object(r.b)("tr",{parentName:"thead"},Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Value"),Object(r.b)("th",Object(b.a)({parentName:"tr"},{align:null}),"Example"))),Object(r.b)("tbody",{parentName:"table"},Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$SITE_NAME")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"Example Site")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$SITE_URL")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"(",Object(r.b)("a",Object(b.a)({parentName:"td"},{href:"https://example.koj.co"}),"https://example.koj.co"),")")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$ISSUE_URL")," ",Object(r.b)("em",{parentName:"td"},"(down message only)")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("a",Object(b.a)({parentName:"td"},{href:"https://github.com/upptime/upptime/issues/4"}),"https://github.com/upptime/upptime/issues/4"))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$RESPONSE_CODE")," ",Object(r.b)("em",{parentName:"td"},"(down message only)")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),"500")),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$STATUS")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("ul",null,Object(r.b)("li",null,Object(r.b)("strong",{parentName:"td"},"down")),Object(r.b)("li",null,"experiencing ",Object(r.b)("strong",{parentName:"td"},"degraded performance")),Object(r.b)("li",null,"is back up"),Object(r.b)("li",null,"performance has improved")))),Object(r.b)("tr",{parentName:"tbody"},Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("inlineCode",{parentName:"td"},"$EMOJI")),Object(r.b)("td",Object(b.a)({parentName:"tr"},{align:null}),Object(r.b)("ul",null,Object(r.b)("li",null,"\ud83d\udfe5"),Object(r.b)("li",null,"\ud83d\udfe8"),Object(r.b)("li",null,"\ud83d\udfe9")))))))}j.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/404.html b/404.html index 38d224a..6002b29 100644 --- a/404.html +++ b/404.html @@ -12,14 +12,14 @@ Page Not Found | Upptime - +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/blog/2021/01/22/github-actions-schedule-not-working/index.html b/blog/2021/01/22/github-actions-schedule-not-working/index.html index fea88a6..6d9742c 100644 --- a/blog/2021/01/22/github-actions-schedule-not-working/index.html +++ b/blog/2021/01/22/github-actions-schedule-not-working/index.html @@ -12,7 +12,7 @@ GitHub Actions workflow not triggering at scheduled time | Upptime - + @@ -24,7 +24,7 @@

GitHub Actions workflow not triggering at scheduled time

Anand Chowdhary

Anand Chowdhary

Upptime creator, Koj cofounder/CTO

We've seen many reports of GitHub Actions workflows not triggering at the scheduled time. In fact, in the official upptime/upptime repository, workflows scheduled for every five minutes run as slower as once every hour. This blog post is a quick summary of what we know, and what you can do.

The first time we saw this was when @rouilj pointed it out in #112:

If I look at the GitHub Actions listing and select the "Uptime CI", I don't see it being executed every 5 minutes; it looks more like it's running every 18 minutes or so.

And my reply:

Hi @rouilj, unfortunately this is out of our control. We request GitHub to run the Uptime CI workflow every 5 minutes. It's added to a queue and run whenever GitHub has a machine available, sometimes this is every 7 minutes, sometimes every 15 minutes. There's really not much we can do, with the exception of manually triggering the workflow using an external scheduler.

When you set up a GitHub Actions workflow with a schedule, say for once every 10 minutes, you're essneially requesting GitHub to schedule that workflow for you. There is no guarantee that the workflow will run every 10 minutes. In a discussion in the GitHub Support Community (No assurance on scheduled jobs?), Github partner @brightran said that many a times, there may be a delay when triggering the scheduled workflow:

Generally, the delay time is about 3 to 10 minutes. Sometimes, it may be more, even dozens of minutes, or more than one hour.

He also said that if the delay time is too long, the scheduled workflow may be not triggered at that day. Therefore, it's not recommended to use GitHub Actions scheduled workflows for production tasks that require execution guarantee.

So, what can you do to guarantee your GitHub Actions scheduled workflow will run? In #42, @belhyun proposed triggering it manually:

In order to execute correctly every 5 minutes, I ran a build job with jenkins and executed a POST request.

GitHub Actions supports the workflow_dispatch trigger (see Events that trigger workflows on GitHub Docs), so if you manually trigger a workflow, it will be queued to run soon-ish. This means that you can use a third-party cron scheduling service like IFTTT, Google Cloud Scheduler, Jenkins, Cronhub, etc., to make a request to the GitHub API to trigger the workflow.

- + diff --git a/blog/index.html b/blog/index.html index da63db3..49fccb6 100644 --- a/blog/index.html +++ b/blog/index.html @@ -12,7 +12,7 @@ Blog | Upptime - + @@ -25,7 +25,7 @@
- + diff --git a/blog/tags/github-actions/index.html b/blog/tags/github-actions/index.html index 1ff0fd7..c99c5cf 100644 --- a/blog/tags/github-actions/index.html +++ b/blog/tags/github-actions/index.html @@ -12,7 +12,7 @@ Posts tagged "github-actions" | Upptime - + @@ -25,7 +25,7 @@

1 post tagged with "github-actions"

View All Tags
- + diff --git a/blog/tags/index.html b/blog/tags/index.html index 432dec9..85ccf7d 100644 --- a/blog/tags/index.html +++ b/blog/tags/index.html @@ -12,7 +12,7 @@ Tags | Upptime - + @@ -24,7 +24,7 @@
- + diff --git a/blog/tags/uptime-monitor/index.html b/blog/tags/uptime-monitor/index.html index 7badecc..e650bc3 100644 --- a/blog/tags/uptime-monitor/index.html +++ b/blog/tags/uptime-monitor/index.html @@ -12,7 +12,7 @@ Posts tagged "uptime-monitor" | Upptime - + @@ -25,7 +25,7 @@

1 post tagged with "uptime-monitor"

View All Tags
- + diff --git a/docs/badges/index.html b/docs/badges/index.html index 92df843..c9863f6 100644 --- a/docs/badges/index.html +++ b/docs/badges/index.html @@ -12,7 +12,7 @@ Badges | Upptime - + @@ -26,7 +26,7 @@

Badges

You can use the Shields.io service with the API endpoint generated by your repository's api directory. For example, the URL https://raw.githubusercontent.com/upptime/upptime/master/api/google/uptime.json has the following JSON schema:

{
"schemaVersion": 1,
"label": "uptime",
"message": "100%",
"color": "brightgreen"
}

In the above URL, google is the name of your endpoint as defined in the api directory of your Upptime repository.

This translates to this badge: Uptime

![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fupptime%2Fupptime%2Fmaster%2Fapi%2Fgoogle%2Fuptime.json)

Similarly, response time badges are available: Uptime

![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fupptime%2Fupptime%2Fmaster%2Fapi%2Fgoogle%2Fresponse-time.json)
- + diff --git a/docs/configuration/index.html b/docs/configuration/index.html index 1ea77a9..66486e9 100644 --- a/docs/configuration/index.html +++ b/docs/configuration/index.html @@ -12,7 +12,7 @@ Configuration | Upptime - + @@ -26,7 +26,7 @@

Configuration

The .upptimerc.yml file is used as the central configuration for Upptime, with this syntax:

owner: koj-co # GitHub username
repo: upptime # GitHub repository name
user-agent: koj-co
sites: # List of endpoints to track
- name: Google
url: https://www.google.com
assignees: # Users to assign downtime issues (optional)
- AnandChowdhary
status-website: # Status website (optional)
cname: upptime.js.org # Custom domain CNAME
# baseUrl: /repo
name: Upptime # Status website title

Configuration options

Repository

A GitHub repository is used as the "source of truth" for your uptime logs, and the static site uses the GitHub API and fetches data from this repository.

After you've created a new repository using this template (see Creating a repository from a template), specify the username and repository name in the configuration:

owner: koj-co
repo: upptime

Endpoints

You can track as many websites as you like. Add the names and URLs of your endpoints in the sites key:

sites:
- name: Google
url: https://www.google.com
- name: DuckDuckGo
url: https://duckduckgo.com

HTTP verbs

To make POST requests (or any other HTTP verb), you can add the method key:

sites:
- name: POST to Google
url: https://www.google.com
method: POST
- name: DELETE Example
url: https://example.com
method: DELETE

TCP Port Enpoints

To make a TCP ping to any port, you can add the check key "tcp-ping":

sites:
- name: Google DNS 1
check: "tcp-ping"
url: 8.8.4.4
port: 53
- name: Google DNS 2
check: "tcp-ping"
url: 8.8.8.8
port: 53

You can also use hostnames with "tcp-ping":

sites:
- name: Google DNS
check: "tcp-ping"
url: dns.google
port: 53

If you want to test only IPv6 for specific hostnames (e.g. use only the AAAA DNS records), then set the ipv6 flag to true:

sites:
- name: Google DNS
check: "tcp-ping"
url: dns.google
port: 53
ipv6: true

Secret URLs

If you don't want to show a URL publicly, you can use repository secrets (see Creating and storing encrypted secrets). Instead of the plain text URL, add the name of the secret prefixed with a $ character:

- name: Secret Site
url: $SECRET_SITE

In the above example, a secret named SECRET_SITE (without the $) is stored in the repository. You can add as many secrets as you like, and use them in URLs by adding the $prefix. For example, if your environment variable is calledAPI_URL, the site URL can be $API_URL.

You can also use these secrets as part of the URL, for example using a secret called MY_API_KEY:

- name: API endpoint
url: https://example.com/get-user/3?api_key=$MY_API_KEY

Request headers

Similarly, you can set headers in a request like so:

- name: API endpoint
url: https://example.com/get-user/3
headers:
- "Authorization: Bearer $SECRET_SITE_2"
- "Content-Type: application/json"

Request body

If you want to send data alongside the headers, you can use the body key:

- name: API endpoint with data
method: POST
url: https://example.com/login
headers:
- "Content-Type: application/json"
body: '{ "password": "hello" }'

You can add any string to the body parameter, but make sure that you supply the relevant content-type header too.

Custom icons

Each API endpoint has an icon visible on the README.md file and the status website. By default, we use the GitHub Favicon Service to fetch the favicon for the domain of your endpoint (with a fallback to a generic globe icon), but you can also provide a custom icon URL, preferably a transparent square PNG:

sites:
- name: Google
url: https://www.google.com
icon: https://www.google.com/favicon.ico

Status codes

If you, for example, expect a 404 response (which is traditionally an error response), you can set it as expectedStatusCodes to mark your site as up. By default, all 20x and 30x responses are as expectedStatusCodes:

sites:
- name: Google
url: https://www.google.com
expectedStatusCodes:
- 200
- 201
- 404

Maximum response time

Upptime endpoints can be up, down, or degraded. By default, if an endpoint takes more than 30 seconds to respond, its performance is tracked as "degraded". You can customize the maximum response time:

- name: Slow endpoint
url: https://example.com
maxResponseTime: 5000

In the above example, this endpoint will be measured as degraded if it takes more than 5 seconds to respond.

Self-signed SSL certificates

If you're using a self-signed SSL certificate, you can set the __dangerous__disable_verify_peer option to true to skip verifying the certificate:

- name: API endpoint
url: https://example.com/get-user/3
__dangerous__disable_verify_peer: true

If you don't want to check for certificate name mismatches, you can set the __dangerous__disable_verify_host option to true to skip verifying the certificate:

- name: API endpoint
url: https://example.com/get-user/3
__dangerous__disable_verify_host: true

Alternately, you can disable both of the above settings using __dangerous__insecure:

- name: API endpoint
url: https://example.com/get-user/3
__dangerous__insecure: true

Custom status detection

In some cases, your endpoint may return a 200 response but you show the user an error message. This is not a recommended approach, but you can add custom strings to check for.

sites:
- name: Custom down
url: https://example.com
__dangerous__body_down: "File not found"

In the above example, if the body HTML response includes the string "File not found", the site will be marked as "down". Similarly, you can use __dangerous__body_degraded to mark the site as "degraded" instead.

In other cases your endpoint may return a 200 response with a success message in the body. You might want to check for a specific success message in the body:

sites:
- name: Custom up
url: https://example.com/api/system/status
__dangerous__body_down_if_text_missing: '"status":"UP"'

In the above example, if the body HTML response does not include "status":"UP", the site will be marked as "down". Similarly, you can use __dangerous__body_degraded_if_text_missing to mark the site as "degraded" instead.

Notifications

You can add services to send downtime notifications to, such as SMS, Slack, or email. For more information about notifications, visit the Notifications docs page. You can directly configure the notifications in repository secrets (environment variables).

Assignees

You can add members of your team to be assigned to every downtime issue:

assignees:
- AnandChowdhary
- CarloBadini

If you want particular users to be assigned per-site, you can add assignees under each entry in sites:

sites:
- name: Google
url: https://www.google.com
assignees:
- AnandChowdhary

Status website

Theme

You can select one of many themes available to customize your status website:

status-website:
theme: light

Available themes are light, dark, night or ocean.

You can also write your own custom theme by creating a CSS file in the assets/ directory of your Upptime repository. For example, if you create a file assets/my-custom-theme.css, you can use CSS variables to style your theme. To see a list of all available variables, see the dark.css theme:

:root {
--body-background-color: #001716;
--body-text-color: #f0ffff;
--card-background-color: #002b29;
--nav-background-color: #002b29;
--nav-border-bottom-color: #015450;
}
/* . . . */

Then, this file will be available at https://example.com/my-custom-theme.css. All files from the assets directory are served as-is, so you can use this URL to specify your new theme using themeUrl:

status-website:
themeUrl: https://example.com/my-custom-theme.css

Branding

A static website with PWA is also generated, and you can customize the logo and name in the navbar:

status-website:
name: Upptime
logoUrl: https://example.com/image.jpg

Custom domain

If you want to add a custom domain, you can add the cname key:

status-website:
name: Upptime
logoUrl: https://example.com/image.jpg
cname: upptime.js.org # Custom CNAME

If you're not using a custom domain, you should add the base URL to support the default GitHub Pages URL.

status-website:
baseUrl: /repo # where "repo" is your repository name
name: Your Status Website

Then, your status page may be hosted on https://user.github.io/repo/, where user is your GitHub username and repo is your repository name.

Navbar links

You can customize the navbar by adding or removing top-level navigation links.

status-website:
navbar:
- title: Status
href: /
- title: GitHub
href: https://github.com/$OWNER/$REPO

Intro text

Optionally, you can add some introductory text to the website. You can use Markdown:

status-website:
introTitle: "**Upptime** is the open-source uptime monitor and status page, powered entirely by GitHub."
introMessage: This is a sample status page which uses **real-time** data from our [Github repository](https://github.com/koj-co/upptime). No server required โ€” just GitHub Actions, Issues, and Pages.

Custom favicons

You can add a custom favicon in both SVG and PNG formats:

status-website:
favicon: https://example.com/favicon.png
faviconSvg: https://example.com/logo.svg

Custom HTML

To add any custom HTML (unsanitized), you can use customHeadHtml and customBodyHtml:

status-website:
customHeadHtml: "<!-- Custom HTML to add in the <head> tag -->"
customBodyHtml: "<!-- Custom HTML to add at the beginning of <body> -->"

Custom JavaScript

You can add custom scripts:

status-website:
scripts:
- src: https://example.com/script.js
- src: https://example.com/script-2.js
async: true

Or, directly add inline JS:

status-website:
js: "window.onload = function() { alert('Hello!') }"

Custom CSS

You can add custom stylesheets:

status-website:
links:
- rel: stylesheet
href: https://example.com/custom-styles.css

Or, directly add inline CSS:

status-website:
css: "body { opacity: 0.5 }"

Custom meta tags

To add any custom meta tags, you can use a syntax similar to the links:

status-website:
metaTags:
- name: "color-scheme"
content: "dark light"
- name: "robots"
content: "noindex"

Custom robots.txt files

You might want to have custom search engine indexing rules:

status-website:
robotsText: "User-agent: * \n Disallow: /"

Custom API base URL

By default, Upptime uses the official GitHub API to fetch data for your status page website. If you have a proxy API (perhaps using a personal access token with readonly access to your private repository), you can set the apiBaseUrl key under status-website:

status-website:
apiBaseUrl: https://api.github.com

Internationalization

Though our status page is in English, you can use any language with Upptime by supplying the required strings. The list of all required strings is available in upptime/status-page/i18n.yml, and you can add them under the i18n key in the configuration file:

i18n:
activeIncidents: Incidentes activos
allSystemsOperational: Todos los sistemas estรกn operativos
# ...

You can, for example, change the footer copyright text by changing the internationalization key for footer. These i18n keys are also used for your README.md file.

Similarly, you can also localize the README.md file by adding these to the same i18n.yml file: List of README.md strings.

Repository metadata

If you've just set up your new repository and don't have repository metadata (like description, topics, and homepage), Upptime will update that for you. It will update the metadata as follows:

  • Description: "๐Ÿ“ˆ Uptime monitor and status page for $TITLE, powered by @upptime", where $TITLE is the name of your GitHub organization or user
  • Topics: "uptime-monitor", "status-page", "upptime"
  • Homepage: Link to your status website

You can add these configuration properties if you don't want these updates to occur:

skipDescriptionUpdate: true
skipTopicsUpdate: true
skipHomepageUpdate: true

Git commit options

Upptime commits to git history to keep a track of response times, and also commits graphs and README updates. You can change the commit messages for each of these actions:

commitMessages:
readmeContent: ":pencil: Update summary in README [skip ci] [upptime]"
summaryJson: ":card_file_box: Update status summary [skip ci] [upptime]"
statusChange: "$EMOJI $SITE_NAME is $STATUS ($RESPONSE_CODE in $RESPONSE_TIME ms) [skip ci] [upptime]"
graphsUpdate: ":bento: Update graphs [skip ci] [upptime]"

By default, these commits are done by Upptime Bot, but you can overwrite these commits to use your bot instead.

commitMessages:
commitAuthorName: "Upptime Bot"
commitAuthorEmail: "upptime@koj.co"

CI schedule

You can customize the schedule when Uptime workflows run by adding the workflowSchedule key in your configuration file. The syntax followed is that of cron. The default values are like so:

Keep in mind that a scheduled GitHub Action cannot run faster than every 5 minutes.

workflowSchedule:
graphs: "0 0 * * *"
responseTime: "0 23 * * *"
staticSite: "0 1 * * *"
summary: "0 0 * * *"
updateTemplate: "0 0 * * *"
updates: "0 3 * * *"
uptime: "*/5 * * * *"

Self-hosted runners

You may want to use a self-hosted runner instead of the publicly available GitHub runners in your project for more accurate uptime monitoring (ensuring scheduled workflows run on time) or to save build minutes. You can specify your self-hosted runner like so:

runner: "[self-hosted, linux, ARM64]"

User agent

Requests made to the GitHub API must include a valid User-Agent header (see User Agent required). It is recommended to use your GitHub username here:

user-agent: your-github-username
- + diff --git a/docs/contributing/index.html b/docs/contributing/index.html index f2d28f2..e8a979c 100644 --- a/docs/contributing/index.html +++ b/docs/contributing/index.html @@ -12,7 +12,7 @@ Contributing | Upptime - + @@ -26,7 +26,7 @@
- + diff --git a/docs/faq/index.html b/docs/faq/index.html index 6d73e44..4051772 100644 --- a/docs/faq/index.html +++ b/docs/faq/index.html @@ -12,7 +12,7 @@ Frequently Asked Questions | Upptime - + @@ -26,7 +26,7 @@

Frequently Asked Questions

Is Upptime free and open-source software (FOSS)?

Yes, Upptime is 100% free and open-source, with all components licensed under the permissive MIT License.

My status website is broken (CSS is not loading)

You are probably running the website on a non-root domain, for example at https://user.github.io/repo/, where user is your GitHub username and repo is the repository name. You should add the baseUrl configuration:

.upptimerc.yml
status-website:
baseUrl: /repo # "repo" is your repository name

My status website doesn't work with my private repository.

By default, Upptime only supports publishing status websites from public repositories, since the GitHub API is used to fetch data. However, you can set up a proxy API (for example, using a personal access token with readonly access to your private repository) and set that as the apiBaseUrl configuration key under status-website. See #54 and the Configuration for apiBaseUrl to learn how to set up a status website from your private repository.

How do I remove the "Powered by Upptime" in the footer of my website?

You can add an internationalization object that overwrites some keys, see Internationalization:

.upptimerc.yml
i18n:
footer: This page is [open source]($REPO), powered by [Upptime](https://upptime.js.org)

I'm getting a 404 error in Setup CI

Make sure you've changed the owner and repo in the Configuration.

- + diff --git a/docs/get-started/index.html b/docs/get-started/index.html index 4f69013..e064d3c 100644 --- a/docs/get-started/index.html +++ b/docs/get-started/index.html @@ -12,7 +12,7 @@ Getting started | Upptime - + @@ -27,7 +27,7 @@

Getting started

To use Upptime as an uptime monitor and status website generator, you start by creating a repository using the template on GitHub.

Create a repository from the template

You can click on the following link to generate a repository using the template: Create a new repository from upptime/upptime. Alternatively, you can visit the Upptime repository on GitHub and click on the "Use this template" button on the top-right.

In both cases, the next steps are:

  1. Enter a name for your new repository.
  2. Important: Check "Include all branches".
  3. Click on "Create repository from template".

For more details on how to create repositories using template, read the article on the GitHub website: Creating a repository from a template.

Billing note: Upptime uses thousands of build minutes every month (approximately 3,000 minutes in the default setting). If you use a public repository, GitHub offers unlimited free build minutes, but if you use a private repository, you'll have to pay for this time.

After creating your repository

The following steps apply to your new repository, not the upptime/upptime template repository.

Enable publishing

To get a static status website, you have to enable GitHub Pages on your new repository.
Usually, GitHub will enable GitHub Pages as soon as a gh-pages branch is detected. If this doesn't happen should you do the following steps.

  1. Go to your repository settings page
  2. Go to the "Pages" sub-section on the left
  3. Under "Source", change "None" to "Deploy from a branch"
  4. In the Branch dropdown, select gh-pages and /(root)
  5. Click on "Save"

After saving, you will see confirmation text "Your site is live at..." at the top of the page. For more information on enabling GitHub Pages, see the article on the GitHub website: Configuring a publishing source for your GitHub Pages site.

If you don't want to have a publicly-available status website, you don't have to enable publishing. If that is the case, you can also choose to keep your repository private. It is not possible to publish a status website from a private repository without using an API proxy with authentication. See #54 and the Configuration for apiBaseUrl to learn how to set up a status website from your private repository.

Add repository secrets

All sensitive information required, such as API keys, are provided as environment variables. These are stored as GitHub repository secrets (see Creating and storing encrypted secrets).

To make commits and publish your website, Upptime requires a personal access token (PAT) with read-write permissions of Actions, Contents, Issues and Workflows, stored as a repository secret named GH_PAT. You can create a personal access token by following these steps:

  1. Click on your profile picture on the top-right corner and select "Settings"
  2. In the left sidebar, select "Developer settings"
  3. In the left sidebar, click "Personal access tokens" > "Fine-grained tokens"
  4. Click "Generate new token"
  5. Give your token a specific distinct name
  6. In the "Expiration" dropdown, select "90 days" or a custom, longer expiry
  7. In the "Resource Owner" section select the user or organization your Upptime repository belongs to
  8. In the "Repository Access" section select "Only select repositories" and select your Upptime repository
  9. In the "Permissions" > "Repository permissions" section enable read-write access to Actions, Contents, Issues and Workflows
  10. Skip the "Organization permissions" section
  11. Click "Generate token" or "Generate token and request access" (if it is in an org you are not an admin of)

After generating your token, copy it (you will not see it again). Then, add it as a repository secret:

  1. In your Upptime repository, select "Settings"
  2. In the left sidebar, click "Secrets and variables" followed by "Actions"
  3. Press the button "New repository secret"
  4. Enter the name of the secret as GH_PAT
  5. Paste your personal access token into the Value field
  6. Be sure there are no spaces before or after the token and/or linebreaks after your token
  7. Save your PAT by selecting "Add secret"

For more information on PATs, read article on the GitHub website: Creating a personal access token.

Update configuration

The .upptimerc.yml file is used as the central configuration store. In that file, you can specify which endpoints you want to monitor and configure your status website. For more information, visit Configuration.

You can start by setting the owner and repo, and adding your endpoints under sites:

.upptimerc.yml
owner: koj-co # GitHub username
repo: upptime # GitHub repository name
sites: # List of endpoints to track
- name: Google
url: https://www.google.com
assignees: # Users to assign downtime issues (optional)
- AnandChowdhary
status-website: # Status website (optional)
cname: upptime.js.org # Custom domain CNAME
name: Upptime # Status website title

If you're not using a custom domain, you can remove the line starting with cname: and instead add the GitHub repository name using the baseUrl: setting:

status-website:
baseUrl: /repo # where "repo" is your repository name
name: Your Status Website

Then, your status page may be hosted on https://user.github.io/repo/, where user is your GitHub username and repo is your repository name.

Viewing GitHub Actions workflows

After updating the configuration file, Upptime should run workflows using GitHub Actions to update your README.md and generate API endpoints and graphs. To view the status, click on the "Actions" tab in your repository. You should see pending or complete workflows. If you don't, you can manually trigger the "Setup CI" using the Triggers article.

If you've forked the Upptime repository or have rules to disable Actions by default, you'll have to manually enable GitHub Actions, but this should probably not be your case.

Best practices

Now that you have your Upptime instance fully set up, you should follow these best practices when adding details to outage incidents.

  • Upptime will automatically open a new issue when an outage occurs
  • If you haven't identified the cause of this outage, you can add a comment like: "Investigating: We're currently investigating the cause of this outage, and we'll update the details here shortly."
  • Then, you can add some comments with the details of the outage, and change the name of the issue with the details of the outage
  • The issue will be automatically closed when the site comes back up, so you can add a last comment with a postmortem of the outage
- + diff --git a/docs/index.html b/docs/index.html index 3626bee..2c2d2d8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,7 +12,7 @@ How it works | Upptime - + @@ -26,7 +26,7 @@

How it works

Upptime is a free and open-source uptime monitor and status website service. It's very different from other status-page services because it doesn't require a server โ€” it's all powered by GitHub:

  1. GitHub Actions is used as an uptime monitor
  2. GitHub Issues are used for incident reports
  3. GitHub Pages are used for the status website

Concepts

GitHub Actions-powered uptime monitor

Using GitHub Actions, users can schedule workflows to automatically run every x-minutes. The shortest interval is 5 minutes. So, every 5 minutes, Upptime visits your websites and makes sure that they're up.

We also record the response time once per day and commit it to git history. This way, we can graph long-term trends in your websites' response times by going through git commit history. We generate these graphs once every day, also using schedulers.

You can see example commit history.

GitHub Issues-powered incident reports

When a specified endpoint goes down, Upptime automatically opens a new issue in your GitHub repository. You can use this issue to add more information about the outage, such as whether you are investigating, what caused the downtime, etc. You can also choose to automatically assign certain members from your team to the issue and send notifications to connected services like Slack and Telegram.

To add information about an incident, you can add comments to the issue. By default, issues will be locked, so only your team members are allowed to comment on them. When your website comes back up, the issue will be automatically closed.

You can see an example issue #67.

GitHub Pages-powered status website

Lastly, you get a beautiful, staticly-generated status website. This website will show users your websites' live status, incident history, and response time graphs. The website is always up-to-date as it uses the GitHub API to fetch data in real-time, and is built using Svelte and Sapper. You can customize the logo, copy, and more to make it your own.

You can see the example status website.

- + diff --git a/docs/notifications/index.html b/docs/notifications/index.html index 24e4af6..57b231e 100644 --- a/docs/notifications/index.html +++ b/docs/notifications/index.html @@ -12,7 +12,7 @@ Notifications | Upptime - + @@ -20,15 +20,16 @@ - +

Notifications

Using notifications, you can alert your team when an endpoint goes down or experiences degraded performance. To add notifications, you have to add environment variables as GitHub repository secrets (Settings -> Secrets -> Actions) and add Environment variable as your Secret name and Value in environment variable as value in secret. DO NOT select Variables select Secret(see Creating and storing encrypted secrets).

Secrets

Every time an endpoint goes down, a notification with the following text is sent:

๐ŸŸฅ Example Site (https://example.koj.co) is down: https://github.com/upptime/upptime/issues/4

If it experiences degraded performance, a notification with the following text is sent:

๐ŸŸจ Example Site (https://example.koj.co) has degraded performance: https://github.com/upptime/upptime/issues/4

When it comes back up, another notification is sent:

๐ŸŸฉ Example Site is back up.

Strategy

If you have more than one configurations of each provider (say multiple email configurations, both SMTP and SES), you can choose the strategy. For each notification provider (Slack, email, etc.), you can specify the strategy using the NOTIFICATION_{PROVIDER}_STRATEGY environment variable, where {PROVIDER} is the constant-case service name, for example NOTIFICATION_SLACK_STRATEGY. The strategy can be any one of:

ValueDescription
fallbackIf one provider returns an error, try the next
roundrobin (default)Use every provider in turns
no-fallbackDeactivates fallback strategy

More information is available on the Multi-provider strategies page in the documentation.

Providers

For each notification type (Slack, email, etc.), you need to first enable it by setting the NOTIFICATION_{PROVIDER} to true, where {PROVIDER} is the constant-case service name, for example NOTIFICATION_SLACK. Each notification type also requires additional environment variables. See the examples below.

Slack

Environment variableValue
NOTIFICATION_SLACKSet to true
NOTIFICATION_SLACK_WEBHOOKSet to true
NOTIFICATION_SLACK_WEBHOOK_URLSlack webhook URL

To create a Slack webhook URL, see the article Incoming webhooks for Slack on the Slack website.

Telegram

Environment variableValue
NOTIFICATION_TELEGRAMSet to true
NOTIFICATION_TELEGRAM_BOT_KEYYour bot key
NOTIFICATION_TELEGRAM_CHAT_IDYour chat ID

To create a Telegram bot key, see the documentation for Botfather on the Telegram Support website.

Discord

Environment variableValue
NOTIFICATION_DISCORDSet to true
NOTIFICATION_DISCORD_WEBHOOKSet to true
NOTIFICATION_DISCORD_WEBHOOK_URLDiscord webhook URL

To create a Discord webhook URL, see the article Intro to Webhooks on the Discord Support website.

Zulip

Environment variableValue
NOTIFICATION_ZULIP_MESSAGE_URLZulip Message API URL
NOTIFICATION_ZULIP_API_EMAILEmail of the Zulip bot
NOTIFICATION_ZULIP_API_KEYAPI Key of the Zulip bot

To create a Zulip Incoming Webhook bot, see the article Add a bot or integration in the Zulip docs. The NOTIFICATION_ZULIP_MESSAGE_URL should include the type, to and topic query params and would look something like this: -https://domain.zulipchat.com/api/v1/messages?type=stream&to=general&topic=Upptime%20notifications.

Microsoft Teams

Environment variableValue
NOTIFICATION_TEAMSSet to true
NOTIFICATION_TEAMS_WEBHOOK_URLTeams webhook URL

To create a Microsoft Teams webhook URL, see the article Create Incoming Webhooks on the Microsoft Learn website.

Email

To send an email, you can use SMTP or a hosted service such as AWS SES, Sendgrid, Sparkpost, or Mailgun.

All services require you to specify the email address from and to:

Environment variableValue
NOTIFICATION_EMAILSet to true
NOTIFICATION_EMAIL_FROM"From" email address
NOTIFICATION_EMAIL_TO"To" email address

Sendgrid

Environment variableValue
NOTIFICATION_EMAIL_SENDGRIDSet to true
NOTIFICATION_EMAIL_SENDGRID_API_KEYSendgrid API key

AWS SES

Environment variableValue
NOTIFICATION_EMAIL_SESSet to true
NOTIFICATION_EMAIL_SES_REGIONAWS region
NOTIFICATION_EMAIL_SES_ACCESS_KEY_IDAWS access key ID
NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEYAWS secret access key
NOTIFICATION_EMAIL_SES_SESSION_TOKENAWS session token

Sparkpost

Environment variableValue
NOTIFICATION_EMAIL_SPARKPOSTSet to true
NOTIFICATION_EMAIL_SPARKPOST_API_KEYSparkpost API key

Mailgun

Environment variableValue
NOTIFICATION_EMAIL_MAILGUNSet to true
NOTIFICATION_EMAIL_MAILGUN_API_KEYMailgun API key
NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAMEMailgun domain name

SMTP

Environment variableValue
NOTIFICATION_EMAIL_SMTPSet to true
NOTIFICATION_EMAIL_SMTP_PORTSMTP Port
NOTIFICATION_EMAIL_SMTP_HOSTSMTP Host
NOTIFICATION_EMAIL_SMTP_USERNAMESMTP Username
NOTIFICATION_EMAIL_SMTP_PASSWORDSMTP Password

SMS

To send a text message, you can any one of several services: Callr, Clickatell, Infobip, Nexmo, OVH, Plivo, Twilio, or 46elks. You'll have to create an account at the service of your choice and provide authentication information as specified below.

All services require you to specify the phone number from and to:

Environment variableValue
NOTIFICATION_SMS_FROM"From" phone number
NOTIFICATION_SMS_TO"To" phone number

46elks

Environment variableValue
NOTIFICATION_SMS_46ELKSSet to true
NOTIFICATION_SMS_46ELKS_API_USERNAME46elks username
NOTIFICATION_SMS_46ELKS_API_PASSWORD46elks password

Callr

Environment variableValue
NOTIFICATION_SMS_CALLRSet to true
NOTIFICATION_SMS_CALLR_LOGINCallr login
NOTIFICATION_SMS_CALLR_PASSWORDCallr password

Clickatell

Environment variableValue
NOTIFICATION_SMS_CLICKATELLSet to true
NOTIFICATION_SMS_CLICKATELL_API_KEYClickatell API key

Infobip

Environment variableValue
NOTIFICATION_SMS_INFOBIPSet to true
NOTIFICATION_SMS_INFOBIP_USERNAMEInfobip username
NOTIFICATION_SMS_INFOBIP_PASSWORDInfobip password

Nexmo

Environment variableValue
NOTIFICATION_SMS_NEXMOSet to true
NOTIFICATION_SMS_NEXMO_API_KEYNexmo API key
NOTIFICATION_SMS_NEXMO_API_SECRETNexmo API secret

OVH

Environment variableValue
NOTIFICATION_SMS_OVHSet to true
NOTIFICATION_SMS_OVH_APP_KEYOVH app key
NOTIFICATION_SMS_OVH_APP_SECRETOVH app secret
NOTIFICATION_SMS_OVH_CONSUMER_KEYOVH consumer key
NOTIFICATION_SMS_OVH_ACCOUNTOVH account
NOTIFICATION_SMS_OVH_HOSTOVH host

Plivo

Environment variableValue
NOTIFICATION_SMS_PLIVOSet to true
NOTIFICATION_SMS_PLIVO_AUTH_IDPlivo auth ID
NOTIFICATION_SMS_PLIVO_AUTH_TOKENPlivo auth token

Twilio

Environment variableValue
NOTIFICATION_SMS_TWILIOSet to true
NOTIFICATION_SMS_TWILIO_ACCOUNT_SIDTwilio account SID
NOTIFICATION_SMS_TWILIO_AUTH_TOKENTwilio auth token
+https://domain.zulipchat.com/api/v1/messages?type=stream&to=general&topic=Upptime%20notifications.

Microsoft Teams

Environment variableValue
NOTIFICATION_TEAMSSet to true
NOTIFICATION_TEAMS_WEBHOOK_URLTeams webhook URL

To create a Microsoft Teams webhook URL, see the article Create Incoming Webhooks on the Microsoft Learn website.

Email

To send an email, you can use SMTP or a hosted service such as AWS SES, Sendgrid, Sparkpost, or Mailgun.

All services require you to specify the email address from and to:

Environment variableValue
NOTIFICATION_EMAILSet to true
NOTIFICATION_EMAIL_FROM"From" email address
NOTIFICATION_EMAIL_TO"To" email address

Sendgrid

Environment variableValue
NOTIFICATION_EMAIL_SENDGRIDSet to true
NOTIFICATION_EMAIL_SENDGRID_API_KEYSendgrid API key

AWS SES

Environment variableValue
NOTIFICATION_EMAIL_SESSet to true
NOTIFICATION_EMAIL_SES_REGIONAWS region
NOTIFICATION_EMAIL_SES_ACCESS_KEY_IDAWS access key ID
NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEYAWS secret access key
NOTIFICATION_EMAIL_SES_SESSION_TOKENAWS session token

Sparkpost

Environment variableValue
NOTIFICATION_EMAIL_SPARKPOSTSet to true
NOTIFICATION_EMAIL_SPARKPOST_API_KEYSparkpost API key

Mailgun

Environment variableValue
NOTIFICATION_EMAIL_MAILGUNSet to true
NOTIFICATION_EMAIL_MAILGUN_API_KEYMailgun API key
NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAMEMailgun domain name

SMTP

Environment variableValue
NOTIFICATION_EMAIL_SMTPSet to true
NOTIFICATION_EMAIL_SMTP_PORTSMTP Port
NOTIFICATION_EMAIL_SMTP_HOSTSMTP Host
NOTIFICATION_EMAIL_SMTP_USERNAMESMTP Username
NOTIFICATION_EMAIL_SMTP_PASSWORDSMTP Password

SMS

To send a text message, you can any one of several services: Callr, Clickatell, Infobip, Nexmo, OVH, Plivo, Twilio, or 46elks. You'll have to create an account at the service of your choice and provide authentication information as specified below.

All services require you to specify the phone number from and to:

Environment variableValue
NOTIFICATION_SMS_FROM"From" phone number
NOTIFICATION_SMS_TO"To" phone number

46elks

Environment variableValue
NOTIFICATION_SMS_46ELKSSet to true
NOTIFICATION_SMS_46ELKS_API_USERNAME46elks username
NOTIFICATION_SMS_46ELKS_API_PASSWORD46elks password

Callr

Environment variableValue
NOTIFICATION_SMS_CALLRSet to true
NOTIFICATION_SMS_CALLR_LOGINCallr login
NOTIFICATION_SMS_CALLR_PASSWORDCallr password

Clickatell

Environment variableValue
NOTIFICATION_SMS_CLICKATELLSet to true
NOTIFICATION_SMS_CLICKATELL_API_KEYClickatell API key

Infobip

Environment variableValue
NOTIFICATION_SMS_INFOBIPSet to true
NOTIFICATION_SMS_INFOBIP_USERNAMEInfobip username
NOTIFICATION_SMS_INFOBIP_PASSWORDInfobip password

Nexmo

Environment variableValue
NOTIFICATION_SMS_NEXMOSet to true
NOTIFICATION_SMS_NEXMO_API_KEYNexmo API key
NOTIFICATION_SMS_NEXMO_API_SECRETNexmo API secret

OVH

Environment variableValue
NOTIFICATION_SMS_OVHSet to true
NOTIFICATION_SMS_OVH_APP_KEYOVH app key
NOTIFICATION_SMS_OVH_APP_SECRETOVH app secret
NOTIFICATION_SMS_OVH_CONSUMER_KEYOVH consumer key
NOTIFICATION_SMS_OVH_ACCOUNTOVH account
NOTIFICATION_SMS_OVH_HOSTOVH host

Plivo

Environment variableValue
NOTIFICATION_SMS_PLIVOSet to true
NOTIFICATION_SMS_PLIVO_AUTH_IDPlivo auth ID
NOTIFICATION_SMS_PLIVO_AUTH_TOKENPlivo auth token

Twilio

Environment variableValue
NOTIFICATION_SMS_TWILIOSet to true
NOTIFICATION_SMS_TWILIO_ACCOUNT_SIDTwilio account SID
NOTIFICATION_SMS_TWILIO_AUTH_TOKENTwilio auth token

Custom Notifications

Both the up and down/degraded performance notifications can be customized with your preferred message, configured as an environment variable. +Multiple variables are available to use within the message, relating to the site and status.

Environment Variables

ValueDescription
NOTIFICATIONS_DOWN_MESSAGEDown/degraded performance message
NOTIFICATIONS_UP_MESSAGEUp message

Message Variables

ValueExample
$SITE_NAMEExample Site
$SITE_URL(https://example.koj.co)
$ISSUE_URL (down message only)https://github.com/upptime/upptime/issues/4
$RESPONSE_CODE (down message only)500
$STATUS
  • down
  • experiencing degraded performance
  • is back up
  • performance has improved
$EMOJI
  • ๐ŸŸฅ
  • ๐ŸŸจ
  • ๐ŸŸฉ
- + @@ -36,6 +37,6 @@ - + \ No newline at end of file diff --git a/docs/packages/index.html b/docs/packages/index.html index fe82788..41c0876 100644 --- a/docs/packages/index.html +++ b/docs/packages/index.html @@ -12,7 +12,7 @@ Packages | Upptime - + @@ -26,7 +26,7 @@

Packages

Upptime consists of several packages written in TypeScript and Svelte/Sapper, which are consumed by the template repository.

@upptime/uptime-monitor

npm version npm GitHub Repo stars

This package includes the uptime monitor that sends network requests to ensure that your endpoints are online. It also includes all features, including notifications, interactions with the GitHub API, and generating the status website and README.md files. It's written in TypeScript.

@upptime/status-page

npm version npm GitHub Repo stars

This package contains the source code of the status website written in Svelte using Sapper. Users don't directly interact with this package, rather the @upptime/uptime-monitor fetches the source code of the static site from here.

@upptime/graphs

npm version npm GitHub Repo stars

This package includes the response time graph generator using Chart.js. This is a separate package because it has several dependencies, and it's only installed when graphs are actually being generated (by default, once per day), and not in other workflows. It's written in TypeScript.

- + diff --git a/docs/scheduled-maintenance/index.html b/docs/scheduled-maintenance/index.html index fa6f996..e8651e1 100644 --- a/docs/scheduled-maintenance/index.html +++ b/docs/scheduled-maintenance/index.html @@ -12,7 +12,7 @@ Scheduled maintenance | Upptime - + @@ -26,7 +26,7 @@

Scheduled maintenance

Upptime helps you set up scheduled maintenance times by opening issues manually. To create a new scheduled maintenance, create a new issue in your Upptime repository and add the label maintenance to it. The issue body should include an HTML comment, like so:

<!--
start: 2021-02-24T13:00:00+00:00
end: 2021-02-24T14:00:00+00:00
expectedDown: google, hacker-news
-->

The start and end keys are mandatory and should contain an ISO datetime with the start and ending time for the scheduled maintenance respectively.

If you expect that an endpoint will go down during this time, you can add it to expectedDown and Upptime will not open an issue if it goes down within this time period. Similarly, you can add expectedDegraded if you expect degraded performance. Both these keys should have comma-separated list of slugs.

Upptime will automatically close the issue when the end time happens, and it shows both currently ongoing and past scheduled maintenance events on the static website.

- + diff --git a/docs/triggers/index.html b/docs/triggers/index.html index 05a8d7c..a3269d2 100644 --- a/docs/triggers/index.html +++ b/docs/triggers/index.html @@ -12,7 +12,7 @@ Triggers | Upptime - + @@ -28,7 +28,7 @@ Fine grained tokens ae preferred as you can limit the token to a specific repository.

In either case Type any note or name you wish, and set Expiration to anything you wish too (I recommend make it never expire).

Then generate your new token using the button at the bottom of the page and save it somewhere safe.

Or, with JavaScript (@octokit/core.js) (untested):

await octokit.request("POST /repos/{owner}/{repo}/actions/workflows/uptime.yml/dispatches", {
owner: "user",
repo: "repo",
ref: "master",
});

For more information, read this article on the GitHub website: Create a repository dispatch event.

- + diff --git a/index.html b/index.html index ad8656a..84b9622 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ Upptime - + @@ -22,7 +22,7 @@

Upptime

GitHub-powered open-source uptime monitor and status page

This is a real status website โ†“

Monitor uptime every 5 minutes

Monitor uptime every 5 minutes

Using GitHub Actions, monitor unlimited webpages every 5 minutes, and store version-controlled response time stats.

Modern status page website

Modern status page website

Get a sleek and beautiful status page powered by a modern Svelte static site with outage history and long-term trend charts.

Get notified where you work

Get notified where you work

Find out the moment any website goes down, with built-in notification support for Slack, Telegram, custom webhooks, and more.

- + diff --git a/runtime~main.56675f0c.js b/runtime~main.66d477f8.js similarity index 97% rename from runtime~main.56675f0c.js rename to runtime~main.66d477f8.js index 498411c..29e39a0 100644 --- a/runtime~main.56675f0c.js +++ b/runtime~main.66d477f8.js @@ -1 +1 @@ -!function(e){function r(r){for(var n,c,f=r[0],d=r[1],u=r[2],i=0,l=[];ifunction gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-TYJM49782H",{}) Search the documentation | Upptime - + @@ -22,7 +22,7 @@

Search the documentation

- + diff --git a/status/upptime-icon.svg b/status/upptime-icon.svg new file mode 100644 index 0000000..f909d51 --- /dev/null +++ b/status/upptime-icon.svg @@ -0,0 +1,4 @@ + + + +