max
max

Reputation: 2396

Golang - Gmail API 400 BadRequest Failed Precondition

I've been struggling against this error (googleapi: Error 400: Bad Request, failedPrecondition) for about 8 hours now. I've written a simple go program which reproduces the problem for me. Maybe someone familiar with the Google APIs can help me out.

The error is the same as the one mentioned here: Gmail REST API : 400 Bad Request + Failed Precondition. The only difference is that it is in Go. I've followed the steps but still no luck.

I've also updated my code based on How to send email through Gmail Go SDK?

Both questions were helpful but did not help resolve the latest issue. I have also set GOOGLE_APPLICATION_CREDENTIALS to my project's json.

package main

import (
    "encoding/base64"
    "fmt"
    "log"
    "net/mail"
    "strings"

    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"

    gmail "google.golang.org/api/gmail/v1"
)

func main() {
    // Use oauth2.NoContext if there isn't a good context to pass in.
    ctx := context.TODO()

    client, err := google.DefaultClient(ctx, gmail.GmailSendScope)
    if err != nil {
        panic(err)
    }

    // create service
    svc, err := gmail.New(client)
    if err != nil {
        log.Fatalf("Unable to create Gmail service: %v", err)
    }

    if err := SendEmail(ctx, svc, <redacted>); err != nil {
        log.Fatalf("failed to send email: %v", err)
    }
}

func SendEmail(ctx context.Context, svc *gmail.Service, email string) error {
    from := mail.Address{"", "[email protected]"}

    header := make(map[string]string)
    header["From"] = from.String()
    header["To"] = email
    header["Subject"] = encodeRFC2047("Hello, Gmail!")
    header["MIME-Version"] = "1.0"
    header["Content-Type"] = "text/html; charset=\"utf-8\""
    header["Content-Transfer-Encoding"] = "base64"

    var msg string
    for k, v := range header {
        msg += fmt.Sprintf("%s: %s\r\n", k, v)
    }
    msg += "\r\n" + "Hello, Gmail!"

    gmsg := gmail.Message{
        Raw: encodeWeb64String([]byte(msg)),
    }

    _, err := svc.Users.Messages.Send("me", &gmsg).Do()
    return err
}

func encodeRFC2047(s string) string {
    // use mail's rfc2047 to encode any string
    addr := mail.Address{s, ""}
    return strings.Trim(addr.String(), " <>")
}

func encodeWeb64String(b []byte) string {

    s := base64.URLEncoding.EncodeToString(b)

    var i = len(s) - 1
    for s[i] == '=' {
        i--
    }

    return s[0 : i+1]
}

Running the code above should produce the following error:

2015/12/12 22:16:46 failed to send email: googleapi: Error 400: Bad Request, failedPrecondition

Upvotes: 0

Views: 1183

Answers (1)

Brandon Jewett-Hall
Brandon Jewett-Hall

Reputation: 746

To send mail, you must specify a valid address for the From: header (https://support.google.com/mail/answer/22370). [email protected] is unlikely to be such an address given that example.com is a test-only domain per RFC 2606.

Upvotes: 1

Related Questions