I am trying to access my gmail api with the scope of:
https://www.googleapis.com/auth/gmail.modify
But I am getting a Precondition check failed error.
The below is the code that I am using to connect to my gmail and use to send a message out:
func ConnectToGmailAPI() *gmail.Service {
ctx := context.Background()
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
key := os.Getenv("PRIVATE_KEY")
newkey := strings.Replace(key, "\\n", "\n", -1)
pKey := []byte(newkey)
conf := &jwt.Config{
Email: os.Getenv("CLIENT_EMAIL"),
PrivateKeyID: os.Getenv("PRIVATE_KEY_ID"),
PrivateKey: pKey,
Scopes: []string{
"https://www.googleapis.com/auth/gmail.modify",
},
TokenURL: os.Getenv("TOKEN_URL"),
}
client := conf.Client(ctx)
srv, err := gmail.NewService(ctx, option.WithHTTPClient(client))
if err != nil {
log.Fatalf("Unable to connect to service %v", err)
}
return srv
}
func SendEmail(srv *gmail.Service, subj, msg, to string) (*gmail.Message, error) {
message, err := gmail.NewUsersMessagesService(srv).Send(
"me",
prepMessage(subj, msg, to),
).Do()
if err != nil {
return &gmail.Message{}, err
}
return message, nil
}
func prepMessage(subj, msg, to string) *gmail.Message {
header := make(map[string]string)
header["To"] = to
header["Subject"] = subj
header["Content-Type"] = "text/plain; charset=utf-8"
var headers []*gmail.MessagePartHeader
for k, v := range header {
headers = append(headers, &gmail.MessagePartHeader{Name: k, Value: v})
}
messagePart := &gmail.MessagePart{
Body: &gmail.MessagePartBody{
Data: base64.URLEncoding.EncodeToString([]byte(msg)),
},
Headers: headers,
}
message := gmail.Message{
Payload: messagePart,
}
return &message
}
The below is the actual test I am running:
srv := ConnectToGmailAPI()
msg, err := SendEmail(srv, "Test", "This is a test sending", "[email protected]")
if err != nil {
t.Error(err)
}
Through research I have found that domain wide delegation is needed which I haved ensured is configured with the same scope I am using as evident of the Domain wide Delegation page screen shot below showing the same scope for the service account that was created:
Furthermore, I know that my ConnectToGmailAPI()
function should work because I used the same service account, same environmental variables, and the same config file to set up for a sheets api call which still works. The only thing that I changed between the two implimintations was the scopes in the jwt.Config{}
to be gmail.modify
. To my understanding the rest of the information should be the same because the service account that I am using is the same.
I would appreciate any insight as to how best I can debug this. The error doesn't really point to a specific problem.
Let me know if you need more information
if you are using a service account then you need to denote the user on your domain that you want it to impersonate this is done by setting Subject