Search code examples
ruby-on-railsrubygoogle-apigmailservice-accounts

How to implement server to server communication using google api in ruby?


I have a rails application in which I wanted to send email using Gmail API(using google-api-client for ruby). I have created one application in google developers and I have generated a service account key. I am using google specification for storing that credential JSON file(storing in /home/user/.config/gcloud/applicaton_default_credentials.json).

For starters, I wanted to fetch user labels below is my code

require 'google/apis/gmail_v1'
gmail_v1 = Google::Apis::GmailV1
service = gmail_v1::GmailService.new
service.authorization = Google::Auth.get_application_default([gmail_v1::AUTH_SCOPE, gmail_v1::AUTH_GMAIL_COMPOSE, gmail_v1::AUTH_GMAIL_MODIFY, gmail_v1::AUTH_GMAIL_READONLY])
user_id = 'me'
result = service.list_user_labels(user_id)

But this is giving me Google::Apis::ClientError: failedPrecondition: Bad Request error.

My end goal is to send email using an email for which I have generated the credentials JSON file, as I don't want to put my username and password in the smtp config of the ActionMailer.


Solution

  • After many hours of debugging, I finally found a working solution. DalmTo is right about the concept that a service account can't access Gmail as Gmail requires a User account, but we can leverage the power of impersonation in this case. The steps to do impersonation are:

    1. Go to your service account.
    2. Give permission to the user you want to impersonate.
    3. We need to change our code for this setup like below

      service = gmail_v1::GmailService.new
      service.authorization = Google::Auth.get_application_default([gmail_v1::AUTH_SCOPE,    gmail_v1::AUTH_GMAIL_COMPOSE, gmail_v1::AUTH_GMAIL_MODIFY, gmail_v1::AUTH_GMAIL_READONLY])
      auth_client = service.authorization.dup
      auth_client.sub = 'user@domain'
      user_id = 'me'
      result = auth_client.list_user_labels(user_id)
      

    Note: For this, to work, we need to go to our G-suit account and give proper permission to our service account.