admin管理员组

文章数量:1125041

Today I come to you with a little problem. I used to program this in Python and everything was working well.

Then I switched to Ruby on Rails (for consistency), wrote a service that could execute the now ruby code and then poof, does not work as expected.

The service should insert an email in the inbox of the user with the subject, from, to, and content of the mail.

But every time, no matter what I try, I receive an empty message with (no sender) (no subject)

Here's the extracted code with dummy values

require 'google/apis/gmail_v1'
require 'googleauth'
require 'base64'
require 'mail'

class GmailServiceAccount
  SCOPES = ['.insert']

  def initialize(service_account_file)
    @service_account_file = service_account_file
    @token_cache = {}
  end

  def get_service(user_email)
    return @token_cache[user_email] if @token_cache.key?(user_email)

    credentials = Google::Auth::ServiceAccountCredentials.make_creds(
      json_key_io: File.open(@service_account_file),
      scope: SCOPES
    ).dup
    credentials.sub = user_email

    service = Google::Apis::GmailV1::GmailService.new
    service.authorization = credentials
    @token_cache[user_email] = service
    service
  end

  def create_html_message(sender, to, subject, html_content, plain_text = nil)
    plain_text ||= "Please use an HTML capable email client to view this message."

    message = Mail.new do
      from    sender
      to      to
      subject subject
      text_part do
        body plain_text
      end
      html_part do
        content_type 'text/html; charset=UTF-8'
        body html_content
      end
    end

    # Debug: Print the message to ensure it's constructed correctly
    puts "Constructed Message:\n#{message}"

    # Ensure the message is properly encoded
    raw = Base64.urlsafe_encode64(message.to_s)
    { raw: raw }
  end

  def insert_html_email(user_email, sender, subject, html_template_path, template_variables = {})
    begin
      html_content = File.read(html_template_path, encoding: 'utf-8')

      template_variables.each do |key, value|
        html_content.gsub!("{{ #{key} }}", value.to_s)
      end

      service = get_service(user_email)
      message = create_html_message(sender, user_email, subject, html_content)

      # Debug: Print the raw message to ensure it's not empty
      puts "Encoded Raw Message:\n#{message[:raw]}"

      # Include labelIds in the message body
      message_body = {
        raw: message[:raw],
        labelIds: ['INBOX', 'UNREAD']
      }

      result = service.insert_user_message(user_email, message_body)

      { user: user_email, status: 'success', message_id: result.id }
    rescue => e
      { user: user_email, status: 'error', error: e.message }
    end
  end
end

# Command-line execution
if __FILE__ == $0
  service_account_file = 'path/to/your/service-account-key.json'
  user_email = '[email protected]'
  sender = '[email protected]'
  subject = 'Test Email'
  html_template_path = 'email_template.html'
  template_variables = { 'name' => 'John Doe' }

  gmail_service = GmailServiceAccount.new(service_account_file)
  result = gmail_service.insert_html_email(user_email, sender, subject, html_template_path, template_variables)

  puts result
end

I tried to run the code standalone in ruby, same problem.

I tried some chat-gpt-fu, same problem.

I tried explicitly setting the object as a GMail object, same thing.

本文标签: Why does not my gmail insert script in ruby works properlyStack Overflow