From 62b7b5d84bf16cf5f26925894a09650afb23ff60 Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Fri, 29 Mar 2024 20:06:07 -0700 Subject: [PATCH] Added commands to display Chat events. --- docs/GamUpdates.md | 6 + docs/How-to-Upgrade-from-Standard-GAM.md | 4 +- docs/Users-Chat.md | 73 ++++++++++- docs/Users-Gmail-Messages-Threads.md | 4 +- docs/Version-and-Help.md | 12 +- src/GamCommands.txt | 12 ++ src/GamUpdate.txt | 18 ++- src/gam/__init__.py | 147 ++++++++++++++++++++--- src/gam/gamlib/glapi.py | 2 + src/gam/gamlib/glclargs.py | 4 + src/gam/gamlib/glentity.py | 2 + 11 files changed, 251 insertions(+), 33 deletions(-) diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index bb5fa8db..f3facd6d 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,12 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation +### 6.72.04 + +Added commands to display Chat events. + +* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Chat#display-chat-events + ### 6.72.03 Fixed bug in `gam create chatspace` that caused a trap. diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index ec4b590c..6317bd49 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found -GAMADV-XTD3 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.2 64-bit final MacOS Sonoma 14.2.1 x86_64 @@ -1006,7 +1006,7 @@ writes the credentials into the file oauth2.txt. C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt C:\GAMADV-XTD3>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAMADV-XTD3 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.2 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Users-Chat.md b/docs/Users-Chat.md index d9acc360..24b23f14 100644 --- a/docs/Users-Chat.md +++ b/docs/Users-Chat.md @@ -9,11 +9,15 @@ - [Display Chat Members](#display-chat-members) - [Manage Chat Messages](#manage-chat-messages) - [Display Chat Messages](#display-chat-messages) +- [Display Chat Events](#display-chat-events) - [Bulk Operations](#bulk-operations) ## API documentation -* https://developers.google.com/chat/concepts -* https://developers.google.com/chat/reference/rest +* https://developers.google.com/workspace/chat/overview +* https://developers.google.com/workspace/chat/api/reference/rest +* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.members/list +* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list +* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list * https://support.google.com/chat/answer/7655820 ## Introduction @@ -63,6 +67,7 @@ Google requires that you have a Chat Bot configured in order to use the Chat API (gdoc )| (gcsdoc )) + ::= spaces//spaceEvents/ ::= spaces//members/ ::= "(,)*" ::= spaces//messages/ @@ -378,7 +383,6 @@ Display a specific Chat message. ``` gam info chatmessage name - [filter ] [formatjson] ``` By default, Gam displays the information as an indented list of keys and values. @@ -447,6 +451,69 @@ filter 'createTime > \"2012-04-21T11:30:00+00:00\" AND createTime < \"2013-01-01 filter 'thread.name = spaces/AAAAAAAAAAA/threads/123' ``` +## Display Chat Events +Display a specific Chat event. + +``` +gam info chatevent name + [formatjson] +``` +By default, Gam displays the information as an indented list of keys and values. +* `formatjson` - Display the fields in JSON format. + +### Example +``` +gam user user@domain.com info chatevent name spaces/AAAAsUhqjkg/spaceEvents/MTcxMTY4ODM2NDE3OTQzOV81X3VwZGF0ZWQ +``` + +### Display information about all chat events in a chat space +``` +gam show chatevents + filter + [formatjson] +``` +By default, Gam displays the information as an indented list of keys and values. +* `formatjson` - Display the fields in JSON format. + +``` +gam print chatevents [todrive *] + filter + [formatjson [quotechar ]] +``` +By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format, +* `formatjson` - Display the fields in JSON format. + +By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain +the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled. +When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output. +The `quotechar ` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output. +`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used. + +Use `filter ` to filter events by when they occurred and by the type of event. + +To filter events by the date they happened, specify the start_time and end_time with a timestamp in RFC-3339 format and double quotation marks. + +You must specify at least one event type (event_types) using the has : operator. To filter by multiple event types, use the OR operator. +For a list of supported event types, see: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents#SpaceEvent.FIELDS.event_type + +For example, the following queries are valid on Linux/MacOS: +``` +filter 'start_time="2024-03-15T11:30:00-04:00" AND event_types:"google.workspace.chat.message.v1.created"' +filter 'start_time="2024-03-15T11:30:00+00:00" AND end_time="2024-03-3100:00:00+00:00"event_types:"google.workspace.chat.message.v1.created"' +``` + +For example, the following queries are valid on Windows Command Prompt: +``` +filter "start_time=\"2024-03-15T11:30:00-04:00\" AND event_types:\"google.workspace.chat.message.v1.created\"" +filter "start_time=\"2024-03-15T11:30:00+00:00\" AND end_time=\"2024-03-3100:00:00+00:00\" AND event_types:\"google.workspace.chat.message.v1.created\"" +``` + +For example, the following queries are valid on Windows PowerShell: +``` +filter 'start_time=\"2024-03-15T11:30:00-04:00\" AND event_types:\"google.workspace.chat.message.v1.created\"' +filter 'start_time=\"2024-03-15T11:30:00+00:00\" AND end_time=\"2024-03-3100:00:00+00:00\" AND event_types:\"google.workspace.chat.message.v1.created\"' +``` + ## Bulk Operations ### Display information about all chat spaces for a collection of users ``` diff --git a/docs/Users-Gmail-Messages-Threads.md b/docs/Users-Gmail-Messages-Threads.md index 6ed95a39..fe39cd88 100644 --- a/docs/Users-Gmail-Messages-Threads.md +++ b/docs/Users-Gmail-Messages-Threads.md @@ -355,10 +355,10 @@ See below for message selection. Export messages in EML format. ``` gam export message|messages - (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [doit] [max_to_export ])|(ids ) + (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [max_to_export ])|(ids ) [targetfolder ] [targetname ] [overwrite []] gam export thread|threads - (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [doit] [max_to_export ])|(ids ) + (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [max_to_export ])|(ids ) [targetfolder ] [targetname ] [overwrite []] ``` diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 78e1754c..f5a870f9 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -3,7 +3,7 @@ Print the current version of Gam with details ``` gam version -GAMADV-XTD3 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.2 64-bit final MacOS Sonoma 14.2.1 x86_64 @@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00 Print the current version of Gam with details and time offset information ``` gam version timeoffset -GAMADV-XTD3 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.2 64-bit final MacOS Sonoma 14.2.1 x86_64 @@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second Print the current version of Gam with extended details and SSL information ``` gam version extended -GAMADV-XTD3 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.2 64-bit final MacOS Sonoma 14.2.1 x86_64 @@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64 Path: /Users/Admin/bin/gamadv-xtd3 Version Check: Current: 5.35.08 - Latest: 6.72.03 + Latest: 6.72.04 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.72.03 +6.72.04 ``` In Linux/MacOS you can do: ``` @@ -82,7 +82,7 @@ echo $VER Print the current version of Gam and address of this Wiki ``` gam help -GAM 6.72.03 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.72.04 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.12.2 64-bit final MacOS Sonoma 14.2.1 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 3e1df91f..e4190794 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -2043,6 +2043,9 @@ gam delete chatmessage name gam info chatmessage name [formatjson] +gam info chatevent name + [formatjson] + # Chrome Installed Apps Counts gam show chromeapps @@ -6001,6 +6004,15 @@ gam print chatmessages [todrive *] ]] [filter ] [formatjson [quotechar ]] +gam info chatevent name + [formatjson] +gam show chatevents + filter + [formatjson] +gam print chatevents [todrive *] + filter + [formatjson [quotechar ]] + # Users - Drive ::= diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index f29a4ff5..d72044a5 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -2,6 +2,12 @@ Merged GAM-Team version +6.72.04 + +Added commands to display Chat events. + +* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Chat#display-chat-events + 6.72.03 Fixed bug in `gam create chatspace` that caused a trap. @@ -236,12 +242,12 @@ Added support for Gmail Client Side Encryption. This is an initial, minimally tested release; proceed with care and report all issues. -c6.69.00 +6.69.00 -Added `use_classroom_owner_access` Boolean variable to `gam.cfg` that controls how GAM gets -classroom member information and removes students/teachers. Client access does not provide +Added `use_course_owner_access` Boolean variable to `gam.cfg` that controls how GAM gets +classroom member information and removes students/teachers. Client/admin access does not provide complete information about non-domain students/teachers. -* `False` - Use client access; this is the default. Use if you don't have non-domain members in your courses. +* `False` - Use client/admin access; this is the default. Use if you don't have non-domain members in your courses. * `True` - Use service account access as the classroom owner. An extra API call is required per course to authenticate the owner; this will affect performance Added the following command which must be used to delete classroom invitations for non-domain students/teachers. @@ -443,8 +449,8 @@ Added option `exportlinkeddrivefiles ` to `gam create vaultexport` that Updated `gam remove aliases user|group ` to give a more informative error message when the target/alias combination does not exist. ``` -Old: User: testsimple@rdschool.org, User Alias: tsalias@rdschool.org, Remove Failed: Invalid Input: resource_id -New: User: testsimple@rdschool.org, User Alias: tsalias@rdschool.org, Remove Failed: Does not exist +Old: User: testsimple@domain.com, User Alias: tsalias@domain.com, Remove Failed: Invalid Input: resource_id +New: User: testsimple@domain.com, User Alias: tsalias@domain.com, Remove Failed: Does not exist ``` 6.67.20 diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 381ba88e..1f2be2dd 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -4738,7 +4738,7 @@ def getSvcAcctCredentials(scopesOrAPI, userEmail, softErrors=False, forceOauth=F GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES] = GM.Globals[GM.SVCACCT_SCOPES].get(scopesOrAPI, []) else: GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES] = API.JWT_APIS[scopesOrAPI] - if not GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES]: + if scopesOrAPI != API.CHAT_EVENTS and not GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES]: if softErrors: return None SvcAcctAPIAccessDeniedExit() @@ -4746,6 +4746,9 @@ def getSvcAcctCredentials(scopesOrAPI, userEmail, softErrors=False, forceOauth=F GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES].append(API.USERINFO_PROFILE_SCOPE) if scopesOrAPI in {API.PEOPLE_OTHERCONTACTS}: GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES].append(API.PEOPLE_SCOPE) + elif scopesOrAPI == API.CHAT_EVENTS: + for chatAPI in [API.CHAT_SPACES, API.CHAT_MEMBERSHIPS, API.CHAT_MESSAGES]: + GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES].extend(GM.Globals[GM.SVCACCT_SCOPES].get(chatAPI, [])) else: GM.Globals[GM.CURRENT_SVCACCT_API] = '' GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES] = scopesOrAPI @@ -25847,10 +25850,8 @@ def doInfoChatMember(): # [formatjson [quotechar ]] def printShowChatMembers(users): def _printChatMember(user, member): - row = flattenJSON(member, timeObjects=CHAT_MEMBER_TIME_OBJECTS) - if user is not None: - row['User'] = user - row['space.name'] = parent + row = {'User': user, 'space.name': parent} if user is not None else {'space.name': parent} + flattenJSON(member, flattened=row, timeObjects=CHAT_MEMBER_TIME_OBJECTS) if not FJQC.formatJSON: csvPF.WriteRowTitles(row) elif csvPF.CheckRowTitles(row): @@ -26127,13 +26128,12 @@ def doInfoChatMessage(): def printShowChatMessages(users): def _printChatMessage(user, message): _cleanChatMessage(message) - row = flattenJSON(message, timeObjects=CHAT_MESSAGE_TIME_OBJECTS) - if user is not None: - row['User'] = user + row = {'User': user, 'space.name': parent} if user is not None else {'space.name': parent} + flattenJSON(message, flattened=row, timeObjects=CHAT_MESSAGE_TIME_OBJECTS) if not FJQC.formatJSON: csvPF.WriteRowTitles(row) elif csvPF.CheckRowTitles(row): - row = {'User': user} if user is not None else {} + row = {'User': user, 'space.name': parent} if user is not None else {'space.name': parent} row.update({'name': message['name'], 'JSON': json.dumps(cleanJSON(message, timeObjects=CHAT_MESSAGE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)}) @@ -26194,6 +26194,119 @@ def printShowChatMessages(users): if csvPF: csvPF.writeCSVfile('Chat Messages') +CHAT_EVENT_TIME_OBJECTS = {'createTime', 'deleteTime', 'eventTime', 'lastUpdateTime'} + +def _showChatEvent(event, FJQC, i=0, count=0): + if FJQC.formatJSON: + printLine(json.dumps(cleanJSON(event, timeObjects=CHAT_EVENT_TIME_OBJECTS), + ensure_ascii=False, sort_keys=True)) + return + printEntity([Ent.CHAT_EVENT, event['name']], i, count) + Ind.Increment() + showJSON(None, event, timeObjects=CHAT_EVENT_TIME_OBJECTS) + Ind.Decrement() + +# gam info chatevent name +# [formatjson] +def infoChatEvent(users): + FJQC = FormatJSONQuoteChar() + name = None + while Cmd.ArgumentsRemaining(): + myarg = getArgument() + if myarg == 'name': + name = getString(Cmd.OB_CHAT_EVENT) + else: + FJQC.GetFormatJSON(myarg) + if not name: + missingArgumentExit('name') + i, count, users = getEntityArgument(users) + for user in users: + i += 1 + user, chat, kvList = buildChatServiceObject(API.CHAT_EVENTS, user, i, count, [Ent.CHAT_EVENT, name]) + if not chat: + continue + try: + event = callGAPI(chat.spaces().spaceEvents(), 'get', + throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], + name=name) + if not FJQC.formatJSON: + entityPerformAction(kvList, i, count) + Ind.Increment() + _showChatEvent(event, FJQC) + Ind.Decrement() + except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e: + exitIfChatNotConfigured(chat, kvList, str(e), i, count) + +def doInfoChatEvent(): + infoChatEvent([None]) + +# gam show chatevents +# filter +# [formatjson] +# gam print chatevents [todrive *] +# filter +# [formatjson [quotechar ]] +def printShowChatEvents(users): + def _printChatEvent(user, event): + row = {'User': user, 'space.name': parent} if user is not None else {'space.name': parent} + flattenJSON(event, flattened=row, timeObjects=CHAT_EVENT_TIME_OBJECTS) + if not FJQC.formatJSON: + csvPF.WriteRowTitles(row) + elif csvPF.CheckRowTitles(row): + row = {'User': user, 'space.name': parent} if user is not None else {'space.name': parent} + row.update({'name': event['name'], + 'JSON': json.dumps(cleanJSON(event, timeObjects=CHAT_EVENT_TIME_OBJECTS), + ensure_ascii=False, sort_keys=True)}) + csvPF.WriteRowNoFilter(row) + + csvPF = CSVPrintFile(['User', 'space.name', 'name'] if not isinstance(users, list) else ['space.name', 'name']) if Act.csvFormat() else None + FJQC = FormatJSONQuoteChar(csvPF) + parent = pfilter = None + while Cmd.ArgumentsRemaining(): + myarg = getArgument() + if csvPF and myarg == 'todrive': + csvPF.GetTodriveParameters() + elif myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'): + parent = getChatSpace(myarg) + elif myarg =='filter': + pfilter = getString(Cmd.OB_STRING) + else: + FJQC.GetFormatJSONQuoteChar(myarg, True) + if not parent: + missingArgumentExit('space') + if not pfilter: + missingArgumentExit('filter') + qfilter = f'{Ent.Singular(Ent.CHAT_SPACE)}: {parent}, {pfilter}' + i, count, users = getEntityArgument(users) + for user in users: + i += 1 + user, chat, kvList = buildChatServiceObject(API.CHAT_EVENTS, user, i, count, [Ent.CHAT_SPACE, parent]) + if not chat: + continue + try: + events = callGAPIpages(chat.spaces().spaceEvents(), 'list', 'spaceEvents', + pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter), + throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], + pageSize=CHAT_PAGE_SIZE, parent=parent, filter=pfilter) + except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e: + exitIfChatNotConfigured(chat, kvList, str(e), i, count) + continue + if not csvPF: + jcount = len(events) + if not FJQC.formatJSON: + entityPerformActionNumItems(kvList, jcount, Ent.CHAT_EVENT, i, count) + Ind.Increment() + j = 0 + for event in events: + j += 1 + _showChatEvent(event, FJQC, j, jcount) + Ind.Decrement() + else: + for event in events: + _printChatEvent(user, event) + if csvPF: + csvPF.writeCSVfile('Chat Events') + def _getOrgunitsOrgUnitIdPath(orgUnit): if orgUnit.startswith('orgunits/'): orgUnit = f'id:{orgUnit[9:]}' @@ -54004,7 +54117,7 @@ def _stripCommentPhotoLinks(comment): for reply in comment.get('replies', []): if 'author' in reply: reply['author'].pop('photoLink', None) - + def _showComment(comment, stripPhotoLinks, timeObjects, i=0, count=0, FJQC=None): if stripPhotoLinks: _stripCommentPhotoLinks(comment) @@ -66457,10 +66570,11 @@ def deleteLabelIds(users, labelEntity): l += 1 try: callGAPI(gmail.users().labels(), 'delete', - throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.INVALID, GAPI.PERMISSION_DENIED], + throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.INVALID, + GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], userId='me', id=labelId) entityActionPerformed([Ent.USER, user, Ent.LABEL_ID, labelId], l, lcount) - except (GAPI.notFound, GAPI.invalid, GAPI.permissionDenied) as e: + except (GAPI.notFound, GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: entityActionFailedWarning([Ent.USER, user, Ent.LABEL_ID, labelId], str(e), l, lcount) except (GAPI.serviceNotAvailable, GAPI.badRequest): entityServiceNotApplicableWarning(Ent.USER, user, i, count) @@ -67174,13 +67288,13 @@ def exportMessagesThreads(users, entityType): Ind.Decrement() # gam export message|messages -# (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [doit] [max_to_export ])|(ids ) +# (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [max_to_export ])|(ids ) # [targetfolder ] [targetname ] [overwrite []] def exportMessages(users): exportMessagesThreads(users, Ent.MESSAGE) # gam export thread|threads -# (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [doit] [max_to_export ])|(ids ) +# (((query [querytime ]*) (matchlabel ) [or|and])+ [quick|notquick] [max_to_export ])|(ids ) # [targetfolder ] [targetname ] [overwrite []] def exportThreads(users): exportMessagesThreads(users, Ent.THREAD) @@ -72698,6 +72812,7 @@ MAIN_COMMANDS_WITH_OBJECTS = { Cmd.ARG_ALIAS: doInfoAliases, Cmd.ARG_BUILDING: doInfoBuilding, Cmd.ARG_BROWSER: doInfoBrowsers, + Cmd.ARG_CHATEVENT: doInfoChatEvent, Cmd.ARG_CHATMEMBER: doInfoChatMember, Cmd.ARG_CHATMESSAGE: doInfoChatMessage, Cmd.ARG_CHATSPACE: doInfoChatSpace, @@ -73728,6 +73843,7 @@ USER_COMMANDS_WITH_OBJECTS = { (Act.INFO, {Cmd.ARG_CALENDAR: infoCalendars, Cmd.ARG_CALENDARACL: infoCalendarACLs, + Cmd.ARG_CHATEVENT: infoChatEvent, Cmd.ARG_CHATMEMBER: infoChatMember, Cmd.ARG_CHATMESSAGE: infoChatMessage, Cmd.ARG_CHATSPACE: infoChatSpace, @@ -73799,6 +73915,7 @@ USER_COMMANDS_WITH_OBJECTS = { Cmd.ARG_CALENDAR: printShowCalendars, Cmd.ARG_CALENDARACL: printShowCalendarACLs, Cmd.ARG_CALSETTINGS: printShowCalSettings, + Cmd.ARG_CHATEVENT: printShowChatEvents, Cmd.ARG_CHATMEMBER: printShowChatMembers, Cmd.ARG_CHATMESSAGE: printShowChatMessages, Cmd.ARG_CHATSPACE: printShowChatSpaces, @@ -73900,6 +74017,7 @@ USER_COMMANDS_WITH_OBJECTS = { Cmd.ARG_CALENDAR: printShowCalendars, Cmd.ARG_CALENDARACL: printShowCalendarACLs, Cmd.ARG_CALSETTINGS: printShowCalSettings, + Cmd.ARG_CHATEVENT: printShowChatEvents, Cmd.ARG_CHATMEMBER: printShowChatMembers, Cmd.ARG_CHATMESSAGE: printShowChatMessages, Cmd.ARG_CHATSPACE: printShowChatSpaces, @@ -74106,6 +74224,7 @@ USER_COMMANDS_OBJ_ALIASES = { Cmd.ARG_CALENDARS: Cmd.ARG_CALENDAR, Cmd.ARG_CALENDARACLS: Cmd.ARG_CALENDARACL, Cmd.ARG_CLASSROOMINVITATIONS: Cmd.ARG_CLASSROOMINVITATION, + Cmd.ARG_CHATEVENTS: Cmd.ARG_CHATEVENT, Cmd.ARG_CHATMEMBERS: Cmd.ARG_CHATMEMBER, Cmd.ARG_CHATMESSAGES: Cmd.ARG_CHATMESSAGE, Cmd.ARG_CHATSPACES: Cmd.ARG_CHATSPACE, diff --git a/src/gam/gamlib/glapi.py b/src/gam/gamlib/glapi.py index a78817da..4aec8725 100644 --- a/src/gam/gamlib/glapi.py +++ b/src/gam/gamlib/glapi.py @@ -27,6 +27,7 @@ ANALYTICS_ADMIN = 'analyticsadmin' CALENDAR = 'calendar' CBCM = 'cbcm' CHAT = 'chat' +CHAT_EVENTS = 'chatevents' CHAT_MEMBERSHIPS = 'chatmemberships' CHAT_MESSAGES = 'chatmessages' CHAT_SPACES = 'chatspaces' @@ -190,6 +191,7 @@ _INFO = { CALENDAR: {'name': 'Calendar API', 'version': 'v3', 'v2discovery': True, 'mappedAPI': 'calendar-json'}, CBCM: {'name': 'Chrome Browser Cloud Management API', 'version': 'v1.1beta1', 'v2discovery': True, 'localjson': True}, CHAT: {'name': 'Chat API', 'version': 'v1', 'v2discovery': True}, + CHAT_EVENTS: {'name': 'Chat API - Events', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, CHAT_MEMBERSHIPS: {'name': 'Chat API - Memberships', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, CHAT_MESSAGES: {'name': 'Chat API - Messages', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, CHAT_SPACES: {'name': 'Chat API - Spaces', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, diff --git a/src/gam/gamlib/glclargs.py b/src/gam/gamlib/glclargs.py index 3ac771b8..a073700f 100644 --- a/src/gam/gamlib/glclargs.py +++ b/src/gam/gamlib/glclargs.py @@ -463,6 +463,8 @@ class GamCLArgs(): ARG_CHANNELSKU = 'channelsku' ARG_CHANNELSKUS = 'channelskus' ARG_CHAT = 'chat' + ARG_CHATEVENT = 'chatevent' + ARG_CHATEVENTS = 'chatevents' ARG_CHATMEMBER = 'chatmember' ARG_CHATMEMBERS = 'chatmembers' ARG_CHATMESSAGE = 'chatmessage' @@ -818,6 +820,8 @@ class GamCLArgs(): OB_CHANNEL_CUSTOMER_ID = 'ChannelCustomerID' OB_CHARACTER = 'Character' OB_CHAR_SET = 'CharacterSet' + OG_CHAT_ATTACHMENT = 'ChatAttachment' + OB_CHAT_EVENT = 'ChatEvent' OB_CHAT_MEMBER = 'ChatMember' OB_CHAT_MESSAGE = 'ChatMessage' OB_CHAT_MESSAGE_ID = 'ChatMessageID' diff --git a/src/gam/gamlib/glentity.py b/src/gam/gamlib/glentity.py index cea444b0..3d9f686c 100644 --- a/src/gam/gamlib/glentity.py +++ b/src/gam/gamlib/glentity.py @@ -84,6 +84,7 @@ class GamEntity(): CHANNEL_PRODUCT = 'chpr' CHANNEL_SKU = 'chsk' CHAT_BOT = 'chbo' + CHAT_EVENT = 'chev' CHAT_MANAGER_USER = 'chgu' CHAT_MEMBER = 'chme' CHAT_MEMBER_GROUP = 'chmg' @@ -423,6 +424,7 @@ class GamEntity(): CHANNEL_PRODUCT: ['Channel Products', 'Channel Product'], CHANNEL_SKU: ['Channel SKUs', 'Channel SKU'], CHAT_BOT: ['Chat BOTs', 'Chat BOT'], + CHAT_EVENT: ['Chat Events', 'Chat Event'], CHAT_MANAGER_USER: ['Chat User Managers', 'Chat User Manager'], CHAT_MESSAGE: ['Chat Messages', 'Chat Message'], CHAT_MESSAGE_ID: ['Chat Message IDs', 'Chat Message ID'],