B4J Question Problems after May 30 2022 accessing to Gmail.

PierPaduan

Active Member
Licensed User
Longtime User
Hello.

I have a desktop app, made with B4J, that reads e-mails from a Gmail address. It's a sort of Email Software.
The app is able to do this because in the Gmail account the "Less secure app access" setting is set to ON.
If I set it to OFF, the app cannot access and it gives to me the following error: "(RuntimeException) java.lang.RuntimeException: Error during login: -ERR [AUTH] Username and password not accepted".

My problem is that Google say they "will automatically turn this setting OFF if it’s not being used" and "on May 30, 2022, this setting will no longer be available".
So after May 30 probably they will turn it OFF and I will not be able to turn it ON again.

Google say that to continue signing in the account, my app should use "Sign in with Google" or "OAuth 2.0". How can I do this?

Thanks a Lot.
 

PierPaduan

Active Member
Licensed User
Longtime User
Thanks Erel.

After some test on the "console.developers.google.com", with the example app I has been able to access to a gmail account and got the "people" information.

Now my questions are:
I think that to get access to the Inbox emails of the test account I must add the Gmail API in the API list of Google console. Is it true?
After the access how I have to change the j.download2(....) line the get the emails?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I think that to get access to the Inbox emails of the test account I must add the Gmail API in the API list of Google console. Is it true?
After the access how I have to change the j.download2(....) line the get the emails?
I cannot answer it (I don't remember their API). You need to follow their documentation.
 
Upvote 0

rosippc64a

Active Member
Licensed User
Longtime User
maybe helps to get emails too...
B4X:
Sub getmails
    
    oauth3.Initialize(Me, "oauth3", ClientId, "https://mail.google.com https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.labels",ClientSecret, File.DirData("GoogleContacts"))

    'http://basic4ppc.com:51042/json/index.html
    oauth3.GetAccessToken
    Wait For OAuth3_AccessTokenAvailable (Success As Boolean, Token3 As String)
    If Success = False Then
        LLog("Error accessing account.")
        Return
    End If
    Dim j As HttpJob
    j.Initialize("", Me)
    j.Download("https://gmail.googleapis.com/gmail/v1/users/me/messages")
    j.GetRequest.SetHeader("Authorization", "Bearer " & Token3)
    j.GetRequest.SetHeader("Accept", "application/json")
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        LLog("Mail get successfully")
        LLog(j.GetString)
        Dim parser As JSONParser
        parser.Initialize(j.GetString)
        Dim jRoot As Map = parser.NextObject
        Dim messages As List = jRoot.Get("messages")
        For Each colmessages As Map In messages
            Dim threadId As String = colmessages.Get("threadId")
            Dim id As String = colmessages.Get("id")
            
            Dim jj As HttpJob
            jj.Initialize("", Me)
            jj.Download($"https://gmail.googleapis.com/gmail/v1/users/me/messages/${id}"$)
            jj.GetRequest.SetHeader("Authorization", "Bearer " & Token3)
            jj.GetRequest.SetHeader("Accept", "application/json")
            Wait For (jj) JobDone(jj As HttpJob)
            If jj.Success Then
                LLog("Mail get successfully")
                LLog(jj.GetString)
                LLog("Done!!!")
            Else
                LLog("Failed to get mail.")
            End If
            jj.Release
        Next
        Dim nextPageToken As String = jRoot.Get("nextPageToken")
        Dim resultSizeEstimate As Int = jRoot.Get("resultSizeEstimate")
    Else
        LLog("Failed to get mail.")
    End If
    j.Release
End Sub
 
Upvote 0

j_o_h_n

Active Member
Licensed User
I made a note for myself a while back about how oauth2 works, might be of some use to someone

Oauth2 is a way of having outside programs and services sign into something without knowing the users credentials.
These are what google call secure apps.
OAuth2 is the successor version of the protocol to OAuth
Lots of organisations use OAuth2, not just gmail or google in general, and they don't all have the exact same steps.

How it works (my understanding is probably inaccurate in ways):
SoftwareInc's customer Joe Soap wants SoftwareInc to send and receive emails using his gmail address.
SoftwareInc already has set up an OAUTH2 GOOGLE CLIENT ID and GOOGLE CLIENT SECRET credentials, for gmail, for the company.
So when Joe Soap clicks on the relevant button in the SoftwareInc app, it visits the google authorisation server/ authentication server and enters its credentials and the customer's email, e.g. [email protected].
Google gives back a unique url which the SoftwareInc app now opens in a browser for Joe Soap.
This is a google sign in page and if Joe signs in and agrees then google returns a success message to the SoftwareInc app.
This is some json which contains four fields:
{
"access_token": "xxxxxxxxxxxxx",
"expires_in": 3599,
"refresh_token": "yyyyyyyyyyyyyyy",
"scope": "https://mail.google.com/",
"token_type": "Bearer"
}

Now when signing into gmail SoftwareInc uses the username (as normal) and the access_token in place of a password
The access token above expires in just under an hour (3600 seconds).
When that happens SoftwareInc will use the refresh token above to request a new one.
Refresh tokens never expire (but I think are single use only)
After authorization is granted in this way the user will get a notification on their phone as well as an email about it.
 
Last edited:
Upvote 0

j_o_h_n

Active Member
Licensed User
My question though is will app specific passwords continue to work when this change happens.
 
Upvote 0

PierPaduan

Active Member
Licensed User
Longtime User
maybe helps to get emails too...
B4X:
Sub getmails
   
    oauth3.Initialize(Me, "oauth3", ClientId, "https://mail.google.com https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.labels",ClientSecret, File.DirData("GoogleContacts"))

    'http://basic4ppc.com:51042/json/index.html
    oauth3.GetAccessToken
    Wait For OAuth3_AccessTokenAvailable (Success As Boolean, Token3 As String)
    If Success = False Then
        LLog("Error accessing account.")
        Return
    End If
    Dim j As HttpJob
    j.Initialize("", Me)
    j.Download("https://gmail.googleapis.com/gmail/v1/users/me/messages")
    j.GetRequest.SetHeader("Authorization", "Bearer " & Token3)
    j.GetRequest.SetHeader("Accept", "application/json")
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        LLog("Mail get successfully")
        LLog(j.GetString)
        Dim parser As JSONParser
        parser.Initialize(j.GetString)
        Dim jRoot As Map = parser.NextObject
        Dim messages As List = jRoot.Get("messages")
        For Each colmessages As Map In messages
            Dim threadId As String = colmessages.Get("threadId")
            Dim id As String = colmessages.Get("id")
           
            Dim jj As HttpJob
            jj.Initialize("", Me)
            jj.Download($"https://gmail.googleapis.com/gmail/v1/users/me/messages/${id}"$)
            jj.GetRequest.SetHeader("Authorization", "Bearer " & Token3)
            jj.GetRequest.SetHeader("Accept", "application/json")
            Wait For (jj) JobDone(jj As HttpJob)
            If jj.Success Then
                LLog("Mail get successfully")
                LLog(jj.GetString)
                LLog("Done!!!")
            Else
                LLog("Failed to get mail.")
            End If
            jj.Release
        Next
        Dim nextPageToken As String = jRoot.Get("nextPageToken")
        Dim resultSizeEstimate As Int = jRoot.Get("resultSizeEstimate")
    Else
        LLog("Failed to get mail.")
    End If
    j.Release
End Sub
Yes this helped me a lot. Thanks.
Problem Fixed.
 
Upvote 0
Top