0
votes

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.

2

2 Answers

1
votes

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: [email protected] 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)
1
votes

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 = "[email protected]"
# 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)