5

I am trying to send an email using gmail API. My Ruby code as you can see below works well without an attachment:

client = google_client user_id
token = Token.find_by_user_id(user_id)
access_token = token.access_token
gmail = Google::Apis::GmailV1::GmailService.new
gmail.authorization = client
message              = Mail.new
message.date         = Time.now
message.subject      = 'Supertram p'
message.body         = "<p>Hi Alex, how's life?</p>"
message.content_type = 'text/html'
message.from         = self.email
message.to           = '[email protected]'

msg = message.encoded
message_object = Google::Apis::GmailV1::Message.new(raw:message.to_s)
gmail.send_user_message('me', message_object)

I was able to successfully send emails in html format. My question is how to attach a file to this message?

client = google_client user_id
token = Token.find_by_user_id(user_id)
access_token = token.access_token
gmail = Google::Apis::GmailV1::GmailService.new
gmail.authorization = client
message              = Mail.new
message.date         = Time.now
message.subject      = 'Supertramp'
message.body         = "<p>Hi Alex, how's life?</p>"
# message.content_type = 'text/html'
message.from         = self.email
message.to           = '[email protected]'
message.add_file("/Users/myname/Downloads/image.png")

msg = message.encoded
message_object = Google::Apis::GmailV1::Message.new(raw:message.to_s)
gmail.send_user_message('me', message_object)

but here is the message that I receive:

-- Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Hi Alex, how's life?

-- Content-Type: image/png; filename=image.png Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=image.png Content-ID: <[email protected]> iVBORw0KGgoAAAANSUhEUgAAAfAAAABMCAYAAACS0+VcAAAX9UlEQVR4Ae2d XWxj1bXH/6lKK+D1VE1oKEa6CPNwpQh4SFBapYOrIoGUuRnN6IRR25HuC1C/ AC8JDMiFGTlP8 [...] == ----

I only receive an encoded string, but not an attached file. My question is how to send an email by Gmail API with an attachment?

4
  • You want to send a multipart e-mail, so don’t specify the content type as 'text/html' ... (Go research what you need to use instead.) Commented Jan 29, 2018 at 9:09
  • i have tried using 'multipart/alternative' but my html part is missing Commented Jan 29, 2018 at 9:12
  • Have you tried reading this developers.google.com/gmail/api/guides/uploads? Commented Jan 29, 2018 at 9:15
  • from where are you getting that Mail class? I couldn't locate it in the google-api-ruby-client library. Commented Oct 13, 2020 at 19:07

2 Answers 2

3

I think you are missing somethings with regard to the attacment

message              = Mail.new
message.date         = Time.now
message.subject      = 'Test Email'
message.body         = "<p>Hi Test, how's life?</p>"
message.content_type = 'text/html'
message.from         = "Test User <[email protected]>"
message.to           = '[email protected]'

service = client.discovered_api('gmail', 'v1')

result = client.execute(
  api_method: service.users.messages.to_h['gmail.users.messages.send'],
  body_object: {
    raw: Base64.urlsafe_encode64(message.to_s)
  },
  parameters:  {
    userId: '[email protected]'
  },
    headers:   { 'Content-Type' => 'application/json' }
)

response = JSON.parse(result.body)

For multi-part email with the attachment:

message         = Mail.new
message.date    = Time.now
message.subject = 'Supertramp'
message.from    = "testone <[email protected]>"
message.to      = '[email protected]'

message.part content_type: 'multipart/alternative' do |part|
  part.html_part = Mail::Part.new(body: "<p>Hi TEst, how's life?</p>", content_type: 'text/html; charset=UTF-8')
  part.text_part = Mail::Part.new(body: "Hi test, how's life?")
end

open('http://google.com/image.jpg') do |file| 
  message.attachments['image.jpg'] = file.read 
end
Sign up to request clarification or add additional context in comments.

3 Comments

for future visitors wondering about the Mail class; it comes from this gem github.com/mikel/mail
@Prime if this is a project you work on personally you need to post that as a disclamer.
no, I don't. Just a developer using it to get stuff done.
1

The original post is creating an instance of Google::Apis::GmailV1::Message with message, which is not encoded, instead of msg, which is encoded. The following solution works for me:

# Include the mail gem in your Gemfile https://github.com/mikel/mail

# Authentication
client = google_client user_id
token = Token.find_by_user_id(user_id)
access_token = token.access_token
gmail = Google::Apis::GmailV1::GmailService.new
gmail.authorization = client

# Create mail object
message              = Mail.new
message.date         = Time.now
message.subject      = 'test subject'
message.from         = self.email
message.to           = '[email protected]'

# Create the 3 necessary parts of the message
message.part content_type: 'multipart/alternative' do |part|
  part.html_part = Mail::Part.new(body: "<p>Hi Alex, how's life?</p>", content_type: 'text/html; charset=UTF-8')
  part.text_part = Mail::Part.new(body: "Hi Alex, how's life?")
end

message.attachments['file.pdf'] = File.open("/path/to/file.extension").read

# Encode the message
msg = message.encoded

# Important! Create an instance of Message with the encoded message
message_object = Google::Apis::GmailV1::Message.new(raw: msg.to_s)

gmail.send_user_message('me', message_object)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.