kootenpv / yagmail

Send email in Python conveniently for gmail using yagmail
MIT License
2.66k stars 265 forks source link

Oauth2 issue: TypeError: refresh_authorization() got an unexpected keyword argument 'installed' #143

Closed DavCza closed 5 years ago

DavCza commented 5 years ago

Env: Win 10, Python 3.7, yagmail 0.11.220:

Any idea?: The first key in the stored client secret JSON file from Google is 'installed. The oauth2 module seems to have a problem accepting it as a kw arg:

File "c:_dev\venv\a3-nlp\lib\site-packages\yagmail\oauth2.py", line 96, in get_oauth_string access_token, expires_in = refresh_authorization(**oauth2_info)

TypeError: refresh_authorization() got an unexpected keyword argument 'installed'

oauth2.py: def get_oauth_string(user, oauth2_info): access_token, expires_in = refresh_authorization(**oauth2_info) auth_string = generate_oauth2_string(user, access_token, as_base64=True) return auth_string

_client_secretgmail.json: {"installed": {"client_id":"224588364290-8enok2fodado2rkrh26go11q3p11dbgi.apps.googleusercontent.com", "project_id":"yagmail-oauth2", "auth_uri":"https://accounts.google.com/o/oauth2/auth", "token_uri":"https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs", "client_secret":"-----------", "redirect_uris":["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]}}

kootenpv commented 5 years ago

Maybe somehow you are generating it in a different way?

Mine looks like:

{
    "google_refresh_token": "XXXXXXX",
    "google_client_secret": "XXX",
    "google_client_id": "XXXX",
    "email_address": "XXX"
}

Did you automatically let it be generated? Just point to a non-existing file and it will try to fill it when it doesn't exist.... so...

yag.SMTP(..., oauth2_file="/my/path") 
DavCza commented 5 years ago

Yes, I was using Google’s JSON file copied from the registered app in the developer console… like using Google Mail API.

The automatic generation did not work in multiple consoles hanging at the end during the input of Google’s response code.

But after a restart it finally worked out and is running fine now, thanks.

Best,

David

From: Pascal van Kooten [mailto:notifications@github.com] Sent: Montag, 2. September 2019 13:37 To: kootenpv/yagmail yagmail@noreply.github.com Cc: David Czarnecki spyz@gmx.de; Author author@noreply.github.com Subject: Re: [kootenpv/yagmail] Oauth2 issue: TypeError: refresh_authorization() got an unexpected keyword argument 'installed' (#143)

Maybe somehow you are generating it in a different way?

Mine looks like:

{ "google_refresh_token": "XXXXXXX", "google_client_secret": "XXX", "google_client_id": "XXXX", "email_address": "XXX" }

Did you automatically let it be generated? Just point to a non-existing file and it will try to fill it when it doesn't exist.... so...

yag.SMTP(..., oauth2_file="/my/path")

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kootenpv/yagmail/issues/143?email_source=notifications&email_token=AHMZHNIXOYVXEZJNK2CQDSTQHT3G3A5CNFSM4IS33FRKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5VSIIQ#issuecomment-527115298 , or mute the thread https://github.com/notifications/unsubscribe-auth/AHMZHNKSCLOOEZOUVTKQEV3QHT3G3ANCNFSM4IS33FRA . https://github.com/notifications/beacon/AHMZHNIERXNBI54E4QNNBZTQHT3G3A5CNFSM4IS33FRKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5VSIIQ.gif

kootenpv commented 5 years ago

Glad to hear it worked!

kgmuzungu commented 4 years ago

same problem here. The google generated .json file does not work.

If I point to a non-existing file yag.SMTP(..., oauth2_file="/my/path"), I get an error: "If you do not have an app registered for your email sending purposes, visit: https://console.developers.google.com and create a new project."

ErikPoppleton commented 2 years ago

I also ran into this problem because Google is not clear that the json file you download when you create the Oauth2 is not the same one you need your app to have access to in order to use yagmail. Here's what I did, hopefully this helps somebody:

  1. I created a project here. I used the email that I want to connect to yagmail, but it doesn't have to be.
  2. Under "APIs and Services" there's an option for "Credentials". Depending on how you got to the Google Cloud site it might already be in the left sidebar, if not, use the search. It's the second one for me (not the Google Maps credentials)
  3. Click "Create Credentials" and fill out the forms. Make sure you specify that your application is a DESKTOP APP, you might think it's a web app because it has an email address, but if you choose web app it will say you have the wrong kind of credentials later.
  4. When filling out the "Oauth consent screen section" you need to add the email account you want to use with yagmail to the "Test Users" section. You have to do this even if that same email account is the one creating the credentials.
  5. Wait a bit, it seems to take 5-10 minutes for any changes to be reflected.
  6. Like @kootenpv said, the first time you try to run a script which sends emails, run it interactively and have it pointed to a credentials.json file that does not exist. DO NOT USE THE FILE THAT GOOGLE GAVE YOU, IT'S NOT THE RIGHT ONE. Yagmail will create the json file when it successfully authenticates.
  7. When yagmail tries to authenticate, it will ask you for the following information: email_address, google_client_id, and google_client_secret, the latter two of which can be found either in the "Edit" page of the credentials or in that json file provided from Google. For some reason I had to enter the id and secret 3 times, but it worked.
  8. It will send you a link which you need to follow to authenticate. If that link gives you a 401 error, then you haven't waited long enough and the credential doesn't exist yet. If it's a 403 then either you didn't set your application type as a desktop app or you didn't include that use in the list of test users.
  9. Send emails to your heart's content.

Some further helpful links:
https://support.google.com/googleapi/answer/6158849?hl=en#zippy=%2Cservice-accounts (terse) https://blog.macuyiko.com/post/2016/how-to-send-html-mails-with-oauth2-and-gmail-in-python.html (kinda out of date)

kramsman commented 1 year ago

I am having the same problem(s) with oauth2 authentication: my file was not in the format specified by DavCza commented [on Sep 2, 2019 (https://github.com/kootenpv/yagmail/issues/143#issuecomment-527216566) above.

When I followed the instructions below I get to step 8 where it is asking to click a link to authenticate, I am simultaneously asked "Enter the localhost URL you were redirected to: >?" to which I replied "http://localhost". I am then brought to google's authentication asking for my email and "Google hasn’t verified this app > continue". So close! But instead of continuing, I get an error page stating "This site can’t be reached / localhost refused to connect. Try: Checking the connection / Checking the proxy and the firewall / ERR_CONNECTION_REFUSED"

Any ideas? I have tried many suggestions and combinations but feel I am going around in circles. Thank you, Brian

I also ran into this problem because Google is not clear that the json file you download when you create the Oauth2 is not the same one you need your app to have access to in order to use yagmail. Here's what I did, hopefully this helps somebody:

  1. I created a project here. I used the email that I want to connect to yagmail, but it doesn't have to be.
  2. Under "APIs and Services" there's an option for "Credentials". Depending on how you got to the Google Cloud site it might already be in the left sidebar, if not, use the search. It's the second one for me (not the Google Maps credentials)
  3. Click "Create Credentials" and fill out the forms. Make sure you specify that your application is a DESKTOP APP, you might think it's a web app because it has an email address, but if you choose web app it will say you have the wrong kind of credentials later.
  4. When filling out the "Oauth consent screen section" you need to add the email account you want to use with yagmail to the "Test Users" section. You have to do this even if that same email account is the one creating the credentials.
  5. Wait a bit, it seems to take 5-10 minutes for any changes to be reflected.
  6. Like @kootenpv said, the first time you try to run a script which sends emails, run it interactively and have it pointed to a credentials.json file that does not exist. DO NOT USE THE FILE THAT GOOGLE GAVE YOU, IT'S NOT THE RIGHT ONE. Yagmail will create the json file when it successfully authenticates.
  7. When yagmail tries to authenticate, it will ask you for the following information: email_address, google_client_id, and google_client_secret, the latter two of which can be found either in the "Edit" page of the credentials or in that json file provided from Google. For some reason I had to enter the id and secret 3 times, but it worked.
  8. It will send you a link which you need to follow to authenticate. If that link gives you a 401 error, then you haven't waited long enough and the credential doesn't exist yet. If it's a 403 then either you didn't set your application type as a desktop app or you didn't include that use in the list of test users.
  9. Send emails to your heart's content.

Some further helpful links: https://support.google.com/googleapi/answer/6158849?hl=en#zippy=%2Cservice-accounts (terse) https://blog.macuyiko.com/post/2016/how-to-send-html-mails-with-oauth2-and-gmail-in-python.html (kinda out of date)