Lee
Lee

Reputation: 41

Receiving 403 error with Users.Messages.Send in Gmail API

I'm trying to call Send on the GmailService from a C# .NET MVC app. and I keep getting a 403 error when I call send.

I've checked my scopes, the Gmail setup definitely has the Gmail API enabled, and my ClientID and ClientSecret are fresh.

var httpClient = new HttpClient{
  BaseAddress = new Uri("https://www.googleapis.com")
};

var requestUrl = $"oauth2/v4/token?code={code}&client_id={ClientId}&client_secret={SecretKey}&redirect_uri={RedirectUrl}&grant_type=authorization_code";

var dict = new Dictionary<string, string>{
  { "Content-Type", "application/x-www-form-urlencoded" }
};

var req = new HttpRequestMessage(HttpMethod.Post, requestUrl){Content = new FormUrlEncodedContent(dict)};
var response = await httpClient.SendAsync(req);
var token = JsonConvert.DeserializeObject<GmailToken>(await response.Content.ReadAsStringAsync());
Session["user"] = token.AccessToken;

//var obj = await GetuserProfile(token.AccessToken);
var obj = await DoSendEmail(token);
public void DoSendEmail(GmailToken inToken) {
  const string fromAcct = "[email protected]";

  TokenResponse token = new TokenResponse();
  token.AccessToken = inToken.AccessToken;
  token.ExpiresInSeconds = inToken.ExpiresIn;
  token.IdToken = inToken.IdToken;
  token.TokenType = inToken.TokenType;
  token.IssuedUtc = DateTime.UtcNow;

  IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer {
    ClientSecrets = secrets,
    Scopes = SCOPES,
    ProjectId = "Xcent CP"
  });

  UserCredential credential = new UserCredential(flow, fromAcct, token);

  if (credential.Token.IsExpired(credential.Flow.Clock)) {
    bool success = credential.RefreshTokenAsync(CancellationToken.None).Result;
    if (!success) {
      throw new Exception("Could not refresh token");
    }
  }

  GmailService gs = null;
  try {
    gs = new GmailService(new Google.Apis.Services.BaseClientService.Initializer() {
       ApplicationName = APP_NAME,
       HttpClientInitializer = credential
    });

    var mailMessage = new System.Net.Mail.MailMessage();
    mailMessage.From = new System.Net.Mail.MailAddress(fromAcct);
    mailMessage.To.Add("[email protected]");
    mailMessage.ReplyToList.Add(fromAcct);
    mailMessage.Subject = "Test email";
    mailMessage.Body = "<html><body>Hi <b>Lee</b>, this is <b>yet another</b> test message.</body></html>";
    mailMessage.IsBodyHtml = true;

    var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage);

    var gmailMessage = new Google.Apis.Gmail.v1.Data.Message {
      Raw = Encode(mimeMessage.ToString())
    };

    gs.Users.Messages.Send(gmailMessage, fromAcct).Execute();

  }
  catch (Exception ex) {
    throw ex;
  }
  finally {
    if (gs != null) {
      gs.Dispose();
    }
    gs = null;
  }
}

I'm not sure where to look...I've been through many many many online articles and tutorials, tried seemingly everything, and I'm still stuck with the 403 error. Help!

Thanks, Lee

Upvotes: 0

Views: 630

Answers (1)

Lee
Lee

Reputation: 41

So after many hours spent looking at this I figured out the problem. My link to the Google login was this:

Response.Redirect($"https://accounts.google.com/o/oauth2/v2/auth?client_id={ClientId}&response_type=code&scope=openid%20email%20profile&redirect_uri={RedirectUrl}&state=abcdef");

"openid%20email%20profile" was the only scope I was specifying for the login, hence the 403 error about the scope I was using for the flow variable.

phew!

Upvotes: 1

Related Questions