So I have been sending emails from my .NET WebApp via GmailService for the past 2 years and now it suddently stopped working. Here's my piece of code sending emails.
It breaks on the line
var renew = credential.GetAccessTokenForRequestAsync().Result;
with the following error:
{Error:"invalid_grant", Description:"Bad Request", Uri:""}
var tokenResponse = new TokenResponse { RefreshToken = sendData.refreshToken };
UserCredential credential = new UserCredential(new ForceOfflineGoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = sendData.clientID,
ClientSecret = sendData.clientSecret
},
Scopes = Scopes
}
),
"me",
tokenResponse);
var renew = credential.GetAccessTokenForRequestAsync().Result;
// Create service
var service = new GmailService(new BaseClientService.Initializer()
{
ApplicationName = "MySuperNonWorkingApplication",
HttpClientInitializer = credential,
});
var message = CreateRawMessageSystemNet(sendData.sendToAddresses,sendData.subject,sendData.body,sendData.email,sendData.emailDisplayName,sendData.attachments);
var result = service.Users.Messages.Send(new Message
{
Raw = message
}, "me").Execute();
For the UserCredential IAuthorizationCodeFlow parameter I'm using class
internal class ForceOfflineGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
public ForceOfflineGoogleAuthorizationCodeFlow(GoogleAuthorizationCodeFlow.Initializer initializer) : base(initializer) { }
public override AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUrl)
{
return new GoogleAuthorizationCodeRequestUrl(new Uri(AuthorizationServerUrl))
{
ClientId = ClientSecrets.ClientId,
Scope = string.Join(" ", Scopes),
RedirectUri = redirectUrl,
AccessType = "offline",
ApprovalPrompt = "force"
};
}
}
If you're wondering about the content of the object credential when sending it looks like this:
The Scopes variable is "https://mail.google.com/"
Thank you very much in advance!
Looks like I managed to resolve the issue. It was nothing wrong with the code, the code works perfectly fine. The problem was the refresh token. To resolve the issue I had to go to https://developers.google.com/oauthplayground. Then on the right side click the cog wheel, "Use your own OAuth credentials" and had to insert to ClientID and Client secret. On the left side, underneath step 1 I had to choose Gmail API (https://mail.google.com/) and click "Authorize API". By doing so, underneath step 2 I received a new Authorization Code and upon clicking "Exchange authorization code for tokens" I received new refresh token. Now upon inserting the new refresh token into
var tokenResponse = new TokenResponse { RefreshToken = sendData.refreshToken };
the code works as it's supposted to.