refactor email send functions, integrate check_nodes in mini-beieli-web
This commit is contained in:
parent
1feb6961bd
commit
681005f10e
|
|
@ -1,399 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"github.com/jordan-wright/email"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func sendEmailAccu(username string, alias string, deveui string, accu_percent string, threshold int, level string) {
|
||||
fmt.Printf("SEND EMAIL ACCU (%s) - %s:%s\n", level, username, deveui)
|
||||
mail_message := `Lieber Benutzer von mini-beieli.ch
|
||||
|
||||
Der Akku von "` + alias + `" (DevEUI: ` + deveui + `) ist noch zu ` + accu_percent + ` Prozent geladen.
|
||||
|
||||
Bitte rechtzeitig wieder laden! Bei 10%-er Ladung erscheint die letzte Warnung.
|
||||
|
||||
Mit freundlichen Grüssen
|
||||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
e := email.NewEmail()
|
||||
e.From = "mini-beieli.ch <info@mini-beieli.ch>"
|
||||
e.To = []string{username}
|
||||
e.Bcc = []string{"joerg.lehmann@nbit.ch"}
|
||||
e.Subject = level + " - mini-beieli.ch: Akku Ladezustand (" + alias + ")"
|
||||
e.Text = []byte(mail_message)
|
||||
e.Send("127.0.0.1:25", nil)
|
||||
}
|
||||
|
||||
func sendEmailAbo(username string, alias string, deveui string, days_left int, level string) {
|
||||
fmt.Printf("SEND EMAIL ABO (%s) - %s:%s\n", level, username, deveui)
|
||||
mail_message := `Lieber Benutzer von mini-beieli.ch
|
||||
|
||||
Das Abo von "` + alias + `" (DevEUI: ` + deveui + `) laeuft in ` + strconv.Itoa(days_left) + ` Tagen ab.
|
||||
|
||||
Bitte Abo verlaengern auf https://mini-beieli.ch
|
||||
|
||||
Mit freundlichen Grüssen
|
||||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
e := email.NewEmail()
|
||||
e.From = "mini-beieli.ch <info@mini-beieli.ch>"
|
||||
e.To = []string{username}
|
||||
e.Bcc = []string{"joerg.lehmann@nbit.ch"}
|
||||
e.Subject = level + " - mini-beieli.ch: Abo laeuft ab (" + alias + ")"
|
||||
e.Text = []byte(mail_message)
|
||||
e.Send("127.0.0.1:25", nil)
|
||||
}
|
||||
|
||||
var globalPool *redis.Pool
|
||||
|
||||
const userPrefix string = "user:"
|
||||
const devPrefix string = "dev:"
|
||||
const confirmPrefix string = "confirm:"
|
||||
|
||||
func newPool() *redis.Pool {
|
||||
return &redis.Pool{
|
||||
// Maximum number of idle connections in the pool.
|
||||
MaxIdle: 80,
|
||||
// max number of connections
|
||||
MaxActive: 12000,
|
||||
// Dial is an application supplied function for creating and
|
||||
// configuring a connection.
|
||||
Dial: func() (redis.Conn, error) {
|
||||
c, err := redis.Dial("tcp", ":6379")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return c, err
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ping tests connectivity for redis (PONG should be returned)
|
||||
func ping(c redis.Conn) error {
|
||||
// Send PING command to Redis
|
||||
// PING command returns a Redis "Simple String"
|
||||
// Use redis.String to convert the interface type to string
|
||||
s, err := redis.String(c.Do("PING"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logit("PING Response = " + s)
|
||||
// Output: PONG
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Dev struct {
|
||||
Deveui string
|
||||
Alias string
|
||||
Alarmactive string
|
||||
Smsnumber string
|
||||
ActiveUntil string // Abo bezahlt bis TT.MM.YYYY
|
||||
}
|
||||
|
||||
func initDB() {
|
||||
|
||||
// newPool returns a pointer to a redis.Pool
|
||||
pool := newPool()
|
||||
// get a connection from the globalPool (redis.Conn)
|
||||
conn := pool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
globalPool = pool
|
||||
|
||||
// wir machen einen Connection Test
|
||||
ping(conn)
|
||||
}
|
||||
|
||||
func closeDB() {
|
||||
globalPool.Close()
|
||||
}
|
||||
|
||||
func getUsers() []string {
|
||||
res := []string{}
|
||||
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
//logit("getUsers")
|
||||
users, err := redis.Strings(conn.Do("KEYS", userPrefix+"*"))
|
||||
if err == nil {
|
||||
//logit("getUsers successful!")
|
||||
res = users
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getMyDevs(username string) []string {
|
||||
res := []string{}
|
||||
|
||||
if username == "" {
|
||||
return res
|
||||
}
|
||||
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
//logit("getMyDevs: User: " + username)
|
||||
mydevs, err := redis.String(conn.Do("HGET", userPrefix+username, "my_devs"))
|
||||
if err == nil {
|
||||
//logit("getMyDevs: mydevs: " + mydevs)
|
||||
res = strings.Split(mydevs, ",")
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getDevAlias(deveui string) string {
|
||||
res := deveui
|
||||
|
||||
if deveui == "" {
|
||||
return res
|
||||
}
|
||||
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
//logit("getDevAlias: Deveui: " + deveui)
|
||||
alias, err := redis.String(conn.Do("HGET", devPrefix+deveui, "alias"))
|
||||
if err == nil {
|
||||
//logit("getDevAlias: alias: " + alias)
|
||||
res = alias
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getActiveUntil(deveui string) string {
|
||||
res := ""
|
||||
|
||||
if deveui == "" {
|
||||
return res
|
||||
}
|
||||
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
//logit("getActiveUntil: Deveui: " + deveui)
|
||||
activeuntil, err := redis.String(conn.Do("HGET", devPrefix+deveui, "active_until"))
|
||||
if err == nil {
|
||||
//logit("getActiveUntil: activeuntil: " + activeuntil)
|
||||
res = activeuntil
|
||||
} else {
|
||||
log.Print(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func InsertAlert(prefix string, deveui string, email string, threshold int) {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
_, err := conn.Do("SET", prefix+deveui+":"+email, threshold)
|
||||
if err != nil {
|
||||
logit("InsertAlert: Error inserting: " + prefix + deveui + ":" + email)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteAlert(prefix string, deveui string, email string) {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email))
|
||||
|
||||
if exists {
|
||||
_, err := conn.Do("DEL", prefix+deveui+":"+email)
|
||||
if err != nil {
|
||||
logit("DeleteAlert: Error deleting: " + prefix + deveui + ":" + email)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AlarmNotAlreadySent(prefix string, deveui string, email string, threshold int) bool {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email))
|
||||
if !exists {
|
||||
return true
|
||||
}
|
||||
alarm_threshold, _ := redis.Int(conn.Do("GET", prefix+deveui+":"+email))
|
||||
return threshold != alarm_threshold
|
||||
}
|
||||
|
||||
type OneMetric struct {
|
||||
Deveui string
|
||||
Alias string
|
||||
Timestamp string
|
||||
BatteryPercent string
|
||||
ActiveUntil string
|
||||
DaysUntilDeactivated int // berechneter Wert
|
||||
}
|
||||
|
||||
func CalcDaysUntil(mydate string) int {
|
||||
var days int
|
||||
layout := "02.01.2006"
|
||||
t, err := time.Parse(layout, mydate)
|
||||
|
||||
if err != nil {
|
||||
days = 0
|
||||
}
|
||||
days = int(t.Sub(time.Now()).Hours() / 24)
|
||||
|
||||
return days
|
||||
}
|
||||
|
||||
func getLastMetrics(deveui string) OneMetric {
|
||||
var res OneMetric
|
||||
|
||||
url := "http://localhost:8086/api/v2/query?org=minibeieliorg"
|
||||
data := []byte(fmt.Sprintf(`from(bucket:"minibeielibucket")
|
||||
|> range(start:-5d)
|
||||
|> filter(fn: (r) => r._measurement == "measurement" and r.deveui == "%s")
|
||||
|> filter(fn: (r) => r._field == "vp")
|
||||
|> last(column: "_time") |> yield(name: "last")`, deveui))
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
log.Fatal("Error reading request. ", err)
|
||||
}
|
||||
|
||||
// Set headers
|
||||
var INFLUX_RO_TOKEN = os.Getenv("INFLUX_RO_TOKEN")
|
||||
|
||||
// Set headers
|
||||
req.Header.Set("Authorization", "Token "+INFLUX_RO_TOKEN)
|
||||
req.Header.Set("accept", "application/csv")
|
||||
req.Header.Set("content-type", "application/vnd.flux")
|
||||
|
||||
// Set client timeout
|
||||
client := &http.Client{Timeout: time.Second * 10}
|
||||
|
||||
// Send request
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Fatal("Error reading response. ", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
//fmt.Println("response Status:", resp.Status)
|
||||
//fmt.Println("response Headers:", resp.Header)
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatal("Error reading body. ", err)
|
||||
}
|
||||
//fmt.Println("response Body:", string(body))
|
||||
|
||||
scanner := bufio.NewScanner(strings.NewReader(string(body)))
|
||||
location, err := time.LoadLocation("Europe/Zurich")
|
||||
for scanner.Scan() {
|
||||
s := strings.Split(scanner.Text(), ",")
|
||||
if (len(s) >= 7) && !(strings.HasPrefix(s[5], "_")) {
|
||||
mytime, err := time.Parse(time.RFC3339, s[5])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
res.Timestamp = mytime.In(location).Format("02.01.2006 15:04")
|
||||
value := s[6]
|
||||
field := s[7]
|
||||
if field == "vp" {
|
||||
res.BatteryPercent = value
|
||||
}
|
||||
}
|
||||
}
|
||||
res.Deveui = deveui
|
||||
res.Alias = getDevAlias(deveui)
|
||||
res.ActiveUntil = getActiveUntil(deveui)
|
||||
res.DaysUntilDeactivated = CalcDaysUntil(res.ActiveUntil)
|
||||
return res
|
||||
}
|
||||
|
||||
func CheckThreshold(d string, vp int, u2 string, last_metric OneMetric, info_threshold int, warning_threshold int, alert_threshold int) bool {
|
||||
var alias string
|
||||
if vp <= info_threshold {
|
||||
alias = getDevAlias(d)
|
||||
}
|
||||
if vp <= alert_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, alert_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "ALARM")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, alert_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
if vp <= warning_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, warning_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, warning_threshold, "WARNING")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, warning_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
if vp <= info_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, info_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "INFO")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, info_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func logit(log_message string) {
|
||||
log.Println(log_message)
|
||||
}
|
||||
|
||||
func main() {
|
||||
logit("Starting check_battery...")
|
||||
initDB()
|
||||
defer closeDB()
|
||||
|
||||
users := getUsers()
|
||||
for _, u := range users {
|
||||
//fmt.Println(u)
|
||||
u2 := u[5:]
|
||||
my_devs := getMyDevs(u2)
|
||||
for _, d := range my_devs {
|
||||
//fmt.Printf("%s:%s\n", u2, d)
|
||||
if !strings.HasPrefix(d, "@") {
|
||||
last_metric := getLastMetrics(d)
|
||||
// Zuerst der Batteriealarm
|
||||
if last_metric.BatteryPercent != "" {
|
||||
fmt.Printf("%s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated)
|
||||
vp, _ := strconv.Atoi(last_metric.BatteryPercent)
|
||||
if CheckThreshold(d, vp, u2, last_metric, 50, 20, 10) {
|
||||
DeleteAlert("alarm_sent_accu:", d, u2)
|
||||
}
|
||||
}
|
||||
// Jetzt der Alarm wegen der Abodauer
|
||||
if last_metric.DaysUntilDeactivated < 30 {
|
||||
fmt.Printf("SEND EMAIL %s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated)
|
||||
alias := getDevAlias(d)
|
||||
sendEmailAbo("joerg.lehmann@nbit.ch", alias, d, last_metric.DaysUntilDeactivated, "INFO")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logit("Done with check_battery...")
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func sendEmailAccu(username string, alias string, deveui string, accu_percent string, threshold int, level string) {
|
||||
fmt.Printf("SEND EMAIL ACCU (%s) - %s:%s\n", level, username, deveui)
|
||||
mail_message := "To: " + username + `
|
||||
From: info@mini-beieli.ch
|
||||
Subject: ` + level + ` - mini-beieli.ch: Akku Ladezustand (` + alias + `)
|
||||
|
||||
Lieber Benutzer von mini-beieli.ch
|
||||
|
||||
Der Akku von "` + alias + `" (DevEUI: ` + deveui + `) ist noch zu ` + accu_percent + ` Prozent geladen.
|
||||
|
||||
Bitte rechtzeitig wieder laden! Bei Unterschreitung von 5% Ladung erscheint die letzte Warnung.
|
||||
|
||||
Mit freundlichen Grüssen
|
||||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
sendEmail(username, "mail@mini-beieli.ch", mail_message)
|
||||
}
|
||||
|
||||
func sendEmailAbo(username string, alias string, deveui string, days_left int, level string) {
|
||||
var ablauftext string
|
||||
if days_left == 0 {
|
||||
fmt.Printf("SEND EMAIL ABO (%s) - %s:%s\n", level, username, deveui)
|
||||
ablauftext = "Das Abo von \"" + alias + "\" (DevEUI: " + deveui + ") ist abgelaufen."
|
||||
} else if days_left > 0 {
|
||||
fmt.Printf("SEND EMAIL ABO (%s) - %s:%s\n", level, username, deveui)
|
||||
ablauftext = "Das Abo von \"" + alias + "\" (DevEUI: " + deveui + ") laeuft in " + strconv.Itoa(days_left) + " Tagen ab."
|
||||
} else {
|
||||
fmt.Printf("DO NOT SEND EMAIL ABO (%s) - %s:%s\n", level, username, deveui)
|
||||
return
|
||||
}
|
||||
mail_message := "To: " + username + `
|
||||
From: info@mini-beieli.ch
|
||||
Subject: ` + level + ` - mini-beieli.ch: Abo verlaengern (` + alias + `)
|
||||
|
||||
Lieber Benutzer von mini-beieli.ch
|
||||
|
||||
` + ablauftext + `
|
||||
|
||||
Bitte Abo verlaengern auf https://mini-beieli.ch
|
||||
|
||||
Mit freundlichen Grüssen
|
||||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
sendEmail(username, "mail@mini-beieli.ch", mail_message)
|
||||
}
|
||||
|
||||
func CheckThreshold(d string, vp int, u2 string, last_metric OneMetric, info_threshold int, warning_threshold int, alert_threshold int) bool {
|
||||
var alias string
|
||||
if vp <= info_threshold {
|
||||
alias = getDevAlias(d)
|
||||
}
|
||||
if vp <= alert_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, alert_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "ALARM")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, alert_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
if vp <= warning_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, warning_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, warning_threshold, "WARNING")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, warning_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
if vp <= info_threshold {
|
||||
if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, info_threshold) {
|
||||
sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "INFO")
|
||||
InsertAlert("alarm_sent_accu:", d, u2, info_threshold)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func checkNodes() {
|
||||
logit("Starting check_battery...")
|
||||
|
||||
users := getUsers()
|
||||
for _, u := range users {
|
||||
//fmt.Println(u)
|
||||
u2 := u[5:]
|
||||
my_devs := getMyDevs(u2)
|
||||
for _, d := range my_devs {
|
||||
fmt.Printf("%s:%s\n", u2, d)
|
||||
if !strings.HasPrefix(d, "@") {
|
||||
last_metric := getLastMetrics(d)
|
||||
// Zuerst der Batteriealarm
|
||||
if last_metric.BatteryPercent != "" {
|
||||
fmt.Printf("%s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated)
|
||||
vp, _ := strconv.Atoi(last_metric.BatteryPercent)
|
||||
if CheckThreshold(d, vp, u2, last_metric, 20, 10, 5) {
|
||||
DeleteAlert("alarm_sent_accu:", d, u2)
|
||||
}
|
||||
}
|
||||
// Jetzt der Alarm wegen der Abodauer
|
||||
if last_metric.DaysUntilDeactivated < 30 {
|
||||
fmt.Printf("SEND EMAIL %s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated)
|
||||
alias := getDevAlias(d)
|
||||
sendEmailAbo(u2, alias, d, last_metric.DaysUntilDeactivated, "INFO")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logit("Done with check_battery...")
|
||||
}
|
||||
|
||||
func checkNodesHandler(w http.ResponseWriter, req *http.Request) {
|
||||
headers := req.Header
|
||||
|
||||
val, ok := headers["X-Checknodes"]
|
||||
if ok {
|
||||
fmt.Printf("X-Checknodes header is present with value %s\n", val)
|
||||
checkNodes()
|
||||
} else {
|
||||
fmt.Println("X-Checknodes header is not present")
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
module nbit.ch/mini-beieli-web/v2
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/gomodule/redigo v1.8.9
|
||||
github.com/gorilla/securecookie v1.1.1
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||
github.com/stripe/stripe-go v70.15.0+incompatible
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
|
||||
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stripe/stripe-go v70.15.0+incompatible h1:hNML7M1zx8RgtepEMlxyu/FpVPrP7KZm1gPFQquJQvM=
|
||||
github.com/stripe/stripe-go v70.15.0+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Contains tells whether a contains x.
|
||||
|
|
@ -18,3 +19,11 @@ func Contains(a []string, x string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getenv(key, fallback string) string {
|
||||
value := os.Getenv(key)
|
||||
if len(value) == 0 {
|
||||
return fallback
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
|
|
|||
63
mail.go
63
mail.go
|
|
@ -1,27 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"net/smtp"
|
||||
)
|
||||
|
||||
func sendEmail(username, confirm_id string) {
|
||||
c, err := smtp.Dial("127.0.0.1:25")
|
||||
func sendEmail(mail_to, mail_default_authuser, mail_message string) {
|
||||
var auth smtp.Auth
|
||||
if getenv("MAILSERVER_USER", "") != "" {
|
||||
// Set up authentication information.
|
||||
auth = smtp.PlainAuth(
|
||||
"",
|
||||
getenv("MAILSERVER_USER", ""),
|
||||
getenv("MAILSERVER_PASSWORD", ""),
|
||||
getenv("MAILSERVER_HOST", "127.0.0.1"),
|
||||
)
|
||||
}
|
||||
// Connect to the server, authenticate, set the sender and recipient,
|
||||
// and send the email all in one step.
|
||||
err := smtp.SendMail(
|
||||
getenv("MAILSERVER_HOST", "127.0.0.1")+":"+getenv("MAILSERVER_PORT", "25"),
|
||||
auth,
|
||||
getenv("MAILSERVER_USER", mail_default_authuser),
|
||||
[]string{mail_to, "info@mini-beieli.ch"},
|
||||
[]byte(mail_message),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
// Set the sender and recipient.
|
||||
c.Mail("register@mini-beieli.ch")
|
||||
c.Rcpt(username)
|
||||
// Send the email body.
|
||||
wc, err := c.Data()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer wc.Close()
|
||||
}
|
||||
|
||||
func sendEmailConfirm(username, confirm_id string) {
|
||||
mail_message := "To: " + username + `
|
||||
From: register@mini-beieli.ch
|
||||
Subject: Passwortaenderung auf https://mini-beieli.ch, bitte bestaetigen
|
||||
|
||||
Lieber Benutzer von mini-beieli.ch
|
||||
|
|
@ -37,28 +49,12 @@ Mit freundlichen Grüssen
|
|||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
buf := bytes.NewBufferString(mail_message)
|
||||
if _, err = buf.WriteTo(wc); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sendEmail(username, "mail@mini-beieli.ch", mail_message)
|
||||
}
|
||||
|
||||
func sendPaymentConfirmationEmail(username, charge_data string, amount int64) {
|
||||
c, err := smtp.Dial("127.0.0.1:25")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
// Set the sender and recipient.
|
||||
c.Mail("info@mini-beieli.ch")
|
||||
c.Rcpt(username)
|
||||
// Send the email body.
|
||||
wc, err := c.Data()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer wc.Close()
|
||||
mail_message := "To: " + username + `
|
||||
From: info@mini-beieli.ch
|
||||
Subject: Zahlungsbestaetigung mini-beieli.ch
|
||||
|
||||
Lieber Benutzer von mini-beieli.ch
|
||||
|
|
@ -71,8 +67,5 @@ Mit freundlichen Grüssen
|
|||
--
|
||||
mini-beieli.ch`
|
||||
|
||||
buf := bytes.NewBufferString(mail_message)
|
||||
if _, err = buf.WriteTo(wc); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sendEmail(username, "mail@mini-beieli.ch", mail_message)
|
||||
}
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -99,6 +99,7 @@ func main() {
|
|||
http.HandleFunc("/save_scale_settings", save_scale_settingsHandler)
|
||||
http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler)
|
||||
http.HandleFunc("/stripewebhook", stripeWebhookHandler)
|
||||
http.HandleFunc("/checknodes", checkNodesHandler)
|
||||
|
||||
logit("Starting Web Application...")
|
||||
http.ListenAndServe("127.0.0.1:4000", nil)
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ func updateUser(username, password string) {
|
|||
return
|
||||
}
|
||||
|
||||
sendEmail(username, confirm_id)
|
||||
sendEmailConfirm(username, confirm_id)
|
||||
}
|
||||
|
||||
func checkLoginCredentials(username, password string) bool {
|
||||
|
|
@ -454,3 +454,39 @@ func confirmUser(confirm_id string) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
func InsertAlert(prefix string, deveui string, email string, threshold int) {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
_, err := conn.Do("SET", prefix+deveui+":"+email, threshold)
|
||||
if err != nil {
|
||||
logit("InsertAlert: Error inserting: " + prefix + deveui + ":" + email)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteAlert(prefix string, deveui string, email string) {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email))
|
||||
|
||||
if exists {
|
||||
_, err := conn.Do("DEL", prefix+deveui+":"+email)
|
||||
if err != nil {
|
||||
logit("DeleteAlert: Error deleting: " + prefix + deveui + ":" + email)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AlarmNotAlreadySent(prefix string, deveui string, email string, threshold int) bool {
|
||||
conn := globalPool.Get()
|
||||
defer conn.Close()
|
||||
|
||||
exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email))
|
||||
if !exists {
|
||||
return true
|
||||
}
|
||||
alarm_threshold, _ := redis.Int(conn.Do("GET", prefix+deveui+":"+email))
|
||||
return threshold != alarm_threshold
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue