Search code examples
ruby-on-railsgoogle-apigmail-apigoogle-api-ruby-client

Rails: Send email using Gmail API with attachment return only encoded file not


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?


Solution

  • 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