Commit db314fd2 authored by Stephan Handuwala's avatar Stephan Handuwala 🏋🏻

Merge branch 'master' into 'master'

Master

See merge request !4
parents 100582dc ad8bc85d
File added
...@@ -19,8 +19,8 @@ requests: ...@@ -19,8 +19,8 @@ requests:
header_type: Content-Type header_type: Content-Type
header_json: application/json header_json: application/json
mailgun: mailgun:
domain: sandbox69b93297d9f045b5ae2383ee3b5d234c.mailgun.org domain: mailgun-bp.comsolvia.se
apikey: 0b6326227e0797740c93e5cfffc901c1-49a2671e-e9e05eca apikey: 68efe0d516a7f70133fee60a2cd5ceba-6140bac2-41d4c8d2
error_report: error_report:
error_sender: qa@parkwaylabs.com error_sender: qa@parkwaylabs.com
error_head: Email Worker Crashed error_head: Email Worker Crashed
......
...@@ -10,11 +10,14 @@ package main ...@@ -10,11 +10,14 @@ package main
*/ */
import ( import (
"context" "context"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"os"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
...@@ -84,13 +87,15 @@ type Couchdb struct { ...@@ -84,13 +87,15 @@ type Couchdb struct {
* email document structure * email document structure
*/ */
type MailBody struct { type MailBody struct {
ID string `json:"_id"` ID string `json:"_id"`
Rev string `json:"_rev"` Rev string `json:"_rev"`
From string `json:"from"` From string `json:"from"`
To string `json:"to"` To string `json:"to"`
Cc string `json:"cc"` Cc string `json:"cc"`
Subject string `json:"subject"` Bcc string `json:"bcc"`
Body string `json:"body"` Subject string `json:"subject"`
Body string `json:"body"`
Attachment string `json:"attachment"`
} }
/** /**
...@@ -101,6 +106,7 @@ var waitGroup sync.WaitGroup ...@@ -101,6 +106,7 @@ var waitGroup sync.WaitGroup
var mailData chan string var mailData chan string
var outboxReadTime chan string var outboxReadTime chan string
var outboxDeleteTime chan string var outboxDeleteTime chan string
var filename = ""
func main() { func main() {
// get configurations // get configurations
...@@ -114,148 +120,156 @@ func main() { ...@@ -114,148 +120,156 @@ func main() {
panic(configErr) panic(configErr)
} }
if config.AppMod.Production == "0" { _, reqErrOutbox := http.NewRequest(config.Requests.Get, config.Curl.CheckMail, nil)
fmt.Println("Starting the Email Manager...") if reqErrOutbox != nil {
} fmt.Println("Error Connectiong to CouchDB. Error is :\n" + reqErrOutbox.Error())
time.Sleep(time.Millisecond * 300) // panic(reqErrOutbox)
mailData = make(chan string) os.Exit(1)
outboxReadTime = make(chan string) } else {
outboxDeleteTime = make(chan string)
for i := 1; i < 4; i++ {
waitGroup.Add(1)
go worker(i)
}
for 1 == 1 {
if childs < 4 {
childs++
//time.Sleep(time.Second * 1)
/**
* make cURL request to read "OUTBOX" DB for documents
* the following cURL request returns the oldest document of the DB
*
*/
req, reqErr := http.NewRequest(config.Requests.Get, config.Curl.CheckMail, nil)
//req, reqErr := http.NewRequest("GET", "http://root:root@0.0.0.0:5984/outbox/_all_docs/?limit=1", nil)
if reqErr != nil {
alert := " Error creating request to OUTBOX DB \n" + reqErr.Error()
alertAdmin(alert)
panic(reqErr)
}
req.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson)
resp, respErr := http.DefaultClient.Do(req)
if respErr != nil {
alert := " Error in getting email from the OUTBOX DB \n" + respErr.Error()
alertAdmin(alert)
panic(respErr)
}
defer resp.Body.Close()
respbody, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(respbody))
/**
* struct the response of the of the cURL request
* after "Unmarshal", the "newDoc" holds the data of the cURL request
*/
var newDoc Couchdb
err1 := json.Unmarshal(respbody, &newDoc)
if err1 != nil {
alert := " Error converting the OUTBOX response to JSON String \n" + err1.Error()
alertAdmin(alert)
}
/** if config.AppMod.Production == "0" {
* if: the "OUTBOX" DB has new records, it returns the number of Rows fmt.Println("Starting the Email Manager...")
* so there are new documents the value is always greaterthan 0 }
* and we send newEmail Document as JSONstring through the channel time.Sleep(time.Millisecond * 300)
* mailData = make(chan string)
* else: send "ko" outboxReadTime = make(chan string)
*/ outboxDeleteTime = make(chan string)
if newDoc.TotalRows > 0 {
for i := 1; i < 4; i++ {
waitGroup.Add(1)
go worker(i)
}
/** for 1 == 1 {
* get Document ID and Revision ID if childs < 4 {
* @type {[type]} childs++
*/ //time.Sleep(time.Second * 1)
newMailID := newDoc.Rows[0].ID
newMailRev := newDoc.Rows[0].Value.Rev
/** /**
* Now we get the documents' email data from the "OUTBOX" DB * make cURL request to read "OUTBOX" DB for documents
* cURL reuest to get the document * the following cURL request returns the oldest document of the DB
*
*/ */
req, reqErr := http.NewRequest(config.Requests.Get, config.Curl.GetOutboxMail+newMailID, nil) req, reqErr := http.NewRequest(config.Requests.Get, config.Curl.CheckMail, nil)
req.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson) //req, reqErr := http.NewRequest("GET", "http://root:root@0.0.0.0:5984/outbox/_all_docs/?limit=1", nil)
resp, respErr := http.DefaultClient.Do(req)
if reqErr != nil { if reqErr != nil {
alert := " Error requesting the OUTBOX mail data \n" + reqErr.Error() alert := " Error creating request to OUTBOX DB \n" + reqErr.Error()
alertAdmin(alert) alertAdmin(alert)
panic(reqErr)
} }
req.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson)
resp, respErr := http.DefaultClient.Do(req)
if respErr != nil { if respErr != nil {
alert := " Error getting the OUTBOX mail data \n" + respErr.Error() alert := " Error in getting email from the OUTBOX DB \n" + respErr.Error()
alertAdmin(alert) alertAdmin(alert)
panic(respErr)
} }
defer resp.Body.Close() defer resp.Body.Close()
respbody, _ := ioutil.ReadAll(resp.Body) respbody, _ := ioutil.ReadAll(resp.Body)
newMail := string(respbody) //fmt.Println(string(respbody))
readTimeOutbox := time.Now().String()
// mailReadTime := mailReadTime.String()
/** /**
* structuring the email document * struct the response of the of the cURL request
* * after "Unmarshal", the "newDoc" holds the data of the cURL request
*/ */
var mail MailBody var newDoc Couchdb
mailErr := json.Unmarshal([]byte(newMail), &mail) err1 := json.Unmarshal(respbody, &newDoc)
if mailErr != nil { if err1 != nil {
alert := " Error converting OUTBOX DB mail data into JSON string \n" + mailErr.Error() alert := " Error converting the OUTBOX response to JSON String \n" + err1.Error()
alertAdmin(alert) alertAdmin(alert)
} }
/** /**
* Send email document as JSONstring * if: the "OUTBOX" DB has new records, it returns the number of Rows
* so there are new documents the value is always greaterthan 0
* and we send newEmail Document as JSONstring through the channel
*
* else: send "ko"
*/ */
mailData <- (newMail) if newDoc.TotalRows > 0 {
outboxReadTime <- (readTimeOutbox)
// data <- ("Worker " + strconv.Itoa(childs)) /**
* get Document ID and Revision ID
* @type {[type]}
*/
newMailID := newDoc.Rows[0].ID
newMailRev := newDoc.Rows[0].Value.Rev
/**
* Now we get the documents' email data from the "OUTBOX" DB
* cURL reuest to get the document
*/
req, reqErr := http.NewRequest(config.Requests.Get, config.Curl.GetOutboxMail+newMailID, nil)
req.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson)
resp, respErr := http.DefaultClient.Do(req)
if reqErr != nil {
alert := " Error requesting the OUTBOX mail data \n" + reqErr.Error()
alertAdmin(alert)
}
if respErr != nil {
alert := " Error getting the OUTBOX mail data \n" + respErr.Error()
alertAdmin(alert)
}
defer resp.Body.Close()
respbody, _ := ioutil.ReadAll(resp.Body)
newMail := string(respbody)
readTimeOutbox := time.Now().String()
// mailReadTime := mailReadTime.String()
/**
* structuring the email document
*
*/
var mail MailBody
mailErr := json.Unmarshal([]byte(newMail), &mail)
if mailErr != nil {
alert := " Error converting OUTBOX DB mail data into JSON string \n" + mailErr.Error()
alertAdmin(alert)
}
/**
* Send email document as JSONstring
*/
mailData <- (newMail)
outboxReadTime <- (readTimeOutbox)
// data <- ("Worker " + strconv.Itoa(childs))
/**
* Delete the document from the "OUTBOX"
*/
delReq, delReqerr := http.NewRequest(config.Requests.Delete, config.Curl.DeleteOutboxMail+newMailID+"?rev="+newMailRev, nil)
if delReqerr != nil {
alert := " Error requesting to delete mail from OUTBOX \n" + delReqerr.Error()
alertAdmin(alert)
}
delReq.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson)
delResp, delResperr := http.DefaultClient.Do(delReq)
if delResperr != nil {
alert := " Error deleting mail from OUTBOX DB \n" + delResperr.Error()
alertAdmin(alert)
}
defer delResp.Body.Close()
ioutil.ReadAll(delResp.Body)
deleteTimeOutbox := time.Now().String()
outboxDeleteTime <- (deleteTimeOutbox)
} else {
mailData <- "ko"
outboxReadTime <- ""
outboxDeleteTime <- ""
/**
* Delete the document from the "OUTBOX"
*/
delReq, delReqerr := http.NewRequest(config.Requests.Delete, config.Curl.DeleteOutboxMail+newMailID+"?rev="+newMailRev, nil)
if delReqerr != nil {
alert := " Error requesting to delete mail from OUTBOX \n" + delReqerr.Error()
alertAdmin(alert)
}
delReq.Header.Set(config.Requests.HeaderType, config.Requests.HeaderJson)
delResp, delResperr := http.DefaultClient.Do(delReq)
if delResperr != nil {
alert := " Error deleting mail from OUTBOX DB \n" + delResperr.Error()
alertAdmin(alert)
} }
defer delResp.Body.Close()
ioutil.ReadAll(delResp.Body)
deleteTimeOutbox := time.Now().String()
outboxDeleteTime <- (deleteTimeOutbox)
} else {
mailData <- "ko"
outboxReadTime <- ""
outboxDeleteTime <- ""
} }
} }
}
close(mailData) close(mailData)
close(outboxReadTime) close(outboxReadTime)
close(outboxDeleteTime) close(outboxDeleteTime)
waitGroup.Wait() waitGroup.Wait()
}
} }
func worker(i int) { func worker(i int) {
...@@ -312,16 +326,60 @@ func worker(i int) { ...@@ -312,16 +326,60 @@ func worker(i int) {
body := mail.Body body := mail.Body
recipient := mail.To recipient := mail.To
cc := mail.Cc cc := mail.Cc
bcc := mail.Bcc
attachment := mail.Attachment
// sending mail via Mailgun // sending mail via Mailgun
mg := mailgun.NewMailgun(config.Mailgun.Domain, config.Mailgun.Apikey) mg := mailgun.NewMailgun(config.Mailgun.Domain, config.Mailgun.Apikey)
message := mg.NewMessage(sender, subject, body, recipient) message := mg.NewMessage(sender, subject, body, recipient)
/** /**
* Add CC if cc recipiants are available * Add CC, BCC & ATTACHMENTS if available
*/ */
if len(cc) > 0 { if len(cc) > 0 {
message.AddCC(cc) message.AddCC(cc)
} }
if len(bcc) > 0 {
message.AddBCC(bcc)
}
if len(attachment) > 0 {
//url := "http://www.orimi.com/pdf-test.pdf"
attachReq, _ := http.NewRequest("GET", attachment, nil)
attchResp, err := http.DefaultClient.Do(attachReq)
// if
//if(attachErr != nil)
//attchResp, err := http.DefaultClient.Do(attachReq)
if err != nil {
panic(err)
}
defer attchResp.Body.Close()
respbody, _ := ioutil.ReadAll(attchResp.Body)
resp := string(respbody)
time := time.Now().UnixNano()
filename = strconv.FormatInt(time, 10) + ".pdf"
dec, err := base64.StdEncoding.DecodeString(resp)
if err != nil {
panic(err)
}
f, err := os.Create(filename)
if err != nil {
panic(err)
}
//defer f.Close()
if _, err := f.Write(dec); err != nil {
panic(err)
}
if err := f.Sync(); err != nil {
panic(err)
}
//message.AddHeader("Content-Type", "multipart/form-data")
message.AddAttachment(filename)
// message.AddReaderAttachment(filename, f)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel() defer cancel()
MailgunResp, id, err := mg.Send(ctx, message) MailgunResp, id, err := mg.Send(ctx, message)
...@@ -329,17 +387,19 @@ func worker(i int) { ...@@ -329,17 +387,19 @@ func worker(i int) {
log.Fatal(err) log.Fatal(err)
//alertAdmin(" MAilgun Error \n" + err.Error()) //alertAdmin(" MAilgun Error \n" + err.Error())
} }
if len(filename) > 0 {
os.Remove(filename)
}
//fmt.Println(resp) //fmt.Println(resp)
if config.AppMod.Production == "0" { if config.AppMod.Production == "0" {
fmt.Printf("Email sent ID: %s Resp: %s\n", id, MailgunResp) fmt.Printf("Email sent ID: %s Resp: %s\n", id, MailgunResp)
} }
//sendMessage(mg, sender, subject, body, recipient, cc) //sendMessage(mg, sender, subject, body, recipient, cc)
mailSentTimeMailgun := time.Now().String() mailSentTimeMailgun := time.Now().String()
/** /**
* add the email as new document in "SENT ITEMS" DB * add the email as new document in "SENT ITEMS" DB
*/ */
mailBody := strings.NewReader(`{"from":"` + sender + `","to":"` + recipient + `","subject":"` + subject + `","body":"` + body + `"}`) mailBody := strings.NewReader(`{"from":"` + sender + `","to":"` + recipient + `","subject":"` + subject + `","body":"` + body + `","cc":"` + cc + `","bcc":"` + bcc + `","attachment":"` + attachment + `"}`)
req, mailBodyerr := http.NewRequest(config.Requests.Put, config.Curl.AddSentMail+mail.ID, mailBody) req, mailBodyerr := http.NewRequest(config.Requests.Put, config.Curl.AddSentMail+mail.ID, mailBody)
if mailBodyerr != nil { if mailBodyerr != nil {
alert := " Error requesting newmail to add in SENTITEMS DB \n" + mailBodyerr.Error() alert := " Error requesting newmail to add in SENTITEMS DB \n" + mailBodyerr.Error()
...@@ -355,7 +415,7 @@ func worker(i int) { ...@@ -355,7 +415,7 @@ func worker(i int) {
ioutil.ReadAll(resp.Body) ioutil.ReadAll(resp.Body)
mailAddedSentitems := time.Now().String() mailAddedSentitems := time.Now().String()
logmail(subject, sender, recipient, readTimeOutbox, mailSentTimeMailgun, id, MailgunResp, mailAddedSentitems, deleteTimeOutbox, mail.ID) logmail(subject, sender, recipient, cc, bcc, attachment, readTimeOutbox, mailSentTimeMailgun, id, MailgunResp, mailAddedSentitems, deleteTimeOutbox, mail.ID)
} }
...@@ -426,7 +486,7 @@ func alertAdmin(err string) { ...@@ -426,7 +486,7 @@ func alertAdmin(err string) {
/** /**
* log worker tasks * log worker tasks
*/ */
func logmail(subject, sender, recipient, readTimeOutbox, mailSentTimeMailgun, id, MailgunResp, mailAddedSentitems, deleteTimeOutbox, mailID string) { func logmail(subject, sender, recipient, cc, bcc, attachment, readTimeOutbox, mailSentTimeMailgun, id, MailgunResp, mailAddedSentitems, deleteTimeOutbox, mailID string) {
// get configurations // get configurations
var config Config var config Config
...@@ -442,6 +502,9 @@ func logmail(subject, sender, recipient, readTimeOutbox, mailSentTimeMailgun, id ...@@ -442,6 +502,9 @@ func logmail(subject, sender, recipient, readTimeOutbox, mailSentTimeMailgun, id
logBody := strings.NewReader(`{"Mail Subject":"` + subject + logBody := strings.NewReader(`{"Mail Subject":"` + subject +
`","Mail sender":"` + sender + `","Mail sender":"` + sender +
`","Mail recipiants":"` + recipient + `","Mail recipiants":"` + recipient +
`","Mail cc":"` + cc +
`","Mail bcc":"` + bcc +
`","Mail attachment":"` + attachment +
`","OUTBOX read time":"` + readTimeOutbox + `","OUTBOX read time":"` + readTimeOutbox +
`","Mail sent to mailgun":"` + mailSentTimeMailgun + `","Mail sent to mailgun":"` + mailSentTimeMailgun +
`","Mailgun ID":"` + id + `","Mailgun ID":"` + id +
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment