From a773efb7afba4f21264f57166276836fe15344bc Mon Sep 17 00:00:00 2001 From: Ville Ranki Date: Tue, 10 Dec 2019 23:43:08 +0200 Subject: [PATCH] Google cal enhancements, fix room lookup --- Dockerfile | 7 ++++++- README.md | 8 ++++++-- bot.py | 11 ++--------- docker-compose.yml | 2 +- modules/googlecal.py | 26 ++++++++++++-------------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Dockerfile b/Dockerfile index fa8ac5f..8a8c5d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,11 @@ COPY Pipfile . RUN pipenv install --skip-lock --system COPY bot.py . -COPY modules . +COPY modules modules + +# Uncomment for google calendar: + +#COPY credentials.json . +#COPY token.pickle . CMD [ "python", "-u", "./bot.py" ] diff --git a/README.md b/README.md index 2074371..cfd2610 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,10 @@ Prints bot uptime. Can access a google calendar in a room. This is a bit pain to set up, sorry. -To set up, you'll need to generate credentials.json file - see https://console.developers.google.com/apis/credentials +To set up, you'll need to generate oauth2 credentials.json file - see https://console.developers.google.com/apis/credentials + +Run the bot on *local* machine as OAuth2 wants to open localhost url in your browser. I haven't found out an easy way to +do this on server. When credentials.json is present, you must authenticate the bot to access calendar. There will be a link in console like this: @@ -40,6 +43,7 @@ Please visit this URL to authorize this application: https://accounts.google.com ``` Open the link and authenticate as needed. A new file token.pickle will be created in the directory and bot will read it in future. +Save the token.pickle and ship it with the bot to your server. Edit Dockerfile to copy it in container if needed. Now the bot should be usable. @@ -52,7 +56,7 @@ Commands: * !googlecal today - Show today's events * !googlecal add [calendar id] - Add new calendar to room * !googlecal del [calendar id] - Delete calendar from room -* !googlecal calendars - List calendars in this room +* !googlecal list - List calendars in this room ### Cron diff --git a/bot.py b/bot.py index e869846..19259ac 100755 --- a/bot.py +++ b/bot.py @@ -28,7 +28,7 @@ class Bot: "body": body, "msgtype": "m.text" } - await self.client.room_send(self.get_room_id(room), 'm.room.message', msg) + await self.client.room_send(room.room_id, 'm.room.message', msg) async def send_html(self, room, html, plaintext): msg = { @@ -37,14 +37,7 @@ class Bot: "formatted_body": html, "body": plaintext } - await self.client.room_send(self.get_room_id(room), 'm.room.message', msg) - - def get_room_id(self, room): - for roomid in self.client.rooms: - if self.client.rooms[roomid].named_room_name() == room.named_room_name(): - return roomid - print('Cannot find id for room', room.named_room_name(), ' - is the bot on it?') - return None + await self.client.room_send(room.room_id, 'm.room.message', msg) def get_room_by_id(self, room_id): return self.client.rooms[room_id] diff --git a/docker-compose.yml b/docker-compose.yml index 97e0d5e..e476f7c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: - malobot: + hemppa: container_name: hemppa image: 'hemppa:latest' build: '.' diff --git a/modules/googlecal.py b/modules/googlecal.py index d80ad1b..2d2cce0 100644 --- a/modules/googlecal.py +++ b/modules/googlecal.py @@ -19,19 +19,12 @@ from google.auth.transport.requests import Request # It's created on first run (run from console!) and # can be copied to another computer. # -# ENV variables: -# -# Google calendar creds file: (defaults to this) -# GCAL_CREDENTIALS="credentials.json" -# class MatrixModule: def matrix_start(self, bot): self.bot = bot self.SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'] self.credentials_file = "credentials.json" - if os.getenv("GCAL_CREDENTIALS"): - self.credentials_file = os.getenv("GCAL_CREDENTIALS") self.service = None self.calendar_rooms = dict() # Contains room_id -> [calid, calid] .. @@ -43,25 +36,30 @@ class MatrixModule: if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) + print('Loaded existing pickle file') # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: + print('No credentials or credentials not valid!') if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( self.credentials_file, self.SCOPES) - creds = flow.run_local_server(port=0) + creds = flow.run_local_server(port=0) # urn:ietf:wg:oauth:2.0:oob # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) + print('Pickle saved') self.service = build('calendar', 'v3', credentials=creds) - calendar_list = self.service.calendarList().list().execute()['items'] - - print(f'Google calendar set up successfully with access to {len(calendar_list)} calendars:\n') - for calendar in calendar_list: - print(calendar['summary'] + ' - ' + calendar['id']) + try: + calendar_list = self.service.calendarList().list().execute()['items'] + print(f'Google calendar set up successfully with access to {len(calendar_list)} calendars:\n') + for calendar in calendar_list: + print(calendar['summary'] + ' - ' + calendar['id']) + except: + print('Getting calendar list failed!') async def matrix_message(self, bot, room, event): @@ -77,7 +75,7 @@ class MatrixModule: for calid in calendars: print('Listing events in cal', calid) events = events + self.list_today(calid) - if args[1] == 'calendars': + if args[1] == 'list': await bot.send_text(room, 'Calendars in this room: ' + str(self.calendar_rooms.get(room.room_id))) elif len(args) == 3: if args[1] == 'add':