使用Gmail API发送电子邮件时出错?

时间:2014-08-01 05:22:38

标签: java sendmail gmail-api

我正在尝试使用Gmail java API发送邮件。我得到了以下错误。

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
    "reason" : "insufficientPermissions"
  } ],
  "message" : "Insufficient Permission"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:111)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:38)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:314)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1060)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:412)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:345)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:463)
    at GMailLibrary.SendEmail.sendMessage(SendEmail.java:32)
    at GMailLibrary.GMailAuthentication.main(GMailAuthentication.java:85)
Java Result: 1

我使用身份验证代码完成了身份验证部分。以下是我发送电子邮件的代码。

public class SendEmail 
{
      public static void sendMessage(Gmail service, String userId, MimeMessage email)throws MessagingException, IOException 
      {
            Message message = createMessageWithEmail(email);
            message = service.users().messages().send(userId, message).execute();

            System.out.println("Message id: " + message.getId());
            System.out.println(message.toPrettyString());
      }

      public static Message createMessageWithEmail(MimeMessage email)throws MessagingException, IOException 
      {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            email.writeTo(bytes);
            String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray());
            Message message = new Message();
            message.setRaw(encodedEmail);

            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);
            //InternetAddress tAddress = new InternetAddress(to);
            //InternetAddress fAddress = new InternetAddress(from);

            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 MimeMessage createEmailWithAttachment(String to, String from, String subject,String bodyText, String fileDir, String filename) throws MessagingException, IOException 
      {
            Properties props = new Properties();
            Session session = Session.getDefaultInstance(props, null);

            MimeMessage email = new MimeMessage(session);
            InternetAddress tAddress = new InternetAddress(to);
            InternetAddress fAddress = new InternetAddress(from);

            email.setFrom(fAddress);
            email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
            email.setSubject(subject);

            MimeBodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(bodyText, "text/plain");
            mimeBodyPart.setHeader("Content-Type", "text/plain; charset=\"UTF-8\"");

            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBodyPart);

            mimeBodyPart = new MimeBodyPart();
            DataSource source = new FileDataSource(fileDir + filename);

            mimeBodyPart.setDataHandler(new DataHandler(source));
            mimeBodyPart.setFileName(filename);
            String contentType = Files.probeContentType(FileSystems.getDefault()
                .getPath(fileDir, filename));
            mimeBodyPart.setHeader("Content-Type", contentType + "; name=\"" + filename + "\"");
            mimeBodyPart.setHeader("Content-Transfer-Encoding", "base64");

            multipart.addBodyPart(mimeBodyPart);

            email.setContent(multipart);

            return email;
      }
}

我通过传递所需信息从主类调用SendMail方法。

MimeMessage email = SendEmail.createEmail(to, from, subject, bodytext); 
SendEmail.sendMessage(service, USER, email);

请帮帮我。我已经尽力了。如果需要更多信息,请与我们联系。

4 个答案:

答案 0 :(得分:5)

我在列出messagesd时遇到了同样的问题。我试图删除" StoredCredential"在〜/ .credentials / gmail-api-quickstar中,但这不会有帮助。 您需要的是设置" GmailScopes" MAIL_GOOGLE_COM,对应于完全权限访问。

 /** Global instance of the scopes required by this quickstart. */
private static final List<String> SCOPES =
        Arrays.asList(GmailScopes.MAIL_GOOGLE_COM);

答案 1 :(得分:4)

我的问题是我使用Google的样本处理列表标签,然后添加了编写范围,但是在我删除〜/ .credentials / gmail-api-quickstart中的身份验证之后它才起作用,然后再次运行所以它打开了一个浏览器并重新进行了身份验证,这次使用了撰写权限。

答案 2 :(得分:2)

根据您在问题中提供的信息,我们说您已经错误地设置了权限,因为您需要Create发送邮件的权限。您可以通过以下方式正确设置permissions

    CLIENT_SECRET_FILE = 'your client secret.json'
    OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.compose'
    STORAGE = Storage('gmail.storage')
    flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
    http = httplib2.Http()
    credentials = STORAGE.get()
    if credentials is None or credentials.invalid:
        credentials = run(flow, STORAGE, http=http)
    http = credentials.authorize(http)
    gmail_service = build('gmail', 'v1', http=http)

这就是我设置gmail API的方式(虽然我有不同的权限,因为我不通过API发送电子邮件)。如果您可以更新您的问题以包含您的设置,我们将很乐意更新我的答案。

答案 3 :(得分:0)

我遇到了同样的问题,首先你需要在google开发者控制台中配置项目,然后在gmail API上下载凭据并将其放入你的项目中,然后你需要设置连接到类的服务发送邮件,这段代码对我有用,你只需要授权许可:我已经调用了sendMail类并使用它的方法。我希望这个对你有用。 PD:请勿在课程名称和其他实例中注意日历,我已修改日历示例以将其与Gmail一起使用。

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
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.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.GmailScopes;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;

public class CalendarSample {



 /**
   * Be sure to specify the name of your application. If the application name is {@code null} or
   * blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
   */
  private static final String APPLICATION_NAME = "gmailProject";

  /** Directory to store user credentials. */
  private static final java.io.File DATA_STORE_DIR =
      new java.io.File(System.getProperty("user.home"), ".store/gmail_sample");

  /**
   * Global instance of the {@link DataStoreFactory}. The best practice is to make it a single
   * globally shared instance across your application.
   */
  private static FileDataStoreFactory dataStoreFactory;

  /** Global instance of the HTTP transport. */
  private static HttpTransport httpTransport;

  /** Global instance of the JSON factory. */
  private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private static com.google.api.services.gmail.Gmail gmailClient;

  /** Authorizes the installed application to access user's protected data. */
  private static Credential authorize() throws Exception {
    // load client secrets
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
        new InputStreamReader(CalendarSample.class.getResourceAsStream("/client_secrets.json")));
    if (clientSecrets.getDetails().getClientId().startsWith("Enter")
        || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
      System.out.println(
          "Enter Client ID and Secret from https://code.google.com/apis/console/?api=gmail "
          + "into calendar-cmdline-sample/src/main/resources/client_secrets.json");
      System.exit(1);
    }
    // set up authorization code flow
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, JSON_FACTORY, clientSecrets,
        Collections.singleton(GmailScopes.MAIL_GOOGLE_COM)).setDataStoreFactory(dataStoreFactory)
        .build();
    // authorize
    return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
  }

  public static void main(String[] args) {
    try {
      // initialize the transport
      httpTransport = GoogleNetHttpTransport.newTrustedTransport();

      // initialize the data store factory
      dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);

      // authorization
      Credential credential = authorize();

            // set up global Gmail instance
           gmailClient = new com.google.api.services.gmail.Gmail.Builder(
           httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();

      mailMethod();

    } catch (IOException e) {
      System.err.println(e.getMessage());
    } catch (Throwable t) {
      t.printStackTrace();
    }
    System.exit(1);
  }

  private static void mailMethod() throws IOException, MessagingException{

    MyClass sendMail = new MyClass();
    MimeMessage mail2;

    mail2 =  sendMail.createEmail("to@gmail.com", "from@gmail.com", "prueba de correo", "prueba de correo2");
    System.out.println("Obtener MIME: " + mail2);

    sendMail.sendMessage(gmailClient, "from@gmail.com", mail2);

  }

}