module GmailClient

This module provides the common functionality that will be needed for local and cloud module. @client_type defines if the gem is being used for local-lockbox or cloud-version.

Constants

APPLICATION_NAME
OOB_URI

Attributes

auth_client[RW]
downloaded[RW]
message_ids[RW]
total_emails[RW]

Public Instance Methods

all_message_ids(label) click to toggle source
# File lib/gmail_client.rb, line 191
def all_message_ids label
  mids = []
  messages = all_messages label
  messages.each { |m| mids << m.id }
  mids
end
all_messages(label) click to toggle source
# File lib/gmail_client.rb, line 173
def all_messages label
  messages = []
  next_page = nil

  begin
    result = @service.list_user_messages('me', max_results: 1000, page_token: next_page, label_ids: [label])
    messages += result.messages
    # break if messages.size >= 1
    next_page = result.next_page_token
  end while next_page

  messages
end
authorization_url() click to toggle source
# File lib/gmail_client.rb, line 93
def authorization_url
  @authorizer.get_authorization_url(base_url: OOB_URI)
end
authorize(code, user_id) click to toggle source
# File lib/gmail_client.rb, line 58
def authorize code, user_id
  credentials = @authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: OOB_URI
  )
  unless credentials.nil?
    init_apis credentials
  end
  credentials
end
encrypt(data) click to toggle source
# File lib/gmail_client.rb, line 247
def encrypt(data)
  Base64.encode64(data)
end
errors() click to toggle source
# File lib/gmail_client.rb, line 40
def errors
  @errors
end
fetch_emails(&process_email_block) click to toggle source

retrieve_emails

retrieve any mail from a folder, followin specified serach condition for any mail retrieved call a specified block

# File lib/gmail_client.rb, line 103
def fetch_emails(&process_email_block)

  @message_ids.each_with_index do |message_id, i|
    begin
      # fetch all the email contents
      # data = imap.uid_fetch(message_id, "RFC822")
      if @auth_client && @auth_client.expired?
        @auth_client.grant_type = "refresh_token"
        @auth_client.refresh!
        @service.authorization = Signet::OAuth2::Client.new(JSON.parse(@auth_client.to_json))
      end

      result = @service.get_user_message('me', message_id)

      process_email_block.call result, i, i == @message_ids.length-1, message_id

    rescue => e
      unless logger.nil?
        logger.info "Issue processing email for uuid ##{message_id}, #{e.message}"
      end

      logToLoggly({event:"EMAIL_SYNC_FAILED", env: @env, storage: @client_type, email: @current_user_email, uuid: message_id, error: e.message})
      raise e
    end
  end

end
get_user_info(user_id) click to toggle source
# File lib/gmail_client.rb, line 187
def get_user_info user_id
  @service.get_user_profile user_id
end
init(client_path, user_cred_path, user_id) click to toggle source
# File lib/gmail_client.rb, line 44
def init client_path, user_cred_path, user_id

  client_id = Google::Auth::ClientId.from_file(client_path)
  token_store = Google::Auth::Stores::FileTokenStore.new(file: user_cred_path)
  @authorizer = Google::Auth::UserAuthorizer.new(client_id, Google::Apis::GmailV1::AUTH_GMAIL_READONLY, token_store)

  credentials = @authorizer.get_credentials(user_id)

  unless credentials.nil?
    init_apis credentials
  end
  credentials
end
init_apis(cred) click to toggle source
# File lib/gmail_client.rb, line 68
def init_apis cred
  @service = Google::Apis::GmailV1::GmailService.new
  @service.client_options.application_name = APPLICATION_NAME
  @service.authorization = cred
