【问题标题】:Unable to resolve Bad Request 400 sending email with Gmail Api and Service Account无法解决使用 Gmail Api 和服务帐户发送电子邮件的错误请求 400
【发布时间】:2019-06-27 07:02:27
【问题描述】:

在此论坛中对错误请求 400 进行了多次回复后,通过服务帐户和 Gmail API 和 Oauth 发送电子邮件时,我已经没有解决该问题的选项了。我尝试过的每个解决方案似乎都没有改变错误,所以我猜我错过了更高的东西。

步骤:

  • 遵循 Gmail api 指南获取代码

  • 设置 GCP 和 Google 管理员(按照此操作启动 medium.com/lyfepedia/sending-emails-with-gmail-api-and-python-49474e32c81f)

  • 具体来说....在 Google Cloud Console 中为项目设置服务帐号,

  • 被授权在域范围内访问,

  • 已将 JSON 凭据文件添加到项目中。

  • 在管理控制台中具有服务帐户 ID 的授权 API 客户端,提供当前可能的所有范围组合“电子邮件(读取/写入/发送)https://mail.google.com/,https://www.googleapis.com/auth/gmail.send

GCP API 仪表板显示正在发出请求,但出现 100% 错误。

应用中返回的错误:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad 
Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Bad Request",
    "reason" : "failedPrecondition"
  } ],
  "message" : "Bad Request"
}

还有我的代码

import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Message;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class mod_gmail_send_2 extends AsyncTask<Void, Void, String> {

    private Gmail mGmailService = null;
    private GoogleCredential mCredential;
    private Context mContext;

    private String userID = "me";
    private String emailFrom = "xxxx@gmail.com"; //non specific  account?!?
    private String emailTo = "xxxxx@gmail.com";
    private String emailSubject = "This is the subject";
    private String emailBody = "This is the body text";
    private List<String> scopes = Arrays.asList(GmailScopes.GMAIL_SEND);

    public mod_gmail_send_2(Context myContext) {
        mContext = myContext;
    }

    @Override
    protected String doInBackground(Void... params) {

        try {
            mCredential = GoogleCredential
                    .fromStream(mContext.getResources().openRawResource(R.raw.myjsoncredentials))
                    .createScoped(scopes);
            HttpTransport transport = AndroidHttp.newCompatibleTransport();
            JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
            mGmailService = new Gmail.Builder(transport, jsonFactory, mCredential).build();
            MimeMessage mMimeMessage = createEmail(emailTo, emailFrom, emailSubject, emailBody);
            sendMessage(mGmailService, userID, mMimeMessage);

        }catch(Throwable e){
            return e.getLocalizedMessage();
        }
        return "Success";
    }

    public static Message sendMessage(Gmail service,String userId,MimeMessage emailContent) throws MessagingException, IOException {
        Message message = createMessageWithEmail(emailContent);
        message = service.users().messages().send(userId, message).execute();
        System.out.println("Message id: " + message.getId());
        System.out.println(message.toPrettyString());
        return message;
    }

    public static MimeMessage createEmail(String to,String from,String subject,String bodyText) throws MessagingException {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        MimeMessage email = new MimeMessage(session);
        email.setFrom(new InternetAddress(from));
        email.addRecipient(javax.mail.Message.RecipientType.TO,new InternetAddress(to));
        email.setSubject(subject);
        email.setText(bodyText);
        return email;
    }

    public static Message createMessageWithEmail(MimeMessage emailContent) throws MessagingException, IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        emailContent.writeTo(buffer);
        byte[] bytes = buffer.toByteArray();
        String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
        Message message = new Message();
        message.setRaw(encodedEmail);
        return message;
    }

    @Override
    protected void onPostExecute(String output) {
        Toast.makeText(mContext, output, Toast.LENGTH_LONG).show();
    }
}

任何想法将不胜感激!

【问题讨论】:

    标签: java android gmail-api service-accounts bad-request


    【解决方案1】:

    您似乎无法从服务帐户发送电子邮件(我愿意更正,或者我应该说希望更正)。您必须模拟在您的 gsuite 域中注册的帐户,并在使用 .createDelegate() 创建您的 Google 凭据时包含该帐户。

     GoogleCredential
        .fromStream(service_account_json_credentials)
        .createDelegate(your_impersonated_account@your_domain)
        .createScoped(scopes)
    

    https://stackoverflow.com/a/54108538/9175763

    虽然您可以将云端硬盘文件夹/文件共享到您的服务帐户以使用云端硬盘 API 进行访问,但您不能将私人 Gmail 委托给您的服务帐户。 “错误:您指定的 Google 帐户地址无效。”

    但是,您可以使用 g-suite 电子邮件别名作为现有 g-suite 电子邮件的代理。只需在管理控制台中为用户添加别名,然后照常打开您的 g-suite 电子邮件帐户,转到设置、帐户、发送邮件并添加您的别名。然后,您可以将委托设置为您的别名。

    【讨论】:

      猜你喜欢
      • 2020-09-30
      • 2013-04-25
      • 2020-10-25
      • 1970-01-01
      • 2016-01-18
      • 2012-03-30
      • 2021-12-16
      • 1970-01-01
      • 2016-04-20
      相关资源
      最近更新 更多