I am trying to send emails from my golang application using my Mailjet credentials, but I am trying to do it the normal golang way (yes, I know that their library is highly encouraged).
I have the emails working fine using the Mailjet library, but my boss made a really good point that we might not stay with Mailjet forever. If we switch to a different email solution, we don't want to have to rewrite all of our email code, we just want to change our hostname and credentials.
My printer sends emails just find through Mailjet using the same hostname and credentials, but for some reason my golang app won't!
My code was adopted from the golang smtp library SendEmail example.
Here it is (without my credentials, of course):
import (
"bytes"
"fmt"
"net/smtp"
)
func SendTestEmail() (bool, error) {
fmt.Println("Send Test Email: Enter")
success := false
hostname := "in-v3.mailjet.com"
auth := smtp.PlainAuth("", username, password, hostname)
to := []string{"me#example.com"}
msg := []byte("To: me#example.com\r\n" +
"Subject: discount Gophers!\r\n" +
"\r\n" +
"This is the email body.\r\n")
fmt.Println("Send Test Email: Sending Email")
err := smtp.SendMail(hostname+":587", auth, "sender#example.com", to, msg)
if err == nil {
fmt.Println("Send Test Email: Email successfully sent!")
success = true
} else {
fmt.Println("Send Test Email: Email failed to send", err)
}
fmt.Println("Send Test Email: Exit")
return success, err
}
Note that I am using port 587. I do not know if my printer is using 587 or 25, but it's working. I don't work when using port 25 either.
What is really weird is that smtp.SendEmail isn't returning any errors, but I still do not get any emails (yes, I am checking my junk folder)!
Also, when I log into Mailjet, I don't see that any emails were sent. I do see that an email was sent when I send something from the printer.
So, where is my email?!
Any help is greatly appreciated. Thanks!
First of all, thanks for choosing Mailjet as your email service provider! I'm leading the API Product and Developers Relations at Mailjet.
When it comes to send, you're right with SMTP. It's standard, widely supported and easy to switch (even if I don't hope we'll get there!). Our Go library will become handy when it comes to deal with our API to manage business processes.
I have several questions / feedback looking at your code:
I guess the "sender#example.com" from address used is not the one you use in your real code? Anyway, this email must have been validated on Mailjet side beforehands. See our dedicated guide
Seems you try to set some SMTP headers like Subject within the message, when it should be handled separately
Here's a working code I'm using to work with SMTP:
package main
import (
"log"
"net/smtp"
"fmt"
)
func main() {
auth := smtp.PlainAuth(
"",
"MAILJET_API_KEY",
"MAILJET_API_SECRET",
"in-v3.mailjet.com",
)
email := "foobar#test.com"
header := make(map[string]string)
header["From"] = email
header["To"] = email
header["Subject"] = "Hello Mailjet World!"
header["X-Mailjet-Campaign"] = "test"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\nHi! Thanks for using Mailjet."
err := smtp.SendMail(
"in-v3.mailjet.com:587",
auth,
email,
[]string{email},
[]byte(message),
)
if err != nil {
log.Printf("Error: %s", err)
} else {
log.Printf("Mail sent!")
}
}
Hope it helps! hAPI sending with Mailjet
Related
I use firebase email trigger and trying to send an email to my gmail account and another account which is not gmail. I received email only on my another account, gmail doesn't work.
Here is my code.
db.collection('mail').add({
to: 'user#gmail.com',
cc: 'user#example.com',
message: {
subject: 'Welcome',
html: 'Hello',
},
})
Here is my mail collection response
Response looks fine.
I received email only on user#example.com account.
I'd be very grateful if some could help me.
Thanks in advance.
The Trigger Email extension for Firebase makes no distinction in how it handles gmail destinations vs other email addresses, so it is very unlikely that this difference happens in the sending of the email.
More likely the email is getting caught in either the spam filter of gmail, or in another spam filter along the way to gmail. I recommend checking your gmail spam box first.
I have changed from email and it works now.
Thanks
Be sure to check in the firebase/firestore itself,
the errors will show in the document itself:
[![error code in firestore][1]][1]
as mentioned, do check your trigger-email settings, that they are linked to the correct collection:
[![collection linked to trigger-email][2]][2]
// Firestore data converter
export const contactFormConvertor = {
toFirestore: (contactform: ContactformDTO) => {
return {
to: <INSERT email you wish to receive the mail on>,
name: contactform._name,
from: <INSERT email you use to send the mail from>,
replyTo: contactform._email,
message: {text: contactform._message + '\n\nkind regards, ' + contactform._name,
subject: contactform._subject}
};
},
fromFirestore: (snapshot: { data: (arg0: any) => any; }, options: any) => {
const data = snapshot.data(options);
return new ContactformDTO(data.name, data.email, data.subject, data.message);
}
};```
[1]: https://i.stack.imgur.com/08cIQ.png
[2]: https://i.stack.imgur.com/m4Sod.png
I am trying to parse my emails in Go and I need help.
How to get access to Content-type field of mail?
cmd, _ = c.Fetch(set, "BODY[HEADER]", "BODY[1]")
for cmd.InProgress() {
for _, rsp = range cmd.Data {
header := imap.AsBytes(rsp.MessageInfo().Attrs["BODY[HEADER]"])
body := imap.AsString(rsp.MessageInfo().Attrs["BODY[1]"])
if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
with this I can gain access to Body and Header, but when email contain included file then with BODY[1] I have all meta-data, not only pure text. To avoid that I can use BODY[1.1], but I need condition by Content-Type:[multipart/alternative] and I can't gain access ot that field.
Ok, so i figured it out by my self. But anyway, maybe someone else interested in that. You can have access to varios fields of mail by
msg.Header.Get("Content-type")
and instead of Content-type you can put any header part name.
fmt.println(msg)
to know what name fields it have
I am sending e-mails over smtp in golang, which works perfectly fine. To set the sender of an e-mail I use the Client.Mail funtion:
func (c *Client) Mail(from string) error
When the recipient gets the e-mail he sees the sender as plaintext e-mail address: sender#example.com
I want the sender to be displayed like: Sandy Sender <sender#example.com>.
Is this possible? I tried setting the sender to Sandy Sender <sender#example.com> or only Sandy Sender but none of them work. I get the error 501 5.1.7 Invalid address
You need to set the From field of your mail to Sandy Sender <sender#example.com>:
...
From: Sandy Sender <sender#example.com>
To: recipient#example.com
Subject: Hello!
This is the body of the message.
And use the address only (sender#example.com) in Client.Mail.
Alternatively, you can use my package Gomail:
package main
import (
"gopkg.in/gomail.v2"
)
func main() {
m := gomail.NewMessage()
m.SetAddressHeader("From", "sender#example.com", "Sandy Sender")
m.SetAddressHeader("To", "recipient#example.com")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/plain", "This is the body of the message.")
d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
You can add "From: EmailName<" + EmailAdderss + "> \r\n" to mail header to show whatever EmailName you want, and add Email Address to void duplicate mail.
You can check if a project like jpoehls/gophermail works better.
It has a test case like this one:
m.SetFrom("Domain Sender <sender#domain.com>")
It internally (main.go) calls in SetMailAddress() the method mail.ParseAddress() which is supposed to follow RFC 5322.
I think you can use mail.Address and use Address.String function formats the address
func (a *Address) String() string
String formats the address as a valid RFC 5322 address. If the address's name contains non-ASCII characters the name will be rendered according to RFC 2047.
and I write example:
go_smtp.go
I am new bie for send grid. I have checked this url for two emails "https://sendgrid.com/api/mail.send.js..." and got the mail successfully in both emails.
The mail received by the users from the above URL have both email address in "TO" field like
For ex. User Test To: test#example.com;test2#example.com. and For User test2 To: test#example.com;test2#example.com.
As per my requirement i want to send mail for multiple user and the each recipents have only his email address not the others.
For ex. User Test To: test#example.com and For User test2 To: test2#example.com.
Can this scenario is possible with send grid.
Thanks
You can send the same email to multiple recipients by using the SendGrid SMTP API's to parameter.
To do this you'll set an X-SMTPAPI: header in your message, this header will include the JSON to communicate with SendGrid's SMTP API. The header will look as such:
X-SMTPAPI: { "to": [ "test#example.com", "test2#example.com" ] }
Each recipient will receive a unique email, addressed only to them.
Be aware: you'll still need to set a To: header for the message to send, however you can set this to yourself or one of the recipients (and then exclude them from the JSON list).
Send grid being a standard SMTP server will respond as if you are sending email from gmail, yahoo or outlook.
The scenario is not possible that I am aware of. I have only incorporated it into 2 applications, so I am certain there are better experts.
As an alternative you could test using the blind copy, The problem with that is would need a main address in the To field, which may not fill your requirement.
Send email on Azure Mobile Service /NodeJS
var sendgrid = new SendGrid('KEY');
sendgrid.send({
to: toEMail, // ["email1#mail.com", "email2#mail.com",...]
from: fromEMail,
subject: subject,
text: body
}, function (success, message) {
console.log("send mail: " + subject);
// If the email failed to send, log it as an error so we can investigate
if (!success) {
console.error(message);
}
});
possible on Sendgrid. You can use the normal bcc on sendgrid via personalization, but we dont like it because the To: is always required. So my solution is sendgrid transactional email. This will send 1 email to multiple users (using sendgrid / php / laravel ):
$email = new \SendGrid\Mail\Mail();
$email->setFrom("sender#mail.com", "Sender Name");
$email->setSubject("Your subject");
$email->addTo(
"email.1#mail.com",
"User One",
[],
0
);
$email->addTo(
"email.2#mail.com",
"User Two",
[],
1
);
$email->addTo(
"email.3#mail.com",
"User Three",
[],
2
);
$email->addContent("text/plain", "your body");
$email->addContent("text/html", "<strong>your body</body>");
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
try {
$response = $sendgrid->send($email);
return response()->json($response, 200);
} catch (Exception $e) {
return response()->json($e->getMessage(), 400);
}
I have found this library and have managed to send an attachment in an empty email but not to combine text and attachments.
https://github.com/sloonz/go-mime-message
How can it be done?
I ended up implementing it myself: https://github.com/scorredoira/email
Usage is very simple:
m := email.NewMessage("Hi", "this is the body")
m.From = "from#example.com"
m.To = []string{"to#example.com"}
err := m.Attach("picture.png")
if err != nil {
log.Println(err)
}
err = email.Send("smtp.gmail.com:587", smtp.PlainAuth("", "user", "password", "smtp.gmail.com"), m)
I created gomail for this purpose. It supports attachments as well as multipart emails and encoding of non-ASCII characters. It is well documented and tested.
Here is an example:
package main
func main() {
m := gomail.NewMessage()
m.SetHeader("From", "alex#example.com")
m.SetHeader("To", "bob#example.com", "cora#example.com")
m.SetAddressHeader("Cc", "dan#example.com", "Dan")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/html", "Hello <b>Bob</b> and <i>Cora</i>!")
m.Attach("/home/Alex/lolcat.jpg")
d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")
// Send the email to Bob, Cora and Dan.
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
I prefer to use https://github.com/jordan-wright/email for email purposes.
It supports attachments.
Email for humans
The email package is designed to be simple to use, but flexible enough
so as not to be restrictive. The goal is to provide an email interface
for humans.
The email package currently supports the following:
From, To, Bcc, and Cc fields
Email addresses in both "test#example.com" and "First Last " format
Text and HTML Message Body
Attachments
Read Receipts
Custom headers
More to come!
Attachements in the SMTP protocol are sent using a Multipart MIME message.
So I suggest you simply
create a MultipartMessage
set your text in the fist part as a TextMessage (with "Content-Type", "text/plain")
add your attachements as parts using AddPart.