1

Using the Gmail Service to send an email, but I'm having problem with the email format which needs to be passed to Google::Apis::GmailV1::Message, I'm passing raw parameter to it in the following format

email_raw = "From: <#{@google_account}>
To: <#{send_to}>
Subject: This is the email subject

The email body text goes here"

# raw is: The entire email message in an RFC 2822 formatted and base64url encoded string.

message_to_send = Google::Apis::GmailV1::Message.new(raw: Base64.encode64(email_raw))
response = @service.send_user_message("me", message_to_send)

This fails even when I pass email_raw without base64 encoding. I'm providing valid emails but it fails with an error

Google::Apis::ClientError (invalidArgument: Recipient address required)

I've checked Sending an email with ruby gmail api v0.9 and I also found this but it uses Mail class which I could not locate in the Gmail API Ruby client library. Currently, email_raw contains \n characters but I've tested it without it and it doesn't work.
Moreover, I also want to send attachments in a message.

Masroor
  • 1,484
  • 3
  • 14
  • 23

2 Answers2

2

We can easily offload the effort of forming a standardized and formatted email to this gem. Just include the gem in your project and do this

mail = Mail.new
mail.subject = "This is the subject"
mail.to = "someperson@gmail.com"
# to add your html and plain text content, do this
mail.part content_type: 'multipart/alternative' do |part|
  part.html_part = Mail::Part.new(body: email_body, content_type: 'text/html')
  part.text_part = Mail::Part.new(body: email_body)
end
# to add an attachment, do this
mail.add_file(params["file"].tempfile.path)

# when you do mail.to_s it forms a raw email text string which you can supply to the raw argument of Message object
message_to_send = Google::Apis::GmailV1::Message.new(raw: mail.to_s)
# @service is an instance of Google::Apis::GmailV1::GmailService
response = @service.send_user_message("me", message_to_send)
Masroor
  • 1,484
  • 3
  • 14
  • 23
  • 1
    You could also try using Aurinko's unified API when working with Gmail API https://apirefs.aurinko.io/#operation/send – Alexey Oct 14 '20 at 17:48
1

Mind that Gmail requires base64url encoding, not base64 encoding

See documentation:

raw string (bytes format)

The entire email message in an RFC 2822 formatted and base64url encoded string. Returned in messages.get and drafts.get responses when the format=RAW parameter is supplied.

A base64-encoded string.

I recommend you to test first with the Try this API - you can encode the message with online base64url encoders.

Then, when using Ruby, you can use the method:

Base64.urlsafe_encode64(message).

UPDATE

The problem seems to be your raw message body.

The message body should have the followind structure:

To: masroorh7@gmail.com Content-Type: multipart/alternative; boundary="000000000000f1f8eb05b18e8970"  --000000000000f1f8eb05b18e8970 Content-Type: text/plain; charset="UTF-8"  This is a test email  --000000000000f1f8eb05b18e8970 Content-Type: text/html; charset="UTF-8"  <div dir="ltr">This is a test email</div>  --000000000000f1f8eb05b18e8970--

base64url encoded, this will look like:

encodedMessage = "VG86IG1hc3Jvb3JoN0BnbWFpbC5jb20NCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2FsdGVybmF0aXZlOyBib3VuZGFyeT0iMDAwMDAwMDAwMDAwZjFmOGViMDViMThlODk3MCINCg0KLS0wMDAwMDAwMDAwMDBmMWY4ZWIwNWIxOGU4OTcwDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9IlVURi04Ig0KDQpUaGlzIGlzIGEgdGVzdCBlbWFpbA0KDQotLTAwMDAwMDAwMDAwMGYxZjhlYjA1YjE4ZTg5NzANCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PSJVVEYtOCINCg0KPGRpdiBkaXI9Imx0ciI-VGhpcyBpcyBhIHRlc3QgZW1haWw8L2Rpdj4NCg0KLS0wMDAwMDAwMDAwMDBmMWY4ZWIwNWIxOGU4OTcwLS0"

Thus, your message body should be:

Google::Apis::GmailV1::Message.new(raw:encodedMessage)
ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • tried it, and still I get the same error: 400 "Recipient address required". The issue lies in the email_raw data – Masroor Oct 13 '20 at 13:44
  • I see, in this case I recommend you to open any email in the Gmail UI, click on the "three dots", `Show original`, and use the `From`, `To` and everything below `Content-Type:` as a template for your message - to make sure that the formating is correct. – ziganotschka Oct 13 '20 at 14:38
  • please have a look my attempt with the email's original message format here https://0bin.net/paste/SOT94vCA#o-HVmtBvLG8w7MB9dY1cFL/NMtaFtugUmk2gkw+8Zof it keeps giving the same error – Masroor Oct 13 '20 at 15:02
  • 1
    Is `masrooratwork@gmail.com` your primary email? Try: `From: `, and do NOT remove the boundaries and the `--`. Removing `Date` and `Message-ID` is correct. – ziganotschka Oct 13 '20 at 15:09
  • yes masrooratwork@gmail.com is the email I've authorized with, and I'm trying to send emails from this account. Sadly, the error is persisting after all these changes(included boundaries and --) – Masroor Oct 13 '20 at 15:19
  • Do yo experience the same error when trying to send an email with the Try This API? – ziganotschka Oct 13 '20 at 21:14
  • not the same error though but the raw input still has problems, see this https://0bin.net/paste/dUbzs-AD#9f7ZVlt48zHmWBKg2-tkn8Lm4A/0e4RiRFAfRZ/2PbK – Masroor Oct 14 '20 at 06:39
  • It has worked when I tried sending the message without encoding. – Masroor Oct 14 '20 at 06:49
  • Please try to send from the Try this API a message with userId `me` and the Base64Url encoded content `To: masroorh7@gmail.com Content-Type: multipart/alternative; boundary="000000000000f1f8eb05b18e8970" --000000000000f1f8eb05b18e8970 Content-Type: text/plain; charset="UTF-8" This is a test email --000000000000f1f8eb05b18e8970 Content-Type: text/html; charset="UTF-8"
    This is a test email
    --000000000000f1f8eb05b18e8970--`
    – ziganotschka Oct 14 '20 at 07:30
  • I tried your encodedMessage as input to raw and it worked in the Try this API. But the problem is I do not have any boundary or -- strings so what do I do about them? I only have To, From, Subject and Email body. There should be a way to make it work without providing any boundary and -- strings. – Masroor Oct 14 '20 at 12:15
  • The boundaries are an obligatory part of the message body. They delimit the header. the plain text and the html parts of the message body. – ziganotschka Oct 14 '20 at 12:26
  • okay fair enough, but how do I generate them? I have no way of making up these things on my own, nor there is any documentation about it. The API just demands RFC 2822 formatted raw text. Btw, thanks for all your effort, I really appreciate it. – Masroor Oct 14 '20 at 12:33
  • Have a read a bout MIME messages: https://en.wikipedia.org/wiki/MIME – ziganotschka Oct 14 '20 at 12:34
  • 1
    Yes with every step you got me closer to the answer. I found something to take care of the RFC format. I'll update my answer. – Masroor Oct 14 '20 at 13:23