This repository has been archived by the owner on Feb 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathinbound_parse.go
executable file
·137 lines (118 loc) · 3.75 KB
/
inbound_parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package main
import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"log"
"net/http"
"net/mail"
"regexp"
"github.com/google/uuid"
)
func initInboundParseDB() {
var err error
inboundParseStmt, err = db.Prepare("INSERT INTO `mails` (`sender_wiiID`,`mail`, `recipient_id`, `mail_id`, `message_id`) VALUES (?, ?, ?, ?, ?)")
if err != nil {
LogError("Unable to prepare inbound parse statement", err)
panic(err)
}
}
var inboundParseStmt *sql.Stmt
var mailDomain *regexp.Regexp
func sendGridHandler(w http.ResponseWriter, r *http.Request) {
// We sincerely hope someone won't attempt to send more than a 11MB image.
// but, if they do, now they have 10mb for image and 1mb for text + etc
// (still probably too much)
err := r.ParseMultipartForm(-1)
if err != nil {
log.Printf("Unable to parse form: %v", err)
return
}
text := r.Form.Get("text")
if r.Form.Get("from") == "" || r.Form.Get("to") == "" {
// something was nil
log.Println("Something happened to SendGrid... is someone else accessing?")
return
}
// If there's no text in the email.
if text == "" {
text = "No message provided."
}
// Figure out who sent it.
fromAddress, err := mail.ParseAddress(r.Form.Get("from"))
if err != nil {
log.Printf("given from address is invalid: %v", err)
return
}
toAddress := r.Form.Get("to")
// Validate who's being mailed.
potentialMailInformation := mailDomain.FindStringSubmatch(toAddress)
if potentialMailInformation == nil || potentialMailInformation[2] != global.SendGridDomain {
log.Println("to address didn't match")
return
}
// 16 digit ID
recipientMlid := potentialMailInformation[1]
// We "create" a response for the Wii to use, based off attachments and multipart components.
type File struct {
Filename string `go:"filename"`
Charset string `go:"charset"`
Type string `go:"type"`
}
var attachedFile []byte
attachmentInfo := make(map[string]File)
err = json.Unmarshal([]byte(r.Form.Get("attachment-info")), &attachmentInfo)
if err == nil {
hasImage := false
hasAttachedText := false
for name, attachment := range attachmentInfo {
attachmentData, _, err := r.FormFile(name)
if err == http.ErrMissingFile {
// We don't care if there's nothing, it'll just stay nil.
} else if err != nil {
log.Printf("failed to read attachment from form: %v", err)
return
} else {
if strings.Contains(attachment.Type, "image") && hasImage == false {
attachedFile, err = ioutil.ReadAll(attachmentData)
if err != nil {
log.Printf("failed to read image attachment from form: %v", err)
return
}
hasImage = true
} else if strings.Contains(attachment.Type, "text") && hasAttachedText == false && text == "No message provided." {
attachedText, err := ioutil.ReadAll(attachmentData)
text = string(attachedText)
if err != nil {
log.Printf("failed to read text attachment from form: %v", err)
return
}
hasAttachedText = true
}
}
}
}
wiiMail, err := FormulateMail(fromAddress.Address, toAddress, r.Form.Get("subject"), text, attachedFile)
if err != nil {
log.Printf("error formulating mail: %v", err)
return
}
// On a normal Wii service, we'd return the cd/msg response.
// This goes to SendGrid, and we hope the database error is resolved
// later on - any non-success tells it to POST again.
_, err = inboundParseStmt.Exec(fromAddress.Address, wiiMail, recipientMlid, uuid.New().String(), uuid.New().String())
if err != nil {
log.Printf("Database error: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if global.Datadog {
err := dataDogClient.Incr("mail.received_mail_sendgrid", nil, 1)
if err != nil {
LogError("Unable to update received_mail_sendgrid.", err)
}
}
fmt.Fprint(w, "thanks sendgrid")
}