mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 09:51:36 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c593b5809 | ||
|
|
d76ef999c5 | ||
|
|
ddaad4d655 | ||
|
|
36a1bdc56b | ||
|
|
089a5994aa | ||
|
|
3e9b46b650 | ||
|
|
7ca3b4d7da | ||
|
|
22d70ca2c3 | ||
|
|
b3acdf5955 | ||
|
|
c13a5215fe | ||
|
|
45750b591a | ||
|
|
c76f1b2128 | ||
|
|
e85e7f6868 | ||
|
|
055c74ed2e | ||
|
|
4ba9385c23 | ||
|
|
9d8442c7ad | ||
|
|
cc19878ba4 | ||
|
|
23ed20a298 | ||
|
|
5b32bc31c7 | ||
|
|
e1260dbd95 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -165,7 +165,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
cache.tar.xz
|
cache.tar.xz
|
||||||
key: gam-${{ matrix.jid }}-20260508
|
key: gam-${{ matrix.jid }}-20260523
|
||||||
|
|
||||||
- name: Untar Cache archive
|
- name: Untar Cache archive
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ dependencies = [
|
|||||||
"google-api-python-client==2.196.0",
|
"google-api-python-client==2.196.0",
|
||||||
"google-auth-httplib2==0.4.0",
|
"google-auth-httplib2==0.4.0",
|
||||||
"google-auth-oauthlib==1.4.0",
|
"google-auth-oauthlib==1.4.0",
|
||||||
"google-auth==2.52.0",
|
"google-auth==2.53.0",
|
||||||
"httplib2==0.31.2",
|
"httplib2==0.31.2",
|
||||||
"lxml==6.1.0",
|
"lxml==6.1.0",
|
||||||
"passlib==1.7.4",
|
"passlib==1.7.4",
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
||||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
cloudidentityfree | cloudidentity | identity | 1010010001 | Cloud Identity Free |
|
||||||
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
||||||
cloudsearch | 1010350001 | Cloud Search |
|
cloudsearch | 1010350001 | Cloud Search |
|
||||||
colabpro | 1010500001 | Colab Pro |
|
colabpro | 1010500001 | Colab Pro |
|
||||||
@@ -2511,6 +2511,7 @@ gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatc
|
|||||||
autoupdateexpiration|
|
autoupdateexpiration|
|
||||||
autoupdatethrough|
|
autoupdatethrough|
|
||||||
backlightinfo|
|
backlightinfo|
|
||||||
|
bluetoothadapterinfo|
|
||||||
bootmode|
|
bootmode|
|
||||||
chromeostype|
|
chromeostype|
|
||||||
cpuinfo|
|
cpuinfo|
|
||||||
@@ -2544,6 +2545,7 @@ gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatc
|
|||||||
orgunitpath|org|ou|
|
orgunitpath|org|ou|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
osversion|
|
osversion|
|
||||||
|
osversioncompliance|
|
||||||
platformversion|
|
platformversion|
|
||||||
recentusers|
|
recentusers|
|
||||||
screenshotfiles|
|
screenshotfiles|
|
||||||
@@ -2725,25 +2727,30 @@ gam <CrOSTypeEntity> get devicefile [select <DeviceFileEntity>] [targetfolder <F
|
|||||||
Print telemetry data for specified CrOS devices.
|
Print telemetry data for specified CrOS devices.
|
||||||
|
|
||||||
<CrOSTelemetryFieldName> ::=
|
<CrOSTelemetryFieldName> ::=
|
||||||
|
appreport|
|
||||||
audiostatusreport|
|
audiostatusreport|
|
||||||
batteryinfo|
|
batteryinfo|
|
||||||
batterystatusreport|
|
batterystatusreport|
|
||||||
bootPerformancereport|
|
bootperformancereport|
|
||||||
cpuinfo|
|
cpuinfo|
|
||||||
cpustatusreport|
|
cpustatusreport|
|
||||||
customer|
|
customer|
|
||||||
deviceid|
|
deviceid|
|
||||||
graphicsinfo|
|
graphicsinfo|
|
||||||
graphicsstatusreport|
|
graphicsstatusreport|
|
||||||
|
heartbeatstatusreport|
|
||||||
|
kioskappstatusreport|
|
||||||
memoryinfo|
|
memoryinfo|
|
||||||
memorystatusreport|
|
memorystatusreport|
|
||||||
name|
|
name|
|
||||||
|
networkbandwidthreport|
|
||||||
networkdiagnosticsreport|
|
networkdiagnosticsreport|
|
||||||
networkinfo|
|
networkinfo|
|
||||||
networkstatusreport|
|
networkstatusreport|
|
||||||
orgunitid|
|
orgunitid|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
peripheralsreport|
|
peripheralsreport|
|
||||||
|
runtimecountersreport|
|
||||||
serialnumber|
|
serialnumber|
|
||||||
storageinfo|
|
storageinfo|
|
||||||
storagestatusreport|
|
storagestatusreport|
|
||||||
@@ -2751,20 +2758,22 @@ Print telemetry data for specified CrOS devices.
|
|||||||
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
|
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
|
||||||
|
|
||||||
<CrOSTelemetryListFieldName> ::=
|
<CrOSTelemetryListFieldName> ::=
|
||||||
|
appreport|
|
||||||
audiostatusreport|
|
audiostatusreport|
|
||||||
batteryinfo|
|
|
||||||
batterystatusreport|
|
batterystatusreport|
|
||||||
bootperformancereport|
|
bootperformancereport|
|
||||||
cpuinfo|
|
|
||||||
cpustatusreport|
|
cpustatusreport|
|
||||||
graphicsstatusreport|
|
graphicsstatusreport|
|
||||||
|
heartbeatstatusreport|
|
||||||
|
kioskappstatusreport|
|
||||||
memorystatusreport|
|
memorystatusreport|
|
||||||
|
networkbandwidthreport|
|
||||||
networkdiagnosticsreport|
|
networkdiagnosticsreport|
|
||||||
networkstatusreport|
|
networkstatusreport|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
peripheralsreport|
|
peripheralsreport|
|
||||||
storagestatusreport|
|
runtimecountersreport|
|
||||||
thunderboltinfo
|
storagestatusreport
|
||||||
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
|
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
|
||||||
|
|
||||||
gam info crostelemetry <SerialNumber>
|
gam info crostelemetry <SerialNumber>
|
||||||
@@ -2781,7 +2790,7 @@ gam show crostelemetry
|
|||||||
gam print crostelemetry [todrive <ToDriveAttribute>*]
|
gam print crostelemetry [todrive <ToDriveAttribute>*]
|
||||||
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
||||||
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
||||||
[reverselists <CrOSTelemetryListFieldNameList>]
|
[reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
|
||||||
[start <Date>] [end <Date>] [listlimit <Number>]
|
[start <Date>] [end <Date>] [listlimit <Number>]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
|
|
||||||
@@ -6768,13 +6777,41 @@ gam <UserTypeEntity> info chatmessage name <ChatMessage>
|
|||||||
[formatjson]
|
[formatjson]
|
||||||
gam <UserTypeEntity> show chatmessages
|
gam <UserTypeEntity> show chatmessages
|
||||||
<ChatSpace>+
|
<ChatSpace>+
|
||||||
[showdeleted [<Boolean>]] [filter <String>]
|
[showdeleted [<Boolean>]
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
[fields <ChatMessageFieldNameList>]
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime [ascending|descending]]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
||||||
<ChatSpace>+
|
<ChatSpace>+
|
||||||
[showdeleted [<Boolean>]] [filter <String>]
|
[showdeleted [<Boolean>]
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[thread <ChatThread>])
|
||||||
[fields <ChatMessageFieldNameList>]
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime [ascending|descending]]
|
||||||
|
[formatjson [quotechar <Character>]]
|
||||||
|
|
||||||
|
gam <UserTypeEntity> show chatsearchmessages
|
||||||
|
keywords <StringList>
|
||||||
|
<ChatSpace>*
|
||||||
|
[displaynames [all|any] <StringList>]
|
||||||
|
[senders <EmailAddressEntity>]*
|
||||||
|
[usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[hasattachment]
|
||||||
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime|relevance]
|
||||||
|
[formatjson]
|
||||||
|
gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
|
||||||
|
keywords <StringList>
|
||||||
|
<ChatSpace>*
|
||||||
|
[displaynames [all|any] <StringList>]
|
||||||
|
[senders <EmailAddressEntity>]*
|
||||||
|
[usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[hasattachment]
|
||||||
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime|relevance]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
|
|
||||||
gam <UserTypeEntity> info chatevent name <ChatEvent>
|
gam <UserTypeEntity> info chatevent name <ChatEvent>
|
||||||
|
|||||||
@@ -1,3 +1,46 @@
|
|||||||
|
7.44.02
|
||||||
|
|
||||||
|
Added fields `bluetoothadapterinfo` and `osversioncompliance` to `<CrOSFieldName>` for use
|
||||||
|
in `gam info|print cros`.
|
||||||
|
|
||||||
|
7.44.01
|
||||||
|
|
||||||
|
Added option `oneitemperrow` to `gam print crostelemetry` to have each of a device's
|
||||||
|
report field entries displayed on a separate row with all of the other device fields.
|
||||||
|
|
||||||
|
Added additional fields to `<CrOSTelemetryFieldName>`and `<CrOSTelemetryListFieldName>`:
|
||||||
|
```
|
||||||
|
appreport
|
||||||
|
heartbeatstatusreport
|
||||||
|
kioskappstatusreport
|
||||||
|
networkbandwidthreport
|
||||||
|
runtimecountersreport
|
||||||
|
```
|
||||||
|
|
||||||
|
7.44.00
|
||||||
|
|
||||||
|
Added support for User data `archivalTime` and `suspensionTime` that is available
|
||||||
|
when fields `archived` and `suspended` are requested in `gam info user` and `gam print users`.
|
||||||
|
|
||||||
|
Added the following options to `gam <UserTypeEntity> show chatmessages` to simplify specifying a filter.
|
||||||
|
```
|
||||||
|
start|starttime <Date>|<Time>
|
||||||
|
end|endtime <Date>|<Time>
|
||||||
|
range <Date>|<Time> <Date>|<Time>
|
||||||
|
thread <ChatThread>
|
||||||
|
```
|
||||||
|
|
||||||
|
Added commands to search for and display chat messages.
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#display-chat-messages-by-searching
|
||||||
|
|
||||||
|
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
|
||||||
|
```
|
||||||
|
developer_preview_apis = chat
|
||||||
|
developer_preview_api_key = <DeveloperPreviewKey>
|
||||||
|
```
|
||||||
|
|
||||||
|
Upgraded to Python 3.14.5.
|
||||||
|
|
||||||
7.43.10
|
7.43.10
|
||||||
|
|
||||||
Updated `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity>` to not forward messages
|
Updated `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity>` to not forward messages
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.43.10'
|
__version__ = '7.44.02'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
# pylint: disable=wrong-import-position
|
||||||
@@ -1002,6 +1002,13 @@ def getChoiceAndValue(item, choices, delimiter):
|
|||||||
missingArgumentExit(item)
|
missingArgumentExit(item)
|
||||||
invalidChoiceExit(choice, choices, False)
|
invalidChoiceExit(choice, choices, False)
|
||||||
|
|
||||||
|
AND_OR_CONJUNCTION_MAP = {
|
||||||
|
'and': 'AND',
|
||||||
|
'or': 'OR',
|
||||||
|
'all': 'AND',
|
||||||
|
'any': 'OR',
|
||||||
|
}
|
||||||
|
|
||||||
SUSPENDED_ARGUMENTS = {'notsuspended', 'suspended', 'issuspended'}
|
SUSPENDED_ARGUMENTS = {'notsuspended', 'suspended', 'issuspended'}
|
||||||
SUSPENDED_CHOICE_MAP = {'notsuspended': False, 'suspended': True}
|
SUSPENDED_CHOICE_MAP = {'notsuspended': False, 'suspended': True}
|
||||||
def _getIsSuspended(myarg):
|
def _getIsSuspended(myarg):
|
||||||
@@ -24642,7 +24649,7 @@ def _getFilterDateTime():
|
|||||||
return (filterDate, filterDate.replace(tzinfo='UTC'))
|
return (filterDate, filterDate.replace(tzinfo='UTC'))
|
||||||
|
|
||||||
CROS_FIELDS_CHOICE_MAP = {
|
CROS_FIELDS_CHOICE_MAP = {
|
||||||
'activetimeranges': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'],
|
'activetimeranges': 'activeTimeRanges',
|
||||||
'annotatedassetid': 'annotatedAssetId',
|
'annotatedassetid': 'annotatedAssetId',
|
||||||
'annotatedlocation': 'annotatedLocation',
|
'annotatedlocation': 'annotatedLocation',
|
||||||
'annotateduser': 'annotatedUser',
|
'annotateduser': 'annotatedUser',
|
||||||
@@ -24651,12 +24658,13 @@ CROS_FIELDS_CHOICE_MAP = {
|
|||||||
'autoupdateexpiration': 'autoUpdateExpiration',
|
'autoupdateexpiration': 'autoUpdateExpiration',
|
||||||
'autoupdatethrough': 'autoUpdateThrough',
|
'autoupdatethrough': 'autoUpdateThrough',
|
||||||
'backlightinfo': 'backlightInfo',
|
'backlightinfo': 'backlightInfo',
|
||||||
|
'bluetoothadapterinfo': 'bluetoothAdapterInfo',
|
||||||
'bootmode': 'bootMode',
|
'bootmode': 'bootMode',
|
||||||
'chromeostype': 'chromeOsType',
|
'chromeostype': 'chromeOsType',
|
||||||
'cpuinfo': 'cpuInfo',
|
'cpuinfo': 'cpuInfo',
|
||||||
'cpustatusreports': 'cpuStatusReports',
|
'cpustatusreports': 'cpuStatusReports',
|
||||||
'deprovisionreason': 'deprovisionReason',
|
'deprovisionreason': 'deprovisionReason',
|
||||||
'devicefiles': ['deviceFiles.type', 'deviceFiles.createTime'],
|
'devicefiles': 'deviceFiles',
|
||||||
'deviceid': 'deviceId',
|
'deviceid': 'deviceId',
|
||||||
'devicelicensetype': 'deviceLicenseType',
|
'devicelicensetype': 'deviceLicenseType',
|
||||||
'diskspaceusage': 'diskSpaceUsage',
|
'diskspaceusage': 'diskSpaceUsage',
|
||||||
@@ -24686,9 +24694,10 @@ CROS_FIELDS_CHOICE_MAP = {
|
|||||||
'orgunitpath': 'orgUnitPath',
|
'orgunitpath': 'orgUnitPath',
|
||||||
'osupdatestatus': 'osUpdateStatus',
|
'osupdatestatus': 'osUpdateStatus',
|
||||||
'osversion': 'osVersion',
|
'osversion': 'osVersion',
|
||||||
|
'osversioncompliance': 'osVersionCompliance',
|
||||||
'ou': 'orgUnitPath',
|
'ou': 'orgUnitPath',
|
||||||
'platformversion': 'platformVersion',
|
'platformversion': 'platformVersion',
|
||||||
'recentusers': ['recentUsers.email', 'recentUsers.type'],
|
'recentusers': 'recentUsers',
|
||||||
'screenshotfiles': 'screenshotFiles',
|
'screenshotfiles': 'screenshotFiles',
|
||||||
'serialnumber': 'serialNumber',
|
'serialnumber': 'serialNumber',
|
||||||
'status': 'status',
|
'status': 'status',
|
||||||
@@ -24696,11 +24705,11 @@ CROS_FIELDS_CHOICE_MAP = {
|
|||||||
'systemramfreereports': 'systemRamFreeReports',
|
'systemramfreereports': 'systemRamFreeReports',
|
||||||
'systemramtotal': 'systemRamTotal',
|
'systemramtotal': 'systemRamTotal',
|
||||||
'tag': 'annotatedAssetId',
|
'tag': 'annotatedAssetId',
|
||||||
'timeranges': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'],
|
'timeranges': 'activeTimeRanges',
|
||||||
'times': ['activeTimeRanges.activeTime', 'activeTimeRanges.date'],
|
'times': 'activeTimeRanges',
|
||||||
'tpmversioninfo': 'tpmVersionInfo',
|
'tpmversioninfo': 'tpmVersionInfo',
|
||||||
'user': 'annotatedUser',
|
'user': 'annotatedUser',
|
||||||
'users': ['recentUsers.email', 'recentUsers.type'],
|
'users': 'recentUsers',
|
||||||
'willautorenew': 'willAutoRenew',
|
'willautorenew': 'willAutoRenew',
|
||||||
}
|
}
|
||||||
CROS_BASIC_FIELDS_LIST = ['deviceId', 'annotatedAssetId', 'annotatedLocation', 'annotatedUser', 'lastSync', 'notes', 'serialNumber', 'status']
|
CROS_BASIC_FIELDS_LIST = ['deviceId', 'annotatedAssetId', 'annotatedLocation', 'annotatedUser', 'lastSync', 'notes', 'serialNumber', 'status']
|
||||||
@@ -24721,6 +24730,7 @@ CROS_SCALAR_PROPERTY_PRINT_ORDER = [
|
|||||||
'firmwareVersion',
|
'firmwareVersion',
|
||||||
'platformVersion',
|
'platformVersion',
|
||||||
'osVersion',
|
'osVersion',
|
||||||
|
'osVersionCompliance',
|
||||||
'bootMode',
|
'bootMode',
|
||||||
'meid',
|
'meid',
|
||||||
'dockMacAddress',
|
'dockMacAddress',
|
||||||
@@ -24969,6 +24979,9 @@ def infoCrOSDevices(entityList):
|
|||||||
backlightInfo = _filterBasicList(cros, 'backLightInfo', True, listLimit)
|
backlightInfo = _filterBasicList(cros, 'backLightInfo', True, listLimit)
|
||||||
if backlightInfo:
|
if backlightInfo:
|
||||||
showJSON('backlightInfo', backlightInfo, dictObjectsKey={'backlightInfo': 'path'})
|
showJSON('backlightInfo', backlightInfo, dictObjectsKey={'backlightInfo': 'path'})
|
||||||
|
bluetoothAdapterInfo = _filterBasicList(cros, 'bluetoothAdapterInfo', True, listLimit)
|
||||||
|
if bluetoothAdapterInfo:
|
||||||
|
showJSON('bluetoothAdapterInfo', bluetoothAdapterInfo, dictObjectsKey={'bluetoothAdapterInfo': 'address'})
|
||||||
fanInfo = _filterBasicList(cros, 'fanInfo', True, listLimit)
|
fanInfo = _filterBasicList(cros, 'fanInfo', True, listLimit)
|
||||||
if fanInfo:
|
if fanInfo:
|
||||||
showJSON('fanInfo', fanInfo)
|
showJSON('fanInfo', fanInfo)
|
||||||
@@ -25198,7 +25211,8 @@ CROS_ENTITIES_MAP = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
|
CROS_INDEXED_TITLES = ['activeTimeRanges', 'recentUsers', 'deviceFiles',
|
||||||
'cpuStatusReports', 'cpuInfo', 'backlightInfo', 'fanInfo', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports']
|
'cpuStatusReports', 'cpuInfo', 'backlightInfo', 'bluetoothAdapterInfo', 'fanInfo',
|
||||||
|
'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports']
|
||||||
|
|
||||||
# gam print cros [todrive <ToDriveAttribute>*]
|
# gam print cros [todrive <ToDriveAttribute>*]
|
||||||
# [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
|
# [(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
|
||||||
@@ -25272,7 +25286,7 @@ def doPrintCrOSDevices(entityList=None):
|
|||||||
return
|
return
|
||||||
row = {}
|
row = {}
|
||||||
for attrib in cros:
|
for attrib in cros:
|
||||||
if attrib in {'cpuInfo', 'backlightInfo', 'fanInfo'}:
|
if attrib in {'cpuInfo', 'backlightInfo', 'bluetoothAdapterInfo', 'fanInfo'}:
|
||||||
flattenJSON({attrib: cros[attrib]}, flattened=row)
|
flattenJSON({attrib: cros[attrib]}, flattened=row)
|
||||||
elif attrib not in {'kind', 'etag', 'diskSpaceUsage', 'osUpdateStatus', 'tpmVersionInfo', 'activeTimeRanges', 'recentUsers',
|
elif attrib not in {'kind', 'etag', 'diskSpaceUsage', 'osUpdateStatus', 'tpmVersionInfo', 'activeTimeRanges', 'recentUsers',
|
||||||
'deviceFiles', 'cpuStatusReports', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports'}:
|
'deviceFiles', 'cpuStatusReports', 'diskVolumeReports', 'lastKnownNetwork', 'screenshotFiles', 'systemRamFreeReports'}:
|
||||||
@@ -25304,7 +25318,7 @@ def doPrintCrOSDevices(entityList=None):
|
|||||||
for key in ['email', 'type']:
|
for key in ['email', 'type']:
|
||||||
new_row[f'recentUsers{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = recentUsers[i][key]
|
new_row[f'recentUsers{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = recentUsers[i][key]
|
||||||
if i < lenDF:
|
if i < lenDF:
|
||||||
for key in ['type', 'createTime']:
|
for key in ['name', 'type', 'downloadUrl', 'createTime']:
|
||||||
new_row[f'deviceFiles{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = deviceFiles[i][key]
|
new_row[f'deviceFiles{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{key}'] = deviceFiles[i][key]
|
||||||
if i < lenCSR:
|
if i < lenCSR:
|
||||||
new_row[f'cpuStatusReports{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}reportTime'] = cpuStatusReports[i]['reportTime']
|
new_row[f'cpuStatusReports{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}reportTime'] = cpuStatusReports[i]['reportTime']
|
||||||
@@ -25820,6 +25834,7 @@ def doPrintCrOSEntity(entityList):
|
|||||||
doPrintCrOSActivity(entityList)
|
doPrintCrOSActivity(entityList)
|
||||||
|
|
||||||
CROS_TELEMETRY_FIELDS_CHOICE_MAP = {
|
CROS_TELEMETRY_FIELDS_CHOICE_MAP = {
|
||||||
|
'appreport': 'appReport',
|
||||||
'audiostatusreport': 'audioStatusReport',
|
'audiostatusreport': 'audioStatusReport',
|
||||||
'batteryinfo': 'batteryInfo',
|
'batteryinfo': 'batteryInfo',
|
||||||
'batterystatusreport': 'batteryStatusReport',
|
'batterystatusreport': 'batteryStatusReport',
|
||||||
@@ -25830,35 +25845,41 @@ CROS_TELEMETRY_FIELDS_CHOICE_MAP = {
|
|||||||
'deviceid': 'deviceId',
|
'deviceid': 'deviceId',
|
||||||
'graphicsinfo': 'graphicsInfo',
|
'graphicsinfo': 'graphicsInfo',
|
||||||
'graphicsstatusreport': 'graphicsStatusReport',
|
'graphicsstatusreport': 'graphicsStatusReport',
|
||||||
|
'heartbeatstatusreport': 'heartbeatStatusReport',
|
||||||
|
'kioskappstatusreport': 'kioskAppStatusReport',
|
||||||
'memoryinfo': 'memoryInfo',
|
'memoryinfo': 'memoryInfo',
|
||||||
'memorystatusreport': 'memoryStatusReport',
|
'memorystatusreport': 'memoryStatusReport',
|
||||||
'name': 'name',
|
'name': 'name',
|
||||||
'networkinfo': 'networkInfo',
|
'networkbandwidthreport': 'networkBandwidthReport',
|
||||||
'networkdiagnosticsreport': 'networkDiagnosticsReport',
|
'networkdiagnosticsreport': 'networkDiagnosticsReport',
|
||||||
|
'networkinfo': 'networkInfo',
|
||||||
'networkstatusreport': 'networkStatusReport',
|
'networkstatusreport': 'networkStatusReport',
|
||||||
'orgunitid': 'orgUnitId',
|
'orgunitid': 'orgUnitId',
|
||||||
'osupdatestatus': 'osUpdateStatus',
|
'osupdatestatus': 'osUpdateStatus',
|
||||||
'peripheralsreport': 'peripheralsReport',
|
'peripheralsreport': 'peripheralsReport',
|
||||||
|
'runtimecountersreport': 'runtimeCountersReport',
|
||||||
'serialnumber': 'serialNumber',
|
'serialnumber': 'serialNumber',
|
||||||
'storageinfo': 'storageInfo',
|
'storageinfo': 'storageInfo',
|
||||||
'storagestatusreport': 'storageStatusReport',
|
'storagestatusreport': 'storageStatusReport',
|
||||||
'thunderboltinfo': 'thunderboltInfo',
|
'thunderboltinfo': 'thunderboltInfo',
|
||||||
}
|
}
|
||||||
CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP = {
|
CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP = {
|
||||||
|
'appreport': 'appReport',
|
||||||
'audiostatusreport': 'audioStatusReport',
|
'audiostatusreport': 'audioStatusReport',
|
||||||
'batteryinfo': 'batteryInfo',
|
|
||||||
'batterystatusreport': 'batteryStatusReport',
|
'batterystatusreport': 'batteryStatusReport',
|
||||||
'bootperformancereport': 'bootPerformanceReport',
|
'bootperformancereport': 'bootPerformanceReport',
|
||||||
'cpuinfo': 'cpuInfo',
|
|
||||||
'cpustatusreport': 'cpuStatusReport',
|
'cpustatusreport': 'cpuStatusReport',
|
||||||
'graphicsstatusreport': 'graphicsStatusReport',
|
'graphicsstatusreport': 'graphicsStatusReport',
|
||||||
|
'heartbeatstatusreport': 'heartbeatStatusReport',
|
||||||
|
'kioskappstatusreport': 'kioskAppStatusReport',
|
||||||
'memorystatusreport': 'memoryStatusReport',
|
'memorystatusreport': 'memoryStatusReport',
|
||||||
|
'networkbandwidthreport': 'networkBandwidthReport',
|
||||||
'networkdiagnosticsreport': 'networkDiagnosticsReport',
|
'networkdiagnosticsreport': 'networkDiagnosticsReport',
|
||||||
'networkstatusreport': 'networkStatusReport',
|
'networkstatusreport': 'networkStatusReport',
|
||||||
'osupdatestatus': 'osUpdateStatus',
|
'osupdatestatus': 'osUpdateStatus',
|
||||||
'peripheralsreport': 'peripheralsReport',
|
'peripheralsreport': 'peripheralsReport',
|
||||||
|
'runtimecountersreport': 'runtimeCountersReport',
|
||||||
'storagestatusreport': 'storageStatusReport',
|
'storagestatusreport': 'storageStatusReport',
|
||||||
'thunderboltinfo': 'thunderboltInfo',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CROS_TELEMETRY_SCALAR_FIELDS = ['deviceId', 'serialNumber', 'customer', 'name', 'orgUnitId', 'orgUnitPath']
|
CROS_TELEMETRY_SCALAR_FIELDS = ['deviceId', 'serialNumber', 'customer', 'name', 'orgUnitId', 'orgUnitPath']
|
||||||
@@ -25880,7 +25901,7 @@ CROS_TELEMETRY_TIME_OBJECTS = {'reportTime', 'lastUpdateTime', 'lastUpdateCheckT
|
|||||||
# gam print crostelemetry [todrive <ToDriveAttribute>*]
|
# gam print crostelemetry [todrive <ToDriveAttribute>*]
|
||||||
# [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
# [(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
||||||
# <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
# <CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
||||||
# [reverselists <CrOSTelemetryListFieldNameList>]
|
# [reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
|
||||||
# [start <Date>] [end <Date>] [listlimit <Number>]
|
# [start <Date>] [end <Date>] [listlimit <Number>]
|
||||||
# [formatjson [quotechar <Character>]]
|
# [formatjson [quotechar <Character>]]
|
||||||
def doInfoPrintShowCrOSTelemetry():
|
def doInfoPrintShowCrOSTelemetry():
|
||||||
@@ -25921,13 +25942,32 @@ def doInfoPrintShowCrOSTelemetry():
|
|||||||
|
|
||||||
def _printDevice(device):
|
def _printDevice(device):
|
||||||
_cleanDevice(device)
|
_cleanDevice(device)
|
||||||
if not FJQC.formatJSON:
|
if FJQC.formatJSON:
|
||||||
csvPF.WriteRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS))
|
|
||||||
else:
|
|
||||||
if (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)):
|
if (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)):
|
||||||
csvPF.WriteRowNoFilter({'deviceId': device['deviceId'],
|
csvPF.WriteRowNoFilter({'deviceId': device['deviceId'],
|
||||||
'JSON': json.dumps(cleanJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS),
|
'JSON': json.dumps(cleanJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS),
|
||||||
ensure_ascii=False, sort_keys=True)})
|
ensure_ascii=False, sort_keys=True)})
|
||||||
|
return
|
||||||
|
if not oneItemPerRow:
|
||||||
|
csvPF.WriteRowTitles(flattenJSON(device, timeObjects=CROS_TELEMETRY_TIME_OBJECTS))
|
||||||
|
return
|
||||||
|
listLens = {}
|
||||||
|
maxLen = 0
|
||||||
|
for field in CROS_TELEMETRY_LIST_FIELDS_CHOICE_MAP.values():
|
||||||
|
if field in device:
|
||||||
|
listLens[field] = len(device[field])
|
||||||
|
if listLens[field] > maxLen:
|
||||||
|
maxLen = listLens[field]
|
||||||
|
baserow = {}
|
||||||
|
for field in CROS_TELEMETRY_SCALAR_FIELDS:
|
||||||
|
if field in device:
|
||||||
|
baserow[field] = device[field]
|
||||||
|
for i in range(maxLen):
|
||||||
|
row = baserow.copy()
|
||||||
|
for field, fieldLen in listLens.items():
|
||||||
|
if i < fieldLen:
|
||||||
|
flattenJSON({field: device[field][i]}, flattened=row, timeObjects=CROS_TELEMETRY_TIME_OBJECTS)
|
||||||
|
csvPF.WriteRowTitles(row)
|
||||||
|
|
||||||
def _showDevice(device, i=0, count=0):
|
def _showDevice(device, i=0, count=0):
|
||||||
_cleanDevice(device)
|
_cleanDevice(device)
|
||||||
@@ -25954,11 +25994,12 @@ def doInfoPrintShowCrOSTelemetry():
|
|||||||
Act.Set(Act.SHOW)
|
Act.Set(Act.SHOW)
|
||||||
else:
|
else:
|
||||||
pfilters = []
|
pfilters = []
|
||||||
csvPF = CSVPrintFile(['deviceId'], CROS_TELEMETRY_SCALAR_FIELDS, CROS_TELEMETRY_LIST_FIELDS) if Act.csvFormat() else None
|
csvPF = CSVPrintFile(['deviceId'], CROS_TELEMETRY_SCALAR_FIELDS) if Act.csvFormat() else None
|
||||||
FJQC = FormatJSONQuoteChar(csvPF)
|
FJQC = FormatJSONQuoteChar(csvPF)
|
||||||
diskPercentOnly = showOrgUnitPath = False
|
diskPercentOnly = showOrgUnitPath = False
|
||||||
listLimit = 0
|
listLimit = 0
|
||||||
startTime = endTime = None
|
startTime = endTime = None
|
||||||
|
oneItemPerRow = False
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if csvPF and myarg == 'todrive':
|
if csvPF and myarg == 'todrive':
|
||||||
@@ -26014,6 +26055,8 @@ def doInfoPrintShowCrOSTelemetry():
|
|||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
elif myarg == 'storagepercentonly':
|
elif myarg == 'storagepercentonly':
|
||||||
diskPercentOnly = True
|
diskPercentOnly = True
|
||||||
|
elif csvPF and myarg == 'oneitemperrow':
|
||||||
|
oneItemPerRow = True
|
||||||
else:
|
else:
|
||||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||||
if fieldsList:
|
if fieldsList:
|
||||||
@@ -26025,6 +26068,8 @@ def doInfoPrintShowCrOSTelemetry():
|
|||||||
readMask = ','.join(set(fieldsList))
|
readMask = ','.join(set(fieldsList))
|
||||||
if csvPF and FJQC.formatJSON:
|
if csvPF and FJQC.formatJSON:
|
||||||
csvPF.SetJSONTitles(['deviceId', 'JSON'])
|
csvPF.SetJSONTitles(['deviceId', 'JSON'])
|
||||||
|
elif csvPF and not oneItemPerRow:
|
||||||
|
csvPF.SetIndexedTitles(CROS_TELEMETRY_LIST_FIELDS)
|
||||||
if not pfilters:
|
if not pfilters:
|
||||||
pfilters = [(None, 'All')]
|
pfilters = [(None, 'All')]
|
||||||
for pfilter in pfilters:
|
for pfilter in pfilters:
|
||||||
@@ -29161,24 +29206,37 @@ def infoChatMessage(users):
|
|||||||
def doInfoChatMessage():
|
def doInfoChatMessage():
|
||||||
infoChatMessage([None])
|
infoChatMessage([None])
|
||||||
|
|
||||||
|
CHAT_MESSAGES_ORDERBY_CHOICE_MAP = {
|
||||||
|
'createtime': 'createTime'
|
||||||
|
}
|
||||||
|
|
||||||
# gam <UserTypeEntity> show chatmessages
|
# gam <UserTypeEntity> show chatmessages
|
||||||
# <ChatSpace>+
|
# <ChatSpace>+
|
||||||
# [showdeleted [<Boolean>]] [filter <String>]
|
# [showdeleted [<Boolean>]]
|
||||||
|
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
# [thread <ChatThread>])
|
||||||
# [fields <ChatMessageFieldNameList>]
|
# [fields <ChatMessageFieldNameList>]
|
||||||
|
# [orderby createtime [ascending|descending]]
|
||||||
# [formatjson]
|
# [formatjson]
|
||||||
# gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
# gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
||||||
# <ChatSpace>+
|
# <ChatSpace>+
|
||||||
# [showdeleted [<Boolean>]] [filter <String>]
|
# [showdeleted [<Boolean>]] [filter <String>]
|
||||||
|
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
# [thread <ChatThread>])
|
||||||
# [fields <ChatMessageFieldNameList>]
|
# [fields <ChatMessageFieldNameList>]
|
||||||
|
# [orderby createtime [ascending|descending]]
|
||||||
# [formatjson [quotechar <Character>]]
|
# [formatjson [quotechar <Character>]]
|
||||||
def printShowChatMessages(users):
|
def printShowChatMessages(users):
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
|
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
|
||||||
FJQC = FormatJSONQuoteChar(csvPF)
|
FJQC = FormatJSONQuoteChar(csvPF)
|
||||||
|
OBY = OrderBy(CHAT_MESSAGES_ORDERBY_CHOICE_MAP, ascendingKeyword='ASC', descendingKeyword='DESC')
|
||||||
fieldsList = []
|
fieldsList = []
|
||||||
pfilter = None
|
pfilter = None
|
||||||
parentList = []
|
parentList = []
|
||||||
showDeleted = False
|
showDeleted = False
|
||||||
|
startEndTime = StartEndTime()
|
||||||
|
threadName = ''
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if csvPF and myarg == 'todrive':
|
if csvPF and myarg == 'todrive':
|
||||||
@@ -29191,10 +29249,35 @@ def printShowChatMessages(users):
|
|||||||
showDeleted = getBoolean()
|
showDeleted = getBoolean()
|
||||||
elif myarg =='filter':
|
elif myarg =='filter':
|
||||||
pfilter = getString(Cmd.OB_STRING)
|
pfilter = getString(Cmd.OB_STRING)
|
||||||
|
elif myarg in {'start', 'starttime', 'end', 'endtime', 'range'}:
|
||||||
|
startEndTime.Get(myarg)
|
||||||
|
elif myarg == 'thread':
|
||||||
|
threadName = getString(Cmd.OB_CHAT_THREAD)
|
||||||
|
elif myarg == 'orderby':
|
||||||
|
OBY.GetChoice()
|
||||||
else:
|
else:
|
||||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||||
if not parentList:
|
if not parentList:
|
||||||
missingArgumentExit('space')
|
missingArgumentExit('space')
|
||||||
|
if startEndTime.startDateTime is not None or startEndTime.endDateTime is not None:
|
||||||
|
if pfilter:
|
||||||
|
pfilter += ' AND '
|
||||||
|
else:
|
||||||
|
pfilter = ''
|
||||||
|
pfilter += '('
|
||||||
|
if startEndTime.startDateTime is not None:
|
||||||
|
pfilter += f'createTime > "{startEndTime.startDateTime}"'
|
||||||
|
if startEndTime.endDateTime is not None:
|
||||||
|
pfilter += ' AND '
|
||||||
|
if startEndTime.endDateTime is not None:
|
||||||
|
pfilter += f'createTime < "{startEndTime.endDateTime}"'
|
||||||
|
pfilter += ')'
|
||||||
|
if threadName:
|
||||||
|
if pfilter:
|
||||||
|
pfilter += ' AND '
|
||||||
|
else:
|
||||||
|
pfilter = ''
|
||||||
|
pfilter += f'thread.name = {threadName}'
|
||||||
chatSenders = {}
|
chatSenders = {}
|
||||||
fields = getItemFieldsFromFieldsList('messages', fieldsList)
|
fields = getItemFieldsFromFieldsList('messages', fieldsList)
|
||||||
i, count, users = getEntityArgument(users)
|
i, count, users = getEntityArgument(users)
|
||||||
@@ -29225,7 +29308,8 @@ def printShowChatMessages(users):
|
|||||||
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter),
|
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter),
|
||||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||||
pageSize=GC.Values[GC.CHAT_MAX_RESULTS], parent=parentName, filter=pfilter, showDeleted=showDeleted,
|
pageSize=GC.Values[GC.CHAT_MAX_RESULTS], parent=parentName,
|
||||||
|
filter=pfilter, showDeleted=showDeleted, orderBy=OBY.orderBy,
|
||||||
fields=fields)
|
fields=fields)
|
||||||
for message in messages:
|
for message in messages:
|
||||||
if 'sender' in message:
|
if 'sender' in message:
|
||||||
@@ -29256,6 +29340,183 @@ def printShowChatMessages(users):
|
|||||||
if csvPF:
|
if csvPF:
|
||||||
csvPF.writeCSVfile('Chat Messages')
|
csvPF.writeCSVfile('Chat Messages')
|
||||||
|
|
||||||
|
def _getChatSpaceDisplayName(chat, space, chatSpaces):
|
||||||
|
spaceName = space['name']
|
||||||
|
if spaceName not in chatSpaces:
|
||||||
|
try:
|
||||||
|
result = callGAPI(chat.spaces(), 'get',
|
||||||
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||||
|
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||||
|
name=spaceName, fields='displayName')
|
||||||
|
spaceDisplayName = result.get('displayName', 'None')
|
||||||
|
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied, GAPI.failedPrecondition):
|
||||||
|
spaceDisplayName = 'None'
|
||||||
|
chatSpaces[spaceName] = spaceDisplayName
|
||||||
|
space['displayName'] = chatSpaces[spaceName]
|
||||||
|
|
||||||
|
CHAT_SEARCHMESSAGES_ORDERBY_CHOICE_MAP = {
|
||||||
|
'createtime': 'createTime',
|
||||||
|
'relevance': 'relevance',
|
||||||
|
}
|
||||||
|
CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP = {'basic': 'SEARCH_MESSAGES_VIEW_BASIC', 'full': 'SEARCH_MESSAGES_VIEW_FULL'}
|
||||||
|
|
||||||
|
# gam <UserTypeEntity> show chatsearchmessages
|
||||||
|
# keywords <StringList>
|
||||||
|
# <ChatSpace>*
|
||||||
|
# [displaynames [all|any] <StringList>]
|
||||||
|
# [senders <EmailAddressEntity>]*
|
||||||
|
# [usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
# [hasattachment [<Boolean>]]
|
||||||
|
# [fields <ChatMessageFieldNameList>]
|
||||||
|
# [orderby createtime|relevance]
|
||||||
|
# [basic|full]
|
||||||
|
# [formatjson]
|
||||||
|
# gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
|
||||||
|
# keywords <StringList>
|
||||||
|
# <ChatSpace>*
|
||||||
|
# [displaynames [all|any] <StringList>]
|
||||||
|
# [senders <EmailAddressEntity>]*
|
||||||
|
# [usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
# [([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
# [hasattachment [<Boolean>]]
|
||||||
|
# [fields <ChatMessageFieldNameList>]
|
||||||
|
# [orderby createtime|relevance]
|
||||||
|
# [basic|full]
|
||||||
|
# [formatjson [quotechar <Character>]]
|
||||||
|
def printShowChatSearchMessages(users):
|
||||||
|
if API.CHAT not in GM.Globals[GM.DEVELOPER_PREVIEW_APIS]:
|
||||||
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||||
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
|
csvPF = CSVPrintFile(['User', 'space.name', 'space.displayName', 'name']) if Act.csvFormat() else None
|
||||||
|
FJQC = FormatJSONQuoteChar(csvPF)
|
||||||
|
orderBy = None
|
||||||
|
fieldsList = []
|
||||||
|
keywordList = []
|
||||||
|
spaceList = []
|
||||||
|
displayNameConjunction = ''
|
||||||
|
displayNameList = []
|
||||||
|
senderList = []
|
||||||
|
userMentionList = []
|
||||||
|
startEndTime = StartEndTime()
|
||||||
|
hasAttachment = False
|
||||||
|
body = {'view': CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP['basic'],
|
||||||
|
'pageSize': GC.Values[GC.CHAT_MAX_RESULTS], 'pageToken': None}
|
||||||
|
parent = 'spaces/-'
|
||||||
|
while Cmd.ArgumentsRemaining():
|
||||||
|
myarg = getArgument()
|
||||||
|
if csvPF and myarg == 'todrive':
|
||||||
|
csvPF.GetTodriveParameters()
|
||||||
|
elif myarg =='keywords':
|
||||||
|
keywordList = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
||||||
|
elif myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'):
|
||||||
|
spaceList.append(getSpaceName(myarg))
|
||||||
|
elif myarg == 'displaynames':
|
||||||
|
displayNameConjunction = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True, defaultChoice='OR')
|
||||||
|
displayNameList = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
||||||
|
elif myarg == 'senders':
|
||||||
|
senderList.extend(getNormalizedEmailAddressEntity(noUid=False))
|
||||||
|
elif myarg == 'usermentions':
|
||||||
|
userMentionConjunction = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True, defaultChoice='OR')
|
||||||
|
userMentionList.extend(getNormalizedEmailAddressEntity(noUid=False))
|
||||||
|
elif myarg in {'start', 'starttime', 'end', 'endtime`', 'range'}:
|
||||||
|
startEndTime.Get(myarg)
|
||||||
|
elif myarg == 'hasattachment':
|
||||||
|
hasAttachment = True
|
||||||
|
elif myarg == 'orderby':
|
||||||
|
orderBy = getChoice(CHAT_SEARCHMESSAGES_ORDERBY_CHOICE_MAP, mapChoice=True)
|
||||||
|
elif myarg in CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP:
|
||||||
|
body['view'] = CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP[myarg]
|
||||||
|
elif getFieldsList(myarg, CHAT_MESSAGES_FIELDS_CHOICE_MAP, fieldsList, initialField='name', onlyFieldsArg=True):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||||
|
if not keywordList:
|
||||||
|
missingArgumentExit('keywords')
|
||||||
|
if orderBy is not None:
|
||||||
|
body['orderBy'] = f'{orderBy} desc'
|
||||||
|
body['filter'] = f'({" ".join(keywordList)})'
|
||||||
|
if spaceList:
|
||||||
|
body['filter'] += ' AND ('
|
||||||
|
for space in spaceList:
|
||||||
|
body['filter'] += f'space.name = "{space}" OR '
|
||||||
|
body['filter'] = body['filter'][:-4] + ')'
|
||||||
|
if displayNameList:
|
||||||
|
body['filter'] += ' AND ('
|
||||||
|
for displayName in displayNameList:
|
||||||
|
body['filter'] += f'space.display_name:{displayName}" {displayNameConjunction} '
|
||||||
|
body['filter'] = body['filter'][:-(len(displayNameConjunction)+2)] + ')'
|
||||||
|
if senderList:
|
||||||
|
body['filter'] += ' AND ('
|
||||||
|
for sender in senderList:
|
||||||
|
body['filter'] += f'sender.name = "users/{sender}" OR '
|
||||||
|
body['filter'] = body['filter'][:-4] + ')'
|
||||||
|
if userMentionList:
|
||||||
|
body['filter'] += ' AND ('
|
||||||
|
for userMention in userMentionList:
|
||||||
|
body['filter'] += f'annotations.user_mentions.user.name:"users/{userMention}" {userMentionConjunction} '
|
||||||
|
body['filter'] = body['filter'][:-(len(userMentionConjunction)+2)] + ')'
|
||||||
|
if startEndTime.startDateTime is not None or startEndTime.endDateTime is not None:
|
||||||
|
body['filter'] += ' AND ('
|
||||||
|
if startEndTime.startDateTime is not None:
|
||||||
|
body['filter'] += f'createTime >= "{startEndTime.startDateTime}"'
|
||||||
|
if startEndTime.endDateTime is not None:
|
||||||
|
body['filter'] += ' AND '
|
||||||
|
if startEndTime.endDateTime is not None:
|
||||||
|
body['filter'] += f'createTime < "{startEndTime.endDateTime}"'
|
||||||
|
body['filter'] += ')'
|
||||||
|
if hasAttachment:
|
||||||
|
body['filter'] += ' AND attachment:*'
|
||||||
|
chatSenders = {}
|
||||||
|
chatSpaces = {}
|
||||||
|
fields = getItemFieldsFromFieldsList('results(message', fieldsList)
|
||||||
|
if fields:
|
||||||
|
fields += ')'
|
||||||
|
i, count, users = getEntityArgument(users)
|
||||||
|
for user in users:
|
||||||
|
i += 1
|
||||||
|
user, chat, kvList = buildChatServiceObject(API.CHAT_MESSAGES, user, i, count, [Ent.CHAT_SPACE, None])
|
||||||
|
if not chat:
|
||||||
|
continue
|
||||||
|
_, chatsp, _ = buildChatServiceObject(API.CHAT_SPACES, user, i, count, [Ent.CHAT_SPACE, None])
|
||||||
|
if not chat:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
results = callGAPIpages(chat.spaces().messages(), 'search', 'results',
|
||||||
|
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, body['filter']),
|
||||||
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||||
|
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||||
|
parent='spaces/-', body=body, fields=fields, pageArgsInBody=True)
|
||||||
|
for result in results:
|
||||||
|
if 'sender' in result['message']:
|
||||||
|
_getChatSenderEmail(cd, result['message']['sender'], chatSenders)
|
||||||
|
if 'space' in result['message']:
|
||||||
|
_getChatSpaceDisplayName(chatsp, result['message']['space'], chatSpaces)
|
||||||
|
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||||
|
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||||
|
continue
|
||||||
|
except GAPI.failedPrecondition:
|
||||||
|
userChatServiceNotEnabledWarning(user, i, count)
|
||||||
|
break
|
||||||
|
if not csvPF:
|
||||||
|
jcount = len(results)
|
||||||
|
if not FJQC.formatJSON:
|
||||||
|
entityPerformActionNumItems(kvList, jcount, Ent.CHAT_MESSAGE, i, count)
|
||||||
|
Ind.Increment()
|
||||||
|
j = 0
|
||||||
|
for result in results:
|
||||||
|
j += 1
|
||||||
|
_showChatItem(result['message'], Ent.CHAT_MESSAGE, FJQC, j, jcount)
|
||||||
|
Ind.Decrement()
|
||||||
|
elif results:
|
||||||
|
for result in results:
|
||||||
|
_printChatItem(user, result['message'], parent, Ent.CHAT_MESSAGE, csvPF, FJQC)
|
||||||
|
elif GC.Values[GC.CSV_OUTPUT_USERS_AUDIT]:
|
||||||
|
csvPF.WriteRowNoFilter({'User': user})
|
||||||
|
if csvPF:
|
||||||
|
csvPF.writeCSVfile('Chat Messages')
|
||||||
|
|
||||||
# gam <UserTypeEntity> info chatevent name <ChatEvent>
|
# gam <UserTypeEntity> info chatevent name <ChatEvent>
|
||||||
# [formatjson]
|
# [formatjson]
|
||||||
def infoChatEvent(users):
|
def infoChatEvent(users):
|
||||||
@@ -47013,7 +47274,9 @@ USER_SCALAR_PROPERTY_PRINT_ORDER = [
|
|||||||
'ipWhitelisted',
|
'ipWhitelisted',
|
||||||
'suspended',
|
'suspended',
|
||||||
'suspensionReason',
|
'suspensionReason',
|
||||||
|
'suspensionTime',
|
||||||
'archived',
|
'archived',
|
||||||
|
'archivalTime',
|
||||||
'changePasswordAtNextLogin',
|
'changePasswordAtNextLogin',
|
||||||
'id',
|
'id',
|
||||||
'customerId',
|
'customerId',
|
||||||
@@ -47104,7 +47367,7 @@ USER_FIELDS_CHOICE_MAP = {
|
|||||||
'agreed2terms': 'agreedToTerms',
|
'agreed2terms': 'agreedToTerms',
|
||||||
'agreedtoterms': 'agreedToTerms',
|
'agreedtoterms': 'agreedToTerms',
|
||||||
'aliases': ['aliases', 'nonEditableAliases'],
|
'aliases': ['aliases', 'nonEditableAliases'],
|
||||||
'archived': 'archived',
|
'archived': ['archived', 'archivalTime'],
|
||||||
'changepassword': 'changePasswordAtNextLogin',
|
'changepassword': 'changePasswordAtNextLogin',
|
||||||
'changepasswordatnextlogin': 'changePasswordAtNextLogin',
|
'changepasswordatnextlogin': 'changePasswordAtNextLogin',
|
||||||
'creationtime': 'creationTime',
|
'creationtime': 'creationTime',
|
||||||
@@ -47174,7 +47437,7 @@ USER_FIELDS_CHOICE_MAP = {
|
|||||||
'ssh': 'sshPublicKeys',
|
'ssh': 'sshPublicKeys',
|
||||||
'sshkeys': 'sshPublicKeys',
|
'sshkeys': 'sshPublicKeys',
|
||||||
'sshpublickeys': 'sshPublicKeys',
|
'sshpublickeys': 'sshPublicKeys',
|
||||||
'suspended': ['suspended', 'suspensionReason'],
|
'suspended': ['suspended', 'suspensionReason', 'suspensionTime'],
|
||||||
'thumbnailphotourl': 'thumbnailPhotoUrl',
|
'thumbnailphotourl': 'thumbnailPhotoUrl',
|
||||||
'username': 'primaryEmail',
|
'username': 'primaryEmail',
|
||||||
'website': 'websites',
|
'website': 'websites',
|
||||||
@@ -47210,7 +47473,7 @@ USER_MULTI_ATTR_FILTER_CHOICE_MAP = {
|
|||||||
|
|
||||||
INFO_USER_OPTIONS = {'noaliases', 'nobuildingnames', 'nogroups', 'nolicenses', 'nolicences', 'noschemas', 'schemas', 'userview'}
|
INFO_USER_OPTIONS = {'noaliases', 'nobuildingnames', 'nogroups', 'nolicenses', 'nolicences', 'noschemas', 'schemas', 'userview'}
|
||||||
USER_SKIP_OBJECTS = {'thumbnailPhotoEtag'}
|
USER_SKIP_OBJECTS = {'thumbnailPhotoEtag'}
|
||||||
USER_TIME_OBJECTS = {'creationTime', 'deletionTime', 'lastLoginTime'}
|
USER_TIME_OBJECTS = {'creationTime', 'deletionTime', 'lastLoginTime', 'suspensionTime', 'archivalTime'}
|
||||||
|
|
||||||
def _getUserMultiAttributeFilters(myarg, userMultiAttributeFilters):
|
def _getUserMultiAttributeFilters(myarg, userMultiAttributeFilters):
|
||||||
up = getChoice(USER_MULTI_ATTR_FILTER_CHOICE_MAP, mapChoice=True)
|
up = getChoice(USER_MULTI_ATTR_FILTER_CHOICE_MAP, mapChoice=True)
|
||||||
@@ -80168,17 +80431,12 @@ def CAABuildCondition():
|
|||||||
unknownArgumentExit()
|
unknownArgumentExit()
|
||||||
return condition
|
return condition
|
||||||
|
|
||||||
CAA_COMBINING_FUNCTIONS_MAP = {
|
|
||||||
'and': 'AND',
|
|
||||||
'or': 'OR',
|
|
||||||
}
|
|
||||||
|
|
||||||
def CAABuildBasicLevel():
|
def CAABuildBasicLevel():
|
||||||
basic_level = {'conditions': []}
|
basic_level = {'conditions': []}
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if myarg == 'combiningfunction':
|
if myarg == 'combiningfunction':
|
||||||
basic_level['combiningFunction'] = getChoice(CAA_COMBINING_FUNCTIONS_MAP, mapChoice=True)
|
basic_level['combiningFunction'] = getChoice(AND_OR_CONJUNCTION_MAP, mapChoice=True)
|
||||||
elif myarg == 'condition':
|
elif myarg == 'condition':
|
||||||
basic_level['conditions'].append(CAABuildCondition())
|
basic_level['conditions'].append(CAABuildCondition())
|
||||||
else:
|
else:
|
||||||
@@ -81699,6 +81957,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
|||||||
Cmd.ARG_CHATEVENT: printShowChatEvents,
|
Cmd.ARG_CHATEVENT: printShowChatEvents,
|
||||||
Cmd.ARG_CHATMEMBER: printShowChatMembers,
|
Cmd.ARG_CHATMEMBER: printShowChatMembers,
|
||||||
Cmd.ARG_CHATMESSAGE: printShowChatMessages,
|
Cmd.ARG_CHATMESSAGE: printShowChatMessages,
|
||||||
|
Cmd.ARG_CHATSEARCHMESSAGE: printShowChatSearchMessages,
|
||||||
Cmd.ARG_CHATSECTION: printShowChatSections,
|
Cmd.ARG_CHATSECTION: printShowChatSections,
|
||||||
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
|
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
|
||||||
Cmd.ARG_CHATSPACE: printShowChatSpaces,
|
Cmd.ARG_CHATSPACE: printShowChatSpaces,
|
||||||
@@ -81817,6 +82076,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
|||||||
Cmd.ARG_CHATEVENT: printShowChatEvents,
|
Cmd.ARG_CHATEVENT: printShowChatEvents,
|
||||||
Cmd.ARG_CHATMEMBER: printShowChatMembers,
|
Cmd.ARG_CHATMEMBER: printShowChatMembers,
|
||||||
Cmd.ARG_CHATMESSAGE: printShowChatMessages,
|
Cmd.ARG_CHATMESSAGE: printShowChatMessages,
|
||||||
|
Cmd.ARG_CHATSEARCHMESSAGE: printShowChatSearchMessages,
|
||||||
Cmd.ARG_CHATSECTION: printShowChatSections,
|
Cmd.ARG_CHATSECTION: printShowChatSections,
|
||||||
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
|
Cmd.ARG_CHATSECTIONITEM: printShowChatSectionItems,
|
||||||
Cmd.ARG_CHATSPACE: printShowChatSpaces,
|
Cmd.ARG_CHATSPACE: printShowChatSpaces,
|
||||||
@@ -82045,6 +82305,7 @@ USER_COMMANDS_OBJ_ALIASES = {
|
|||||||
Cmd.ARG_CHATEVENTS: Cmd.ARG_CHATEVENT,
|
Cmd.ARG_CHATEVENTS: Cmd.ARG_CHATEVENT,
|
||||||
Cmd.ARG_CHATMEMBERS: Cmd.ARG_CHATMEMBER,
|
Cmd.ARG_CHATMEMBERS: Cmd.ARG_CHATMEMBER,
|
||||||
Cmd.ARG_CHATMESSAGES: Cmd.ARG_CHATMESSAGE,
|
Cmd.ARG_CHATMESSAGES: Cmd.ARG_CHATMESSAGE,
|
||||||
|
Cmd.ARG_CHATSEARCHMESSAGES: Cmd.ARG_CHATSEARCHMESSAGE,
|
||||||
Cmd.ARG_CHATSECTIONS: Cmd.ARG_CHATSECTION,
|
Cmd.ARG_CHATSECTIONS: Cmd.ARG_CHATSECTION,
|
||||||
Cmd.ARG_CHATSECTIONITEMS: Cmd.ARG_CHATSECTIONITEM,
|
Cmd.ARG_CHATSECTIONITEMS: Cmd.ARG_CHATSECTIONITEM,
|
||||||
Cmd.ARG_CHATSPACES: Cmd.ARG_CHATSPACE,
|
Cmd.ARG_CHATSPACES: Cmd.ARG_CHATSPACE,
|
||||||
|
|||||||
@@ -846,6 +846,8 @@ class GamCLArgs():
|
|||||||
ARG_CHATMEMBERS = 'chatmembers'
|
ARG_CHATMEMBERS = 'chatmembers'
|
||||||
ARG_CHATMESSAGE = 'chatmessage'
|
ARG_CHATMESSAGE = 'chatmessage'
|
||||||
ARG_CHATMESSAGES = 'chatmessages'
|
ARG_CHATMESSAGES = 'chatmessages'
|
||||||
|
ARG_CHATSEARCHMESSAGE = 'chatsearchmessage'
|
||||||
|
ARG_CHATSEARCHMESSAGES = 'chatsearchmessages'
|
||||||
ARG_CHATSECTION = 'chatsection'
|
ARG_CHATSECTION = 'chatsection'
|
||||||
ARG_CHATSECTIONS = 'chatsections'
|
ARG_CHATSECTIONS = 'chatsections'
|
||||||
ARG_CHATSECTIONITEM = 'chatsectionitem'
|
ARG_CHATSECTIONITEM = 'chatsectionitem'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (C) 2025 Ross Scroggs All Rights Reserved.
|
# Copyright (C) 2026 Ross Scroggs All Rights Reserved.
|
||||||
#
|
#
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
# Products/SKUs
|
# Products/SKUs
|
||||||
_PRODUCTS = {
|
_PRODUCTS = {
|
||||||
'101001': 'Cloud Identity',
|
'101001': 'Cloud Identity Free',
|
||||||
'101005': 'Cloud Identity Premium',
|
'101005': 'Cloud Identity Premium',
|
||||||
'101031': 'Google Workspace for Education',
|
'101031': 'Google Workspace for Education',
|
||||||
'101033': 'Google Voice',
|
'101033': 'Google Voice',
|
||||||
@@ -44,7 +44,7 @@ _PRODUCTS = {
|
|||||||
}
|
}
|
||||||
_SKUS = {
|
_SKUS = {
|
||||||
'1010010001': {
|
'1010010001': {
|
||||||
'product': '101001', 'aliases': ['identity', 'cloudidentity'], 'displayName': 'Cloud Identity'},
|
'product': '101001', 'aliases': ['identity', 'cloudidentity', 'cloudidentityfree'], 'displayName': 'Cloud Identity Free'},
|
||||||
'1010050001': {
|
'1010050001': {
|
||||||
'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'},
|
'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'},
|
||||||
'1010070001': {
|
'1010070001': {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (C) 2023 Ross Scroggs All Rights Reserved.
|
# Copyright (C) 2026 Ross Scroggs All Rights Reserved.
|
||||||
#
|
#
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
@@ -145,10 +145,14 @@ PROPERTIES = {
|
|||||||
{CLASS: PC_BOOLEAN, TITLE: 'IP Whitelisted',},
|
{CLASS: PC_BOOLEAN, TITLE: 'IP Whitelisted',},
|
||||||
'archived':
|
'archived':
|
||||||
{CLASS: PC_BOOLEAN, TITLE: 'Is Archived',},
|
{CLASS: PC_BOOLEAN, TITLE: 'Is Archived',},
|
||||||
|
'archivalTime':
|
||||||
|
{CLASS: PC_TIME, TITLE: 'Archival Time',},
|
||||||
'suspended':
|
'suspended':
|
||||||
{CLASS: PC_BOOLEAN, TITLE: 'Account Suspended',},
|
{CLASS: PC_BOOLEAN, TITLE: 'Account Suspended',},
|
||||||
'suspensionReason':
|
'suspensionReason':
|
||||||
{CLASS: PC_STRING, TITLE: 'Suspension Reason',},
|
{CLASS: PC_STRING, TITLE: 'Suspension Reason',},
|
||||||
|
'suspensionTime':
|
||||||
|
{CLASS: PC_TIME, TITLE: 'Suspension Time',},
|
||||||
'changePasswordAtNextLogin':
|
'changePasswordAtNextLogin':
|
||||||
{CLASS: PC_BOOLEAN, TITLE: 'Must Change Password',},
|
{CLASS: PC_BOOLEAN, TITLE: 'Must Change Password',},
|
||||||
'recoveryEmail':
|
'recoveryEmail':
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ gam oauth create
|
|||||||
autoupdateexpiration|
|
autoupdateexpiration|
|
||||||
autoupdatethrough|
|
autoupdatethrough|
|
||||||
backlightinfo|
|
backlightinfo|
|
||||||
|
bluetoothadapterinfo|
|
||||||
bootmode|
|
bootmode|
|
||||||
chromeostype|
|
chromeostype|
|
||||||
cpuinfo|
|
cpuinfo|
|
||||||
@@ -131,6 +132,7 @@ gam oauth create
|
|||||||
orgunitpath|org|ou|
|
orgunitpath|org|ou|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
osversion|
|
osversion|
|
||||||
|
osversioncompliance|
|
||||||
platformversion|
|
platformversion|
|
||||||
recentusers|
|
recentusers|
|
||||||
screenshotfiles|
|
screenshotfiles|
|
||||||
@@ -185,25 +187,30 @@ gam oauth create
|
|||||||
<CrOSActivityListFieldNameList> ::= "<CrOSActivityListFieldName>(,<CrOSActivityListFieldName>)*"
|
<CrOSActivityListFieldNameList> ::= "<CrOSActivityListFieldName>(,<CrOSActivityListFieldName>)*"
|
||||||
|
|
||||||
<CrOSTelemetryFieldName> ::=
|
<CrOSTelemetryFieldName> ::=
|
||||||
|
appreport|
|
||||||
audiostatusreport|
|
audiostatusreport|
|
||||||
batteryinfo|
|
batteryinfo|
|
||||||
batterystatusreport|
|
batterystatusreport|
|
||||||
bootPerformancereport|
|
bootperformancereport|
|
||||||
cpuinfo|
|
cpuinfo|
|
||||||
cpustatusreport|
|
cpustatusreport|
|
||||||
customer|
|
customer|
|
||||||
deviceid|
|
deviceid|
|
||||||
graphicsinfo|
|
graphicsinfo|
|
||||||
graphicsstatusreport|
|
graphicsstatusreport|
|
||||||
|
heartbeatstatusreport|
|
||||||
|
kioskappstatusreport|
|
||||||
memoryinfo|
|
memoryinfo|
|
||||||
memorystatusreport|
|
memorystatusreport|
|
||||||
name|
|
name|
|
||||||
|
networkbandwidthreport|
|
||||||
networkdiagnosticsreport|
|
networkdiagnosticsreport|
|
||||||
networkinfo|
|
networkinfo|
|
||||||
networkstatusreport|
|
networkstatusreport|
|
||||||
orgunitid|
|
orgunitid|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
peripheralsreport|
|
peripheralsreport|
|
||||||
|
runtimecountersreport|
|
||||||
serialnumber|
|
serialnumber|
|
||||||
storageinfo|
|
storageinfo|
|
||||||
storagestatusreport|
|
storagestatusreport|
|
||||||
@@ -211,20 +218,22 @@ gam oauth create
|
|||||||
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
|
<CrOSTelemetryFieldNameList> ::= "<CrOSTelemetryFieldName>(,<CrOSTelemetryFieldName>)*"
|
||||||
|
|
||||||
<CrOSTelemetryListFieldName> ::=
|
<CrOSTelemetryListFieldName> ::=
|
||||||
|
appreport|
|
||||||
audiostatusreport|
|
audiostatusreport|
|
||||||
batteryinfo|
|
|
||||||
batterystatusreport|
|
batterystatusreport|
|
||||||
bootperformancereport|
|
bootperformancereport|
|
||||||
cpuinfo|
|
|
||||||
cpustatusreport|
|
cpustatusreport|
|
||||||
graphicsstatusreport|
|
graphicsstatusreport|
|
||||||
|
heartbeatstatusreport|
|
||||||
|
kioskappstatusreport|
|
||||||
memorystatusreport|
|
memorystatusreport|
|
||||||
|
networkbandwidthreport|
|
||||||
networkdiagnosticsreport|
|
networkdiagnosticsreport|
|
||||||
networkstatusreport|
|
networkstatusreport|
|
||||||
osupdatestatus|
|
osupdatestatus|
|
||||||
peripheralsreport|
|
peripheralsreport|
|
||||||
storagestatusreport|
|
runtimecountersreport|
|
||||||
thunderboltinfo
|
storagestatusreport
|
||||||
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
|
<CrOSTelemetryListFieldNameList> ::= "<CrOSTelemetryListFieldName>(,<CrOSTelemetryLIstFieldName>)*"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -964,19 +973,21 @@ By default, Gam displays the information as an indented list of keys and values:
|
|||||||
gam print crostelemetry [todrive <ToDriveAttribute>*]
|
gam print crostelemetry [todrive <ToDriveAttribute>*]
|
||||||
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
|
||||||
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
|
||||||
[reverselists <CrOSTelemetryListFieldNameList>]
|
[reverselists <CrOSTelemetryListFieldNameList>] [oneitemperrow]
|
||||||
[start <Date>] [end <Date>] [listlimit <Number>]
|
[start <Date>] [end <Date>] [listlimit <Number>]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected.
|
Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected.
|
||||||
|
|
||||||
- `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
|
- `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
|
||||||
- `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
|
- `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
|
||||||
- `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`.
|
- `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`.
|
||||||
- `filter <String>` - Select the CrOS device with a filter.
|
- `filter <String>` - Select the CrOS device with a filter.
|
||||||
|
|
||||||
|
Use these options to limit/modify the displayed lists.
|
||||||
- `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit.
|
- `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit.
|
||||||
- `start <Date>` and `end <Date>` - Constrain list `reportTime` to fall within the specified `<Dates>`. If a `<Date>` isn't specified, there is no filtering in that range.
|
- `start <Date>` and `end <Date>` - Constrain list `reportTime` to fall within the specified `<Dates>`. If a `<Date>` isn't specified, there is no filtering in that range.
|
||||||
- `reverselists <CrOSTelemetryListFieldNameList>` - For each list, change order from ascending (oldest to newest) to descending (newest to oldest); this makes it easy to get the `N` most recent values with `listlimit N reverselists cpustatusreport,memorystatusreport`
|
- `reverselists <CrOSTelemetryListFieldNameList>` - For each list, change order from descending (newest to oldest) to ascending (oldest to newest)
|
||||||
|
- `oneitemrerrow` - Display each instance of a list item on a separate row; by default, all list items are displayed on a single row
|
||||||
|
|
||||||
By default, all telemetry data is displayed, use the following to select specific fields:
|
By default, all telemetry data is displayed, use the following to select specific fields:
|
||||||
- `<CrOSTelemetryFieldName>*` - Specify fields individually
|
- `<CrOSTelemetryFieldName>*` - Specify fields individually
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ Use this table to filter/query for specific device types:
|
|||||||
|
|
||||||
```
|
```
|
||||||
## Create a company device
|
## Create a company device
|
||||||
|
This method is available only to customers who have one of the following SKUs: Enterprise Standard, Enterprise Plus, Enterprise for Education, and Cloud Identity Premium.
|
||||||
|
|
||||||
Adds a new device to the Google company-owned inventory. Once a user is assigned and enrolled on the device the device will be considered company-owned for management purposes.
|
Adds a new device to the Google company-owned inventory. Once a user is assigned and enrolled on the device the device will be considered company-owned for management purposes.
|
||||||
The device will also register as company-owned with Google services like [Context-Aware Access (CAA)](https://support.google.com/a/answer/9275380).
|
The device will also register as company-owned with Google services like [Context-Aware Access (CAA)](https://support.google.com/a/answer/9275380).
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ In zsh, if an argument contains a `~`, `|`, `!`, `>`, or `<`, you must enclose t
|
|||||||
|
|
||||||
To embed a `'` in a string enclosed in `"`, enter `'`; `name "Test'Group"`.
|
To embed a `'` in a string enclosed in `"`, enter `'`; `name "Test'Group"`.
|
||||||
|
|
||||||
|
To embed a `"` in a string enclosed in `"`, enter `\"`; `name "Test\"Group"`.
|
||||||
|
|
||||||
To embed a `"` in a string enclosed in `'`, enter `"`; `name 'Test"Group'`.
|
To embed a `"` in a string enclosed in `'`, enter `"`; `name 'Test"Group'`.
|
||||||
|
|
||||||
To embed a `'` in a string enclosed in `'`, enter `'\''`; `name 'Test'\''Group'`.
|
To embed a `'` in a string enclosed in `'`, enter `'\''`; `name 'Test'\''Group'`.
|
||||||
|
|
||||||
To embed a `"` in a string enclosed in `"`, enter `\"`; `name "Test\"Group"`.
|
|
||||||
|
|
||||||
Linux and MacOS do not recognize smart or curly quotes, `“` and `”`, they can not be used to enclose arguments.
|
Linux and MacOS do not recognize smart or curly quotes, `“` and `”`, they can not be used to enclose arguments.
|
||||||
|
|
||||||
## Windows Command Prompt
|
## Windows Command Prompt
|
||||||
|
|||||||
@@ -10,6 +10,57 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
|||||||
|
|
||||||
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 7.44.02
|
||||||
|
|
||||||
|
Added fields `bluetoothadapterinfo` and `osversioncompliance` to `<CrOSFieldName>` for use
|
||||||
|
in `gam info|print cros`.
|
||||||
|
|
||||||
|
### 7.44.01
|
||||||
|
|
||||||
|
Added option `oneitemperrow` to `gam print crostelemetry` to have each of a device's
|
||||||
|
report field entries displayed on a separate row with all of the other device fields.
|
||||||
|
|
||||||
|
Added additional fields to `<CrOSTelemetryFieldName>`and `<CrOSTelemetryListFieldName>`:
|
||||||
|
```
|
||||||
|
appreport
|
||||||
|
heartbeatstatusreport
|
||||||
|
kioskappstatusreport
|
||||||
|
networkbandwidthreport
|
||||||
|
runtimecountersreport
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.44.00
|
||||||
|
|
||||||
|
Added support for User data `archivalTime` and `suspensionTime` that is available
|
||||||
|
when fields `archived` and `suspended` are requested in `gam info user` and `gam print users`.
|
||||||
|
|
||||||
|
Added the following options to `gam <UserTypeEntity> show chatmessages` to simplify specifying a filter.
|
||||||
|
```
|
||||||
|
start|starttime <Date>|<Time>
|
||||||
|
end|endtime <Date>|<Time>
|
||||||
|
range <Date>|<Time> <Date>|<Time>
|
||||||
|
thread <ChatThread>
|
||||||
|
```
|
||||||
|
|
||||||
|
Added commands to search for and display chat messages.
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Users-Chat#display-chat-messages-by-searching
|
||||||
|
|
||||||
|
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
|
||||||
|
```
|
||||||
|
developer_preview_apis = chat
|
||||||
|
developer_preview_api_key = <DeveloperPreviewKey>
|
||||||
|
```
|
||||||
|
|
||||||
|
Upgraded to Python 3.14.5.
|
||||||
|
|
||||||
|
### 7.43.10
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity>` to not forward messages
|
||||||
|
to the `Bcc` recipients of the original message.
|
||||||
|
|
||||||
|
Fixed bug in `gam <UserTypeEntity> forward message|thread [recipient|to] <RecipientEntity> addorigfieldstosubject`
|
||||||
|
where the recipient of the forwarded message was added to the subject line instead of the recipient of the original message.
|
||||||
|
|
||||||
### 7.43.09
|
### 7.43.09
|
||||||
|
|
||||||
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
|
Fixed bug in `gam <UserTypeEntity> print filelist` that caused a trap.
|
||||||
|
|||||||
@@ -251,9 +251,9 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
||||||
gamteam@server:/Users/gamteam$ gam version
|
gamteam@server:/Users/gamteam$ gam version
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.44.02 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
@@ -1034,9 +1034,9 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
C:\>del C:\GAMConfig\oauth2.txt
|
C:\>del C:\GAMConfig\oauth2.txt
|
||||||
C:\>gam version
|
C:\>gam version
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM - pythonsource
|
GAM 7.44.02 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
Windows 11 10.0.26200 AMD64
|
Windows 11 10.0.26200 AMD64
|
||||||
Path: C:\GAM7
|
Path: C:\GAM7
|
||||||
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
| Assured Controls | 1010390001 | assuredcontrols |
|
| Assured Controls | 1010390001 | assuredcontrols |
|
||||||
| Assured Controls Plus | 1010390002 | assuredcontrolsplus |
|
| Assured Controls Plus | 1010390002 | assuredcontrolsplus |
|
||||||
| Chrome Enterprise Premium | 1010400001 | cep | chromeenterprisepremium |
|
| Chrome Enterprise Premium | 1010400001 | cep | chromeenterprisepremium |
|
||||||
| Cloud Identity | 1010010001 | cloudidentity |
|
| Cloud Identity Free | 1010010001 | cloudidentity |
|
||||||
| Cloud Identity Premium | 1010050001 | cloudidentitypremium |
|
| Cloud Identity Premium | 1010050001 | cloudidentitypremium |
|
||||||
| Cloud Search | 1010350001 | cloudsearch |
|
| Cloud Search | 1010350001 | cloudsearch |
|
||||||
| Colab Pro | 1010500001 | colabpro |
|
| Colab Pro | 1010500001 | colabpro |
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
||||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
cloudidentityfree| cloudidentity | identity | 1010010001 | Cloud Identity Free |
|
||||||
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
||||||
cloudsearch | 1010350001 | Cloud Search |
|
cloudsearch | 1010350001 | Cloud Search |
|
||||||
colabpro | 1010500001 | Colab Pro |
|
colabpro | 1010500001 | Colab Pro |
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Thank you.
|
|||||||
* James Seymour - https://sites.google.com/view/gam--commands/
|
* James Seymour - https://sites.google.com/view/gam--commands/
|
||||||
* Kevin Melillo - https://github.com/KevinMelilloIEEE/gam-script
|
* Kevin Melillo - https://github.com/KevinMelilloIEEE/gam-script
|
||||||
* Korey Rideout - https://chatgpt.com/g/g-PTxxnVPMG-gam-assist-now-turbocharged-with-gam7
|
* Korey Rideout - https://chatgpt.com/g/g-PTxxnVPMG-gam-assist-now-turbocharged-with-gam7
|
||||||
|
* Paul Ogier (Taming.Tech) - GAM Scripts https://github.com/PaulOgier/GAMScripts
|
||||||
* Paul Ogier (Taming.Tech) - GAM7 Course on Udemy https://taming.tech/GAMCourse
|
* Paul Ogier (Taming.Tech) - GAM7 Course on Udemy https://taming.tech/GAMCourse
|
||||||
* Paul Ogier (Taming.Tech) - GAM7 Tutorials https://www.youtube.com/watch?v=g9LDeyXQNLI&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w
|
* Paul Ogier (Taming.Tech) - GAM7 Tutorials https://www.youtube.com/watch?v=g9LDeyXQNLI&list=PL_dLiK09pJVhKJxZHNk9CHK0q5hkZ856w
|
||||||
* Paul Ogier (Taming.Tech) - Installation videos
|
* Paul Ogier (Taming.Tech) - Installation videos
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
- [Display Chat Members](#display-chat-members)
|
- [Display Chat Members](#display-chat-members)
|
||||||
- [Manage Chat Messages](#manage-chat-messages)
|
- [Manage Chat Messages](#manage-chat-messages)
|
||||||
- [Display Chat Messages](#display-chat-messages)
|
- [Display Chat Messages](#display-chat-messages)
|
||||||
|
- [Display Chat Messages by Searching](#display-chat-messages-by-searching)
|
||||||
- [Display Chat Events](#display-chat-events)
|
- [Display Chat Events](#display-chat-events)
|
||||||
- [Manage Chat Emojis](#manage-chat-emojis)
|
- [Manage Chat Emojis](#manage-chat-emojis)
|
||||||
- [Display Chat Emojis](#display-chat-emojis)
|
- [Display Chat Emojis](#display-chat-emojis)
|
||||||
@@ -65,6 +66,7 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
|
|||||||
* [Chat API - Custom Emojis](https://developers.google.com/workspace/chat/api/reference/rest/v1/customEmojis)
|
* [Chat API - Custom Emojis](https://developers.google.com/workspace/chat/api/reference/rest/v1/customEmojis)
|
||||||
* [Chat API - Members](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.members/list)
|
* [Chat API - Members](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.members/list)
|
||||||
* [Chat API - Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list)
|
* [Chat API - Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list)
|
||||||
|
* [Chat API - Search Messages](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/search)
|
||||||
* [Chat API - Events](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list)
|
* [Chat API - Events](https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list)
|
||||||
* [Chat API - User Sections](https://developers.google.com/workspace/chat/api/reference/rest/v1/users.sections)
|
* [Chat API - User Sections](https://developers.google.com/workspace/chat/api/reference/rest/v1/users.sections)
|
||||||
* [Apps in Google Chat](https://support.google.com/chat/answer/7655820)
|
* [Apps in Google Chat](https://support.google.com/chat/answer/7655820)
|
||||||
@@ -109,8 +111,8 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
|
|||||||
<ChatThread> ::= spaces/<String>/threads/<String>
|
<ChatThread> ::= spaces/<String>/threads/<String>
|
||||||
<ChatSpaceType> ::=
|
<ChatSpaceType> ::=
|
||||||
space|
|
space|
|
||||||
groupchat|
|
groupchat|
|
||||||
directmessage
|
directmessage
|
||||||
<ChatSpaceTypeList> ::= "<ChatSpaceType>(,<ChatSpaceType>)*"
|
<ChatSpaceTypeList> ::= "<ChatSpaceType>(,<ChatSpaceType>)*"
|
||||||
<ChatMessageID> ::= client-<String>
|
<ChatMessageID> ::= client-<String>
|
||||||
<String> must contain only lowercase letters, numbers, and hyphens up to 56 characters in length.
|
<String> must contain only lowercase letters, numbers, and hyphens up to 56 characters in length.
|
||||||
@@ -908,7 +910,7 @@ gam user user@domain.com delete chatmessage name spaces/AAAADi-pvqc/messages/PKJ
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Display Chat Messages
|
## Display Chat Messages
|
||||||
Display a specific Chat message.
|
Display a specific chat message.
|
||||||
|
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> info chatmessage name <ChatMessage>
|
gam <UserTypeEntity> info chatmessage name <ChatMessage>
|
||||||
@@ -923,12 +925,15 @@ By default, Gam displays the information as an indented list of keys and values.
|
|||||||
gam user user@domain.com info chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU
|
gam user user@domain.com info chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU
|
||||||
```
|
```
|
||||||
|
|
||||||
### Display information about all chat messages in a chat space
|
### Display information about chat messages in a chat space
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> show chatmessages
|
gam <UserTypeEntity> show chatmessages
|
||||||
<ChatSpace>+
|
<ChatSpace>+
|
||||||
[showdeleted [<Boolean>]] [filter <String>]
|
[showdeleted [<Boolean>]]
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[thread <ChatThread>])
|
||||||
[fields <ChatMessageFieldNameList>]
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime [ascending|descending]]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
@@ -937,8 +942,11 @@ By default, Gam displays the information as an indented list of keys and values.
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print chatmessages [todrive <ToDriveAttribute>*]
|
||||||
<ChatSpace>+
|
<ChatSpace>+
|
||||||
[showdeleted [<Boolean>]] [filter <String>]
|
[showdeleted [<Boolean>]]
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[thread <ChatThread>])
|
||||||
[fields <ChatMessageFieldNameList>]
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime [ascending|descending]]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
|
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
|
||||||
@@ -952,38 +960,76 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
|
|||||||
|
|
||||||
By default, deleted messages are not displayed; use `showdeleted` to also display deleted messages.
|
By default, deleted messages are not displayed; use `showdeleted` to also display deleted messages.
|
||||||
|
|
||||||
Use `filter <String>` to filter messages by `createTime` and `thread.name`.
|
To filter messages by the time they were created:
|
||||||
|
* `start|starttime <Date>|<Time>` - Display messages created on or after the `<Date>|<Time>`
|
||||||
|
* `end|endtime <Date>|<Time>` - Display messages created before the `<Date>|<Time>`
|
||||||
|
* `range <Date>|<Time> <Date>|<Time>` - Display messages created on or after the first `<Date>|<Time>` and before the second `<Date>|<Time>`
|
||||||
|
|
||||||
To filter messages by the date they were created, specify the createTime with a timestamp in RFC-3339 format and double quotation marks. For example, "2023-04-21T11:30:00-04:00".
|
Use `thread <String>` to filter messages by their thread name, e.g., `spaces/AAAAAAAAAAA/threads/123`.
|
||||||
* Use the greater than operator `>` to list messages that were created after a timestamp.
|
|
||||||
* Use the less than operator `<` to list messages that were created before a timestamp.
|
|
||||||
* To filter messages within a time interval, use the AND operator between two timestamps.
|
|
||||||
* To filter by thread, specify the thread.name, formatted as spaces/{space}/threads/{thread}. You can only specify one thread.name per query.
|
|
||||||
* To filter by both thread and date, use the AND operator in your query.
|
|
||||||
|
|
||||||
For example, the following queries are valid on Linux/MacOS:
|
## Display Chat Messages by Searching
|
||||||
|
These commands are in Developer Preview; to use them you must have these values set in `gam.cfg`.
|
||||||
```
|
```
|
||||||
filter 'createTime > "2012-04-21T11:30:00-04:00"'
|
developer_preview_apis = chat
|
||||||
filter 'createTime > "2012-04-21T11:30:00-04:00" AND thread.name = spaces/AAAAAAAAAAA/threads/123'
|
developer_preview_api_key = <DeveloperPreviewKey>
|
||||||
filter 'createTime > "2012-04-21T11:30:00+00:00" AND createTime < "2013-01-01T00:00:00+00:00" AND thread.name = spaces/AAAAAAAAAAA/threads/123'
|
|
||||||
filter 'thread.name = spaces/AAAAAAAAAAA/threads/123'
|
|
||||||
```
|
```
|
||||||
|
See the following for search option details:
|
||||||
|
https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/search
|
||||||
|
|
||||||
For example, the following queries are valid on Windows Command Prompt:
|
You must specify `keywords <StringList>`; messages that match any word|phrase in `<StringList>` are displayed.
|
||||||
```
|
Phrases must be enclosed in `"`.
|
||||||
filter "createTime > \"2012-04-21T11:30:00-04:00\""
|
* Linux, macOS, Windows Command Prompt - `keywords "\"things to do\" urgent"`
|
||||||
filter "createTime > \"2012-04-21T11:30:00-04:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123"
|
* Windows Power Shell - ```keywords "`"things to do`" urgent"```
|
||||||
filter "createTime > \"2012-04-21T11:30:00+00:00\" AND createTime < \"2013-01-01T00:00:00+00:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123"
|
|
||||||
filter "thread.name = spaces/AAAAAAAAAAA/threads/123"
|
|
||||||
```
|
|
||||||
|
|
||||||
For example, the following queries are valid on Windows PowerShell:
|
By default, all spaces the user has access to are searched; use the following options to limit the search.
|
||||||
|
* `<ChatSpace>*` - Specific chat spaces
|
||||||
|
* `displaynames [all|any] <StringList>` - Spaces with display names with partial matches of `all|any` of the words in `<StringList>`
|
||||||
|
|
||||||
|
Use the following to limit the search to messages with specific characteristics.
|
||||||
|
* `senders <EmailAddressEntity>` - Messages with any sender in `<EmailAddressEntity>`
|
||||||
|
* `usermentions [all|any] <EmailAddressEntity>` - Messages with mentions of `all|any` users in `<EmailAddressEntity>`
|
||||||
|
* `start|starttime <Date>|<Time>` - Messages created on or after the `<Date>|<Time>`
|
||||||
|
* `end|endtime <Date>|<Time>` - Messages created before the `<Date>|<Time>`
|
||||||
|
* `range <Date>|<Time> <Date>|<Time>` - Messages created on or after the first `<Date>|<Time>` and before the second `<Date>|<Time>`
|
||||||
|
* `hasattachment` - Messages with at least one attachment
|
||||||
```
|
```
|
||||||
filter 'createTime > \"2012-04-21T11:30:00-04:00\"'
|
gam <UserTypeEntity> show chatsearchmessages
|
||||||
filter 'createTime > \"2012-04-21T11:30:00-04:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123"'
|
keywords <StringList>
|
||||||
filter 'createTime > \"2012-04-21T11:30:00+00:00\" AND createTime < \"2013-01-01T00:00:00+00:00\" AND thread.name = spaces/AAAAAAAAAAA/threads/123'
|
<ChatSpace>*
|
||||||
filter 'thread.name = spaces/AAAAAAAAAAA/threads/123'
|
[displaynames [all|any] <StringList>]
|
||||||
|
[senders <EmailAddressEntity>]*
|
||||||
|
[usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[hasattachment]
|
||||||
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime|relevance]
|
||||||
|
[formatjson]
|
||||||
```
|
```
|
||||||
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> print chatsearchmessages [todrive <ToDriveAttribute>*]
|
||||||
|
keywords <StringList>
|
||||||
|
<ChatSpace>*
|
||||||
|
[displaynames [all|any] <StringList>]
|
||||||
|
[senders <EmailAddressEntity>]*
|
||||||
|
[usermentions [all|any] <EmailAddressEntity>]*
|
||||||
|
[([start|starttime <Date>|<Time>] [end|endtime <Date>|<Time>])|(range <Date>|<Time> <Date>|<Time>)]
|
||||||
|
[hasattachment]
|
||||||
|
[fields <ChatMessageFieldNameList>]
|
||||||
|
[orderby createtime|relevance]
|
||||||
|
[formatjson [quotechar <Character>]]
|
||||||
|
```
|
||||||
|
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 <Character>` 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.
|
||||||
|
|
||||||
|
|
||||||
## Display Chat Events
|
## Display Chat Events
|
||||||
Display a specific Chat event.
|
Display a specific Chat event.
|
||||||
|
|||||||
@@ -477,12 +477,12 @@ When `matchlabel <LabelName>` is specified, the following characters are replace
|
|||||||
|
|
||||||
## Forward messages/threads
|
## Forward messages/threads
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity>
|
gam <UserTypeEntity> forward message|messages [recipient|to] <RecipientEntity>
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
[labelids <LabelIDList>]
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
|
||||||
[subject <String>] [addorigfieldstosubject]
|
[subject <String>] [addorigfieldstosubject]
|
||||||
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
|
gam <UserTypeEntity> forward thread|threads [recipient|to] <RecipientEntity>
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
[labelids <LabelIDList>]
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.44.02 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
@@ -15,9 +15,9 @@ Time: 2026-02-15T07:51:00-08:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.44.02 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
@@ -27,9 +27,9 @@ 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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.44.02 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 7.43.09
|
Latest: 7.44.02
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -76,7 +76,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
7.43.09
|
7.44.02
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -86,9 +86,9 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 7.43.09 - https://github.com/GAM-team/GAM
|
GAM 7.44.02 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.4 64-bit final
|
Python 3.14.5 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|||||||
Reference in New Issue
Block a user