Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
GO Email Worker
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stephan Handuwala
GO Email Worker
Commits
db314fd2
Commit
db314fd2
authored
Apr 12, 2019
by
Stephan Handuwala
🏋🏻
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 'master'
Master See merge request
!4
parents
100582dc
ad8bc85d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
192 additions
and
129 deletions
+192
-129
.DS_Store
.DS_Store
+0
-0
config.yaml
config.yaml
+2
-2
worker.go
worker.go
+190
-127
No files found.
.DS_Store
0 → 100644
View file @
db314fd2
File added
config.yaml
View file @
db314fd2
...
...
@@ -19,8 +19,8 @@ requests:
header_type
:
Content-Type
header_json
:
application/json
mailgun
:
domain
:
sandbox69b93297d9f045b5ae2383ee3b5d234c.mailgun.org
apikey
:
0b6326227e0797740c93e5cfffc901c1-49a2671e-e9e05eca
domain
:
mailgun-bp.comsolvia.se
apikey
:
68efe0d516a7f70133fee60a2cd5ceba-6140bac2-41d4c8d2
error_report
:
error_sender
:
qa@parkwaylabs.com
error_head
:
Email Worker Crashed
...
...
worker.go
View file @
db314fd2
...
...
@@ -10,11 +10,14 @@ package main
*/
import
(
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
...
...
@@ -84,13 +87,15 @@ type Couchdb struct {
* email document structure
*/
type
MailBody
struct
{
ID
string
`json:"_id"`
Rev
string
`json:"_rev"`
From
string
`json:"from"`
To
string
`json:"to"`
Cc
string
`json:"cc"`
Subject
string
`json:"subject"`
Body
string
`json:"body"`
ID
string
`json:"_id"`
Rev
string
`json:"_rev"`
From
string
`json:"from"`
To
string
`json:"to"`
Cc
string
`json:"cc"`
Bcc
string
`json:"bcc"`
Subject
string
`json:"subject"`
Body
string
`json:"body"`
Attachment
string
`json:"attachment"`
}
/**
...
...
@@ -101,6 +106,7 @@ var waitGroup sync.WaitGroup
var
mailData
chan
string
var
outboxReadTime
chan
string
var
outboxDeleteTime
chan
string
var
filename
=
""
func
main
()
{
// get configurations
...
...
@@ -114,148 +120,156 @@ func main() {
panic
(
configErr
)
}
if
config
.
AppMod
.
Production
==
"0"
{
fmt
.
Println
(
"Starting the Email Manager..."
)
}
time
.
Sleep
(
time
.
Millisecond
*
300
)
mailData
=
make
(
chan
string
)
outboxReadTime
=
make
(
chan
string
)
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
)
}
_
,
reqErrOutbox
:=
http
.
NewRequest
(
config
.
Requests
.
Get
,
config
.
Curl
.
CheckMail
,
nil
)
if
reqErrOutbox
!=
nil
{
fmt
.
Println
(
"Error Connectiong to CouchDB. Error is :
\n
"
+
reqErrOutbox
.
Error
())
// panic(reqErrOutbox)
os
.
Exit
(
1
)
}
else
{
/**
* 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"
*/
if
newDoc
.
TotalRows
>
0
{
if
config
.
AppMod
.
Production
==
"0"
{
fmt
.
Println
(
"Starting the Email Manager..."
)
}
time
.
Sleep
(
time
.
Millisecond
*
300
)
mailData
=
make
(
chan
string
)
outboxReadTime
=
make
(
chan
string
)
outboxDeleteTime
=
make
(
chan
string
)
for
i
:=
1
;
i
<
4
;
i
++
{
waitGroup
.
Add
(
1
)
go
worker
(
i
)
}
/**
* get Document ID and Revision ID
* @type {[type]}
*/
newMailID
:=
newDoc
.
Rows
[
0
]
.
ID
newMailRev
:=
newDoc
.
Rows
[
0
]
.
Value
.
Rev
for
1
==
1
{
if
childs
<
4
{
childs
++
//time.Sleep(time.Second * 1)
/**
* Now we get the documents' email data from the "OUTBOX" DB
* cURL reuest to get the document
* 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
.
GetOutboxMail
+
newMailID
,
nil
)
req
.
Header
.
Set
(
config
.
Requests
.
HeaderType
,
config
.
Requests
.
HeaderJson
)
resp
,
respErr
:=
http
.
DefaultClient
.
Do
(
req
)
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
requesting the OUTBOX mail data
\n
"
+
reqErr
.
Error
()
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
getting the OUTBOX mail data
\n
"
+
respErr
.
Error
()
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
)
newMail
:=
string
(
respbody
)
readTimeOutbox
:=
time
.
Now
()
.
String
()
// mailReadTime := mailReadTime.String()
//fmt.Println(string(respbody))
/**
*
structuring the email documen
t
*
*
struct the response of the of the cURL reques
t
*
after "Unmarshal", the "newDoc" holds the data of the cURL request
*/
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
()
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
)
}
/**
* 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
)
outboxReadTime
<-
(
readTimeOutbox
)
// data <- ("Worker " + strconv.Itoa(childs))
if
newDoc
.
TotalRows
>
0
{
/**
* 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
(
outboxReadTime
)
close
(
outboxDeleteTime
)
waitGroup
.
Wait
()
close
(
mailData
)
close
(
outboxReadTime
)
close
(
outboxDeleteTime
)
waitGroup
.
Wait
()
}
}
func
worker
(
i
int
)
{
...
...
@@ -312,16 +326,60 @@ func worker(i int) {
body
:=
mail
.
Body
recipient
:=
mail
.
To
cc
:=
mail
.
Cc
bcc
:=
mail
.
Bcc
attachment
:=
mail
.
Attachment
// sending mail via Mailgun
mg
:=
mailgun
.
NewMailgun
(
config
.
Mailgun
.
Domain
,
config
.
Mailgun
.
Apikey
)
message
:=
mg
.
NewMessage
(
sender
,
subject
,
body
,
recipient
)
/**
* Add CC
if cc recipiants are
available
* Add CC
, BCC & ATTACHMENTS if
available
*/
if
len
(
cc
)
>
0
{
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
)
defer
cancel
()
MailgunResp
,
id
,
err
:=
mg
.
Send
(
ctx
,
message
)
...
...
@@ -329,17 +387,19 @@ func worker(i int) {
log
.
Fatal
(
err
)
//alertAdmin(" MAilgun Error \n" + err.Error())
}
if
len
(
filename
)
>
0
{
os
.
Remove
(
filename
)
}
//fmt.Println(resp)
if
config
.
AppMod
.
Production
==
"0"
{
fmt
.
Printf
(
"Email sent ID: %s Resp: %s
\n
"
,
id
,
MailgunResp
)
}
//sendMessage(mg, sender, subject, body, recipient, cc)
mailSentTimeMailgun
:=
time
.
Now
()
.
String
()
/**
* 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
)
if
mailBodyerr
!=
nil
{
alert
:=
" Error requesting newmail to add in SENTITEMS DB
\n
"
+
mailBodyerr
.
Error
()
...
...
@@ -355,7 +415,7 @@ func worker(i int) {
ioutil
.
ReadAll
(
resp
.
Body
)
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) {
/**
* 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
var
config
Config
...
...
@@ -442,6 +502,9 @@ func logmail(subject, sender, recipient, readTimeOutbox, mailSentTimeMailgun, id
logBody
:=
strings
.
NewReader
(
`{"Mail Subject":"`
+
subject
+
`","Mail sender":"`
+
sender
+
`","Mail recipiants":"`
+
recipient
+
`","Mail cc":"`
+
cc
+
`","Mail bcc":"`
+
bcc
+
`","Mail attachment":"`
+
attachment
+
`","OUTBOX read time":"`
+
readTimeOutbox
+
`","Mail sent to mailgun":"`
+
mailSentTimeMailgun
+
`","Mailgun ID":"`
+
id
+
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment