Skip to content

Commit

Permalink
Sends emails. Handles most error.
Browse files Browse the repository at this point in the history
  • Loading branch information
danman113 committed Sep 30, 2017
1 parent 1291fb6 commit 8340136
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 43 deletions.
12 changes: 8 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package config

import (
"io/ioutil"
// . "github.com/danman113/gobeet/re"
"encoding/json"
"github.com/danman113/gobeet/site"
"io/ioutil"
)

type pingable interface {
type EmailConfig struct {
Address string `json: address`
Server string `json: server`
Port string `json: port`
Template string `json: template`
Recipients []string `json: recipients`
}

type Config struct {
Sites []site.Website `json: sites`
Email EmailConfig `json: email`
}

func ParseConfigFile(filename string) (*Config, error) {
Expand Down
86 changes: 86 additions & 0 deletions email/email.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package email

import (
"bytes"
"fmt"
"github.com/danman113/gobeet/config"
"github.com/danman113/gobeet/site"
"html/template"
"net/smtp"
)

var (
// Set from main
Config config.EmailConfig
auth smtp.Auth
EmailPassword *string

// Temp variables
temp *template.Template
)

type TemplateData struct {
Config config.EmailConfig
Site *site.Page
Error error
}

func parseTemplate() {
if temp == nil {
t, tErr := template.ParseFiles(Config.Template)
if tErr != nil {
fmt.Println("Template Parse Error: ")
fmt.Println(tErr)
return
}
temp = t
}
}

func buildEmailBody(err error, pg *site.Page) ([]byte, error) {
if temp == nil {
parseTemplate()
}

buf := new(bytes.Buffer)

eErr := temp.Execute(buf, TemplateData{Config, pg, err})

if eErr != nil {
fmt.Println("Template Execute Error: ")
fmt.Println(eErr)
return nil, eErr
}

mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
return []byte(fmt.Sprintf("Subject: %s\r\n%s %s", "Gobeet Alert", mime, buf.String())), nil
}

func SendAlert(err error, pg *site.Page) {
if auth == nil {
auth = smtp.PlainAuth(
"",
Config.Address,
*EmailPassword,
Config.Server,
)
}

body, bodyErr := buildEmailBody(err, pg)

if bodyErr != nil {
return
}

sendErr := smtp.SendMail(
Config.Server+":"+Config.Port,
auth,
Config.Address,
Config.Recipients,
body,
)
if sendErr != nil {
fmt.Println("Email Error!")
fmt.Println(sendErr)
}
}
38 changes: 23 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
package main

import (
"flag"
"fmt"
"github.com/danman113/gobeet/config"
"github.com/danman113/gobeet/email"
"github.com/danman113/gobeet/ping"
// . "github.com/danman113/gobeet/re"
// "runtime"
// "time"
)

func main() {
conf, _ := config.ParseConfigFile("sampleconfig.json")
configPath := flag.String("config", "config.json", "Location for a config file")
emailPassword := flag.String("password", "", "Password for your email account")
flag.Parse()
conf, err := config.ParseConfigFile(*configPath)
if err != nil {
fmt.Println("Could Not Parse Config File")
fmt.Println("Error: ")
fmt.Println(err)
return
}
fmt.Println(conf.Email)
email.Config = conf.Email
email.EmailPassword = emailPassword
// email.SendAlert(err, conf.Sites[0])
if err != nil {
fmt.Println("Could not parse config file: " + *configPath)
return
}
fmt.Println(*conf)
for _, site := range conf.Sites {
fmt.Println(site)
for _, page := range site.Pages {
fmt.Println(page)
ret := make(chan error)
ping.PingStatus(page, ret)
for val := range ret {
fmt.Println("Error: ")
fomt.Println(val)
}
}
for i, _ := range conf.Sites {
go ping.PingWebsite(&conf.Sites[i])
}
select {}
}
50 changes: 42 additions & 8 deletions ping/ping.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package ping

import (
"errors"
"fmt"
"github.com/danman113/gobeet/email"
"github.com/danman113/gobeet/site"
"net/http"
"time"
Expand All @@ -11,15 +13,47 @@ var (
client = &http.Client{}
)

func PingStatus(site *site.Page, res chan error) {
func GobeetError(msg string) error {
return errors.New("Gobeet: " + msg)
}

func PingStatus(site *site.Page, resChan chan error) {
defer close(resChan)
client.Timeout = time.Duration(site.Timeout) * time.Millisecond
req, err := http.NewRequest(site.Method, site.Url, nil)
if err != nil {
res <- error
req, errReq := http.NewRequest(site.Method, site.Url, nil)
if errReq != nil {
resChan <- errReq
return
}
resHttp, errHttp := client.Do(req)
if errHttp != nil {
resChan <- errHttp
return
}
if resHttp.StatusCode != site.Status {
resChan <- GobeetError(fmt.Sprintf("%s: Method %d != %d", site.Url, resHttp.StatusCode, site.Status))
return
}
res, err := client.Do(req)
if err != nil {
res <- error
fmt.Printf("\t %s = %d\n", site.Url, site.Status)
}

func PingWebsite(website *site.Website) {
for {
fmt.Println(website.Url)
for _, page := range website.Pages {
ret := make(chan error)
go PingStatus(&page, ret)
for e := range ret {
handleError(e, &page)
}
}
time.Sleep(time.Duration(website.Interval) * time.Millisecond)
}
fmt.Println(res)
}

func handleError(e error, pg *site.Page) {
fmt.Println("Error: ")
fmt.Println(e)
fmt.Println(*pg)
email.SendAlert(e, pg)
}
84 changes: 76 additions & 8 deletions sampleconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,85 @@
{
"name": "daniel",
"email": {
"address": "[email protected]",
"recipients": ["[email protected]"],
"server": "smtp.gmail.com",
"port": "587",
"template": "sampletemplate.tmpl"
},
"sites": [
{
"url": "www.github.com",
"interval": 6000,
"url": "www.dberezin.com",
"interval": 60000,
"pages": [
{
"status": 404,
"status": 200,
"url": "https://dberezin.com",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "http://dberezin.com",
"timeout": 200,
"method": "GET"
}
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "https://dberezin.com/portfolio",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "https://dberezin.com/about",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "https://dberezin.com/static/pdf/Resume.pdf",
"timeout": 2000,
"method": "GET",
"duration": 10000
}
]
}, {
"url": "www.viviannghiem.com",
"interval": 60000,
"pages": [
{
"status": 200,
"url": "http://viviannghiem.com",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "http://viviannghiem.com/pages/about",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "http://viviannghiem.com/pages/portfolio",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 200,
"url": "http://viviannghiem.com/pages/",
"timeout": 2000,
"method": "GET",
"duration": 10000
}, {
"status": 404,
"url": "http://viviannghiem.com/pages/adsfasfdgsdf",
"timeout": 2000,
"method": "GET",
"duration": 10000
}
]
}
}
]
}
}
42 changes: 42 additions & 0 deletions sampletemplate.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gobeet Error</title>
<style>
body {
font-family: "Segoe UI", "Lucida Grande", Tahoma, sans-serif;
font-size: 100%;
margin: 0;
}
.header {
background-color: #e9ecef;
padding: 15px;
}
.content {
padding: 15px;
}
.pre {
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
background-color: aliceblue;
padding: 15px;
}
a {
color: #3097D1;
}
</style>
</head>
<body>
<div class="header">
<h1>Your website, <a href="{{.Site.Url}}">{{.Site.Url}}</a> is down!</h1>
</div>
<div class="content">
<h3>The error is: </h3>
<div class="pre">
{{.Error}}
</div>
</div>
</body>
</html>
13 changes: 5 additions & 8 deletions site/site.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package site

import (
// "time"
)

type Website struct {
Url string `json: url`
Interval int `json: interval`
Pages []Page `json: pages`
}

type Page struct {
Url string `json: url`
Status int `json: status`
Method string `json: method`
Timeout int `json: timeout`
Url string `json: url`
Status int `json: status`
Method string `json: method`
Timeout int `json: timeout`
Duration int `json: duration`
}

0 comments on commit 8340136

Please sign in to comment.