end
init_apis_cloud(client_path, scope, token, type = "code") click to toggle source
# File lib/gmail_client.rb, line 74
def init_apis_cloud client_path, scope, token, type = "code"
  client_secrets = Google::APIClient::ClientSecrets.load client_path
  @auth_client = client_secrets.to_authorization
  @auth_client.update!(:scope => scope,
                      :redirect_uri => "postmessage")
  if(type == "code")
    @auth_client.code = token
  else
    @auth_client.grant_type = "refresh_token"
    @auth_client.refresh_token = token
  end

  @auth_client.refresh!
  # @auth_client.client_secret = nil
  @service = Google::Apis::GmailV1::GmailService.new
  @service.client_options.application_name = APPLICATION_NAME
  @service.authorization = Signet::OAuth2::Client.new(JSON.parse(@auth_client.to_json))
end
init_messages(label) click to toggle source
# File lib/gmail_client.rb, line 198
def init_messages label
  @message_ids = all_message_ids label
  @total_emails = @message_ids.length
  downloaded_email = getMessageUUIds("#{@download_path}meta/")

  downloaded_email = @message_ids & downloaded_email

  @downloaded = downloaded_email.length

  @downloaded = [@downloaded, @total_emails].min

  @message_ids = @message_ids - downloaded_email

  if @debug
    if @message_ids.empty?
      @logger.info "No new emails found..."
    elsif downloaded_email.any?
      @logger.info "Found emails saved in your #{@client_type}. Downloading only #{@message_ids.count} new emails..."
    else
      @logger.info "Downloading #{@message_ids.count} emails."
    end
  end

end
logToLoggly(messageBody) click to toggle source
# File lib/gmail_client.rb, line 223
def logToLoggly(messageBody)

  if(@logglyTag)
    begin
      HTTParty.post("http://logs-01.loggly.com/bulk/0d67f93b-6568-4b00-9eca-97d0ea0bd5a1/tag/#{@logglyTag}/",
                    body: messageBody.to_json,
                    headers: { 'Content-Type' => 'application/json' } )
    rescue
      true
    end

  else
    if @debug && !@logger.nil?
      @logger.info "Logging to Loggly disabled"
      @logger.info messageBody
    end
  end

end
logger() click to toggle source
# File lib/gmail_client.rb, line 36
def logger
  @logger
end
process_email(mail, uid, stamp = nil) click to toggle source

Process each email downloaded from imap-server and creates meta file that will be sent over to the navi-ai service. Meta will content information like: ['from', 'to', 'cc', …, 'body_url']. This information is then used by navi-ai to parse the body content.

# File lib/gmail_client.rb, line 136
def process_email(mail, uid, stamp = nil)
  meta = Hash.new
  custom_uid = (Time.now.to_f * 1000).to_s + "_" + uid

  payload = mail.payload

  headers = payload.headers
  date = headers.any? { |h| h.name == 'Date' } ? headers.find { |h| h.name == 'Date' }.value : ''
  from = headers.any? { |h| h.name == 'From' } ? headers.find { |h| h.name == 'From' }.value : ''
  to = headers.any? { |h| h.name == 'To' } ? headers.find { |h| h.name == 'To' }.value : ''
  subject = headers.any? { |h| h.name == 'Subject' } ? headers.find { |h| h.name == 'Subject' }.value : ''
  cc = headers.any? { |h| h.name == 'Cc' } ? headers.find { |h| h.name == 'Cc' }.value : ''

  meta["from"] = from
  meta["to"] = to
  meta["cc"] = cc
  meta["subject"] = subject
  meta["date"] = date

  if payload.parts&.any?
    payload.parts.map { |part|
      m = download({"decoded" => part.body.data.nil? ? "" : part.body.data, "mime_type" => part.mime_type.nil? ? "text/html" : part.mime_type}, custom_uid)
      meta.merge!(m) unless m.nil?
    }
  else
    m = download({"decoded" => payload.body.data.nil? ? "" : payload.body.data, "mime_type" => "text/html"}, custom_uid)
    meta.merge!(m) unless m.nil?
  end

  if stamp.nil?
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}")
  else
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}", stamp)
  end

end
setupLoggly(tag) click to toggle source
# File lib/gmail_client.rb, line 243
def setupLoggly(tag)
  @logglyTag = tag
end