ees_microsoft_teams/microsoft_teams_client.py (282 lines of code) (raw):

# # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one # or more contributor license agreements. Licensed under the Elastic License 2.0; # you may not use this file except in compliance with the Elastic License 2.0. # """This module queries Microsoft Teams Graph API and returns the parsed response. """ from . import constant from .microsoft_teams_requests import ( MSTeamsRequests, QueryBuilder, ) from .utils import get_data_from_http_response class MSTeamsClient(MSTeamsRequests): """This class uses the MicrosoftTeamsRequests class to fetch all the supported Microsoft Teams objects and return the parsed response """ def __init__(self, logger, access_token, config): self.access_token = access_token self.logger = logger self.config = config self.query_builder = QueryBuilder() self.retry_count = self.config.get_value('retry_count') def get_teams(self, next_url): """ Get teams from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call """ response_list = {"value": []} while next_url: try: query = self.query_builder.get_query_for_teams().strip() url = f"{next_url}{query}" response_json = self.get(url=url, object_type=constant.TEAMS) response_list["value"].extend(response_json.get("value")) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception( f"Error while fetching teams from the Microsoft Teams. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message="Could not fetch the teams from Microsoft Teams", exception_message="Error while fetching the teams from Microsoft Teams", ) return parsed_response def get_channels(self, next_url): """ Get channels from the Microsoft Teams :param next_url: URL to invoke Graph API call """ try: response = self.get(url=next_url, object_type=constant.CHANNELS) parsed_response = get_data_from_http_response( logger=self.logger, response=response, error_message="Could not fetch the teams from Microsoft Teams", exception_message="Error while fetching the teams from Microsoft Teams", ) return parsed_response except Exception as unknown_exception: self.logger.exception( f"Error while fetching channels from the Microsoft Teams. Error: {unknown_exception}" ) def get_channel_messages(self, next_url, start_time, end_time, channel_name="", is_message_replies=False): """ Get channel messages from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch channel messages :param end_time: Ending time to fetch channel messages :param channel_name: Channel for fetching messages :param is_message_replies: Flag to check if method is used for fetching message replies """ response_list = {"value": []} while next_url: try: query = self.query_builder.get_query_for_channel_and_chat_messages().strip() url = f"{next_url}{query}" response_json = self.get(url=url, object_type=constant.CHANNEL_MESSAGES) # Filter response based on lastModifiedDateTime response_value = response_json.get("value") if response_value: for message in response_value: last_modified_date_time = message.get("lastModifiedDateTime") if start_time <= last_modified_date_time <= end_time: response_list["value"].append(message) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception(f"Error while fetching channel messages from the Microsoft Teams. " f"Error: {unknown_exception}") if is_message_replies: return response_list parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch the messages for channel: {channel_name}", exception_message=f"Error while fetching the messages for channel: {channel_name}" ) return parsed_response def get_channel_tabs(self, next_url, start_time, end_time, channel_name): """ Get channel tabs from the Microsoft Teams with the support of filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch channel tabs :param end_time: Ending time to fetch channel tabs :param channel_name: Channel for fetching channel tabs """ response_list = {"value": []} while next_url: try: response_json = self.get(url=next_url, object_type=constant.CHANNEL_MESSAGES) # Filter response based on dateAdded response_value = response_json.get("value") if response_value: for tab in response_value: date_added = tab.get("configuration").get("dateAdded") if not date_added: response_list["value"].append(tab) elif start_time <= date_added <= end_time: response_list["value"].append(tab) next_url = response_json.get("@odata.nextLink") if not next_url: next_url = None except Exception as unknown_exception: self.logger.exception("Error while fetching the channel tabs from Microsoft Team. " f"Error: {unknown_exception}") parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch tabs for channel: {channel_name}", exception_message=f"Error while fetching tabs for channel: {channel_name}") return parsed_response def get_channel_drives_and_children(self, next_url, object_type, team_name=""): """ Get channel documents from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param object_type: Object type to call the GET api :param team_name: Team for fetching channel documents """ response_list = {"value": []} try: query = self.query_builder.get_query_for_drives_and_docs().strip() url = f"{next_url}{query}" response_json = self.get(url=url, object_type=object_type) return response_json except Exception as unknown_exception: self.logger.exception( f"Error while fetching channel documents the Microsoft Team. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch the channel documents for team: {team_name}", exception_message=f"Error while fetching the channel documents for team: {team_name}" ) return parsed_response def get_channel_documents(self, next_url, start_time, end_time, object_type, team_name=""): """ Get channel documents from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch channel documents :param end_time: Ending time to fetch channel documents :param object_type: Object type to call the GET api :param team_name: Team for fetching channel documents """ response_list = {"value": []} while next_url: try: query = self.query_builder.get_query_for_drives_and_docs().strip() url = f"{next_url}{query}" # The hierarchy(teams > drives > root > children i.e. actual files/folders) through which channel # documents gets fetched. So, due to this `object_type` argument is used to differentiate the objects. response_json = self.get(url=url, object_type=object_type) response_value = response_json.get("value") if response_value: for channel_document in response_value: if channel_document.get("folder"): response_list["value"].append(channel_document) else: last_modified_date_time = channel_document.get("lastModifiedDateTime") if start_time <= last_modified_date_time <= end_time: response_list["value"].append(channel_document) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception("Error while fetching channel documents the Microsoft Team. Error: " f"{unknown_exception}") parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch the channel documents for team: {team_name}", exception_message=f"Error while fetching the channel documents for team: {team_name}" ) return parsed_response def get_user_chats(self, next_url): """ Get user chats from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call """ response_list = {"value": []} is_calling_first_time = True while next_url: try: query = self.query_builder.get_query_for_user_chats().strip() if is_calling_first_time: url = f"{next_url}{query}" is_calling_first_time = False else: url = next_url response_json = self.get(url=url, object_type=constant.CHATS) response_list["value"].extend(response_json.get("value")) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception( f"Error while fetching user chats from the Microsoft Teams. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message="Could not fetch the User Chats from Microsoft Teams", exception_message="Error while fetching the User Chats from Microsoft Teams", ) return parsed_response def get_user_chat_messages(self, next_url, start_time, end_time, chat_id): """ Get user chat messages from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch user chats messages :param end_time: Ending time to fetch user chat messages :param chat_id: Chat ID to fetch user chat messages """ response_list = {"value": []} is_calling_first_time = True while next_url: try: query = self.query_builder.get_query_for_channel_and_chat_messages().strip() if is_calling_first_time: url = f"{next_url}{query}" is_calling_first_time = False else: url = next_url response_json = self.get(url=url, object_type=constant.USER_CHATS_MESSAGE) # Filter response based on lastModifiedDateTime response_value = response_json.get("value") if response_value: for chat_message in response_value: last_modified_date_time = chat_message.get("lastModifiedDateTime") if start_time <= last_modified_date_time <= end_time: response_list["value"].append(chat_message) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception( f"Error while fetching the Microsoft User Chats Messages. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch the User Chats Messages from Microsoft Teams for chat id: {chat_id}", exception_message=f"Error while fetching User Chats Messages from Microsoft Teams for chat id: {chat_id}", ) return parsed_response def get_user_chat_tabs(self, next_url, start_time, end_time, chat_id): """ Get user chat tabs from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch user chats tabs :param end_time: Ending time to fetch user chat tabs :param chat_id: Chat ID to fetch user chat tabs """ response_list = {"value": []} try: response_json = self.get(url=next_url, object_type=constant.USER_CHAT_TABS) if response_json: # Filter response based on dateAdded response_value = response_json.get("value") if response_value: for tab in response_value: date_added = tab.get("configuration").get("dateAdded") if not date_added: response_list["value"].append(tab) elif start_time <= date_added <= end_time: response_list["value"].append(tab) next_url = response_json.get("@odata.nextLink") if not next_url: next_url = None except Exception as unknown_exception: self.logger.exception( f"Error while fetching the Microsoft User Chats Tabs. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message=f"Could not fetch the User Chats Tabs from Microsoft Teams for chat id: {chat_id}", exception_message=f"Error while fetching the User Chats Tabs from Microsoft Teams for chat id: {chat_id}", ) return parsed_response def get_user_chat_attachment_drive(self, next_url): """ Get user chat attachment drives from the Microsoft Teams. :param next_url: URL to invoke Graph API call """ response_json = None try: response_json = self.get(url=next_url, object_type=constant.ATTACHMENTS) except Exception as unknown_exception: self.logger.exception( f"Error while fetching the Microsoft User Chat Attachment. Error: {unknown_exception}" ) return response_json def get_user_chat_attachment_drive_children(self, next_url): """ Get user chat attachments from the Microsoft Teams. :param next_url: URL to invoke Graph API call """ response_list = {"value": []} try: response_json = self.get(url=next_url, object_type=constant.ATTACHMENTS) response_list["value"].extend(response_json.get("value")) except Exception as unknown_exception: self.logger.exception( f"Error while fetching the Microsoft User Chat Attachment. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message="Could not fetch the User Chat Attachment from Microsoft Teams", exception_message="Error while fetching the User Chat Attachment from Microsoft Teams", ) return parsed_response def get_calendars(self, next_url, start_time, end_time): """ Get calendar events from the Microsoft Teams with the support of pagination and filtration. :param next_url: URL to invoke Graph API call :param start_time: Starting time to fetch calendar events :param end_time: Ending time to fetch calendat events """ response_list = {"value": []} while next_url: try: query = self.query_builder.get_query_for_calendars(start_time, end_time).strip() url = f"{next_url}{query}" response_json = self.get(url=url, object_type=constant.CALENDAR) response_list["value"].extend(response_json.get("value")) next_url = response_json.get("@odata.nextLink") if not next_url or next_url == url: next_url = None except Exception as unknown_exception: self.logger.exception( f"Error while fetching calendar events from the Microsoft Teams. Error: {unknown_exception}" ) parsed_response = get_data_from_http_response( logger=self.logger, response=response_list, error_message="Could not fetch the teams from Microsoft Teams", exception_message="Error while fetching the teams from Microsoft Teams", ) return parsed_response