Skip to content

Commit bd59f3a

Browse files
committed
modified code for google calendar integration according to the new google calendar api manual
1 parent 8c27331 commit bd59f3a

File tree

3 files changed

+63
-45
lines changed

3 files changed

+63
-45
lines changed

zulip/integrations/google/get-google-credentials

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,29 @@
22
import argparse
33
import os
44

5-
from oauth2client import client, tools
6-
from oauth2client.file import Storage
5+
from google.auth.transport.requests import Request
6+
from google.oauth2.credentials import Credentials
7+
from google_auth_oauthlib.flow import InstalledAppFlow
78

8-
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
9+
flags = argparse.ArgumentParser(description="Google Calendar Bot")
10+
flags.add_argument('--noauth_local_webserver', action='store_true',
11+
help='Run OAuth flow in console instead of opening a web browser.')
12+
args = flags.parse_args()
913

1014
# If modifying these scopes, delete your previously saved credentials
1115
# at zulip/bots/gcal/
1216
# NOTE: When adding more scopes, add them after the previous one in the same field, with a space
1317
# seperating them.
14-
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
18+
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
1519
# This file contains the information that google uses to figure out which application is requesting
1620
# this client's data.
1721
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
1822
APPLICATION_NAME = "Zulip Calendar Bot"
1923
HOME_DIR = os.path.expanduser("~")
24+
CREDENTIALS_PATH = os.path.join(HOME_DIR, "google-credentials.json")
2025

2126

22-
def get_credentials() -> client.Credentials:
27+
def get_credentials() -> Credentials:
2328
"""Gets valid user credentials from storage.
2429
2530
If nothing has been stored, or if the stored credentials are invalid,
@@ -29,18 +34,30 @@ def get_credentials() -> client.Credentials:
2934
Credentials, the obtained credential.
3035
"""
3136

32-
credential_path = os.path.join(HOME_DIR, "google-credentials.json")
33-
34-
store = Storage(credential_path)
35-
credentials = store.get()
36-
if not credentials or credentials.invalid:
37-
flow = client.flow_from_clientsecrets(os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES)
38-
flow.user_agent = APPLICATION_NAME
39-
# This attempts to open an authorization page in the default web browser, and asks the user
40-
# to grant the bot access to their data. If the user grants permission, the run_flow()
41-
# function returns new credentials.
42-
credentials = tools.run_flow(flow, store, flags)
43-
print("Storing credentials to " + credential_path)
37+
creds = None
38+
39+
# Check if the credentials file exists
40+
if os.path.exists(CREDENTIALS_PATH):
41+
creds = Credentials.from_authorized_user_file(CREDENTIALS_PATH, SCOPES)
42+
43+
# If there are no valid credentials, initiate the OAuth flow
44+
if not creds or not creds.valid:
45+
if creds and creds.expired and creds.refresh_token:
46+
creds.refresh(Request())
47+
else:
48+
flow = InstalledAppFlow.from_client_secrets_file(
49+
os.path.join(HOME_DIR, CLIENT_SECRET_FILE), SCOPES
50+
)
51+
if args.noauth_local_webserver:
52+
creds = flow.run_console()
53+
else:
54+
creds = flow.run_local_server(port=0)
55+
56+
# Save the credentials for future use
57+
with open(CREDENTIALS_PATH, 'w') as token_file:
58+
token_file.write(creds.to_json())
59+
60+
print("Storing credentials to " + CREDENTIALS_PATH)
4461

4562

4663
get_credentials()

zulip/integrations/google/google-calendar

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,16 @@ import time
1212
from typing import List, Optional, Set, Tuple
1313

1414
import dateutil.parser
15-
import httplib2
1615
import pytz
17-
from oauth2client import client
18-
from oauth2client.file import Storage
19-
20-
try:
21-
from googleapiclient import discovery
22-
except ImportError:
23-
logging.exception("Install google-api-python-client")
24-
sys.exit(1)
16+
from google.auth.transport.requests import Request
17+
from google.oauth2.credentials import Credentials
18+
from google_auth_oauthlib.flow import InstalledAppFlow
19+
from googleapiclient.discovery import build
2520

2621
sys.path.append(os.path.join(os.path.dirname(__file__), "../../"))
2722
import zulip
2823

29-
SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
24+
SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"]
3025
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
3126
APPLICATION_NAME = "Zulip"
3227
HOME_DIR = os.path.expanduser("~")
@@ -87,34 +82,39 @@ if not options.zulip_email:
8782

8883
zulip_client = zulip.init_from_options(options)
8984

90-
91-
def get_credentials() -> client.Credentials:
85+
def get_credentials() -> Credentials:
9286
"""Gets valid user credentials from storage.
9387
9488
If nothing has been stored, or if the stored credentials are invalid,
95-
an exception is thrown and the user is informed to run the script in this directory to get
96-
credentials.
89+
the user will be prompted to authenticate.
9790
9891
Returns:
9992
Credentials, the obtained credential.
10093
"""
101-
try:
102-
credential_path = os.path.join(HOME_DIR, "google-credentials.json")
94+
credential_path = os.path.join(HOME_DIR, "google-credentials.json")
95+
creds = None
96+
97+
# Load credentials from file if they exist
98+
if os.path.exists(credential_path):
99+
creds = Credentials.from_authorized_user_file(credential_path, SCOPES)
100+
101+
# If there are no (valid) credentials available, prompt the user to log in.
102+
if not creds or not creds.valid:
103+
if creds and creds.expired and creds.refresh_token:
104+
creds.refresh(Request())
105+
else:
106+
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
107+
creds = flow.run_local_server(port=0)
103108

104-
store = Storage(credential_path)
105-
return store.get()
106-
except client.Error:
107-
logging.exception("Error while trying to open the `google-credentials.json` file.")
108-
sys.exit(1)
109-
except OSError:
110-
logging.error("Run the get-google-credentials script from this directory first.")
111-
sys.exit(1)
109+
# Save the credentials for the next run
110+
with open(credential_path, "w") as token:
111+
token.write(creds.to_json())
112112

113+
return creds
113114

114115
def populate_events() -> Optional[None]:
115116
credentials = get_credentials()
116-
creds = credentials.authorize(httplib2.Http())
117-
service = discovery.build("calendar", "v3", http=creds)
117+
service = build("calendar", "v3", credentials=credentials)
118118

119119
now = datetime.datetime.now(pytz.utc).isoformat()
120120
feed = (
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
httplib2>=0.22.0
2-
oauth2client>=4.1.3
1+
google-api-python-client>=2.157.0
2+
google-auth-httplib2>=0.2.0
3+
google-auth-oauthlib>=1.2.1

0 commit comments

Comments
 (0)