mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Handle issues in update alias/message
This commit is contained in:
@@ -55,13 +55,18 @@ gam create alias bob[@yourdomain.com] user robert[@yourdomain.com]
|
|||||||
The existing alias is deleted and a new alias is created.
|
The existing alias is deleted and a new alias is created.
|
||||||
```
|
```
|
||||||
gam update alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
gam update alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||||
[notargetverify]
|
[notargetverify] [waitafterdelete <Integer>]
|
||||||
```
|
```
|
||||||
`<EmailAddressEntity>` are the aliases, `<EmailAddress>` is the target.
|
`<EmailAddressEntity>` are the aliases, `<EmailAddress>` is the target.
|
||||||
|
|
||||||
By default, GAM makes additional API calls to verify that the target email address exists before updating the alias;
|
By default, GAM makes additional API calls to verify that the target email address exists before updating the alias;
|
||||||
if you know that the target exists, you can suppress the verification with `notargetverify.
|
if you know that the target exists, you can suppress the verification with `notargetverify.
|
||||||
|
|
||||||
|
GAM updates an alias to point to a new target by deleting the alias and then recreates the alias pointing to the new target.
|
||||||
|
Unfortunately, if these commands are executed back-to-back; Google generates the `Update Failed: Duplicate` error.
|
||||||
|
Now, GAM waits 2 seconds between the delete and the insert which seems to eliminate the problem. If the problem persists,
|
||||||
|
use the option `waitafterdelete <Integer>` to increase the wait time to a maximum of 10 seconds.
|
||||||
|
|
||||||
## Delete an alias regardless of the target
|
## Delete an alias regardless of the target
|
||||||
```
|
```
|
||||||
gam delete alias|aliases [user|group|target] <EmailAddressEntity>
|
gam delete alias|aliases [user|group|target] <EmailAddressEntity>
|
||||||
|
|||||||
@@ -10,6 +10,25 @@ 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
|
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 6.66.14
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> modify messages` to recognize the following error:
|
||||||
|
```
|
||||||
|
ERROR: 400: invalid - Invalid label: SENT
|
||||||
|
```
|
||||||
|
|
||||||
|
Updated `gam update alias <EmailAddressEntity> user|group|target <EmailAddress>`
|
||||||
|
to avoid the following problem.
|
||||||
|
```
|
||||||
|
$ gam update alias testalias@domain.com user testuser
|
||||||
|
User Alias: testalias@domain.com, Deleted
|
||||||
|
User Alias: testalias@domain.com, User: testuser@domain.com, Update Failed: Duplicate, Email Address: testalias@domain.com
|
||||||
|
```
|
||||||
|
GAM updates an alias to point to a new target by deleting the alias and then recreating the alias pointing to the new target.
|
||||||
|
Unfortunately, if these commands are executed back-to-back; Google generates the `Update Failed: Duplicate` error.
|
||||||
|
Now, GAM waits 2 seconds between the delete and the insert which seems to eliminate the problem. If the problem persists,
|
||||||
|
the option `waitafterdelete <Integer>` can be used to increase the wait time to a maximum of 10 seconds.
|
||||||
|
|
||||||
### 6.66.13
|
### 6.66.13
|
||||||
|
|
||||||
Updated functionality of option `preservefiletimes` in `gam <UserTypeEntity> update drivefile <DriveFileEntity>`.
|
Updated functionality of option `preservefiletimes` in `gam <UserTypeEntity> update drivefile <DriveFileEntity>`.
|
||||||
|
|||||||
@@ -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$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
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
|
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.66.13 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.10.8 64-bit final
|
Python 3.10.8 64-bit final
|
||||||
MacOS High Sierra 10.13.6 x86_64
|
MacOS High Sierra 10.13.6 x86_64
|
||||||
@@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt.
|
|||||||
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
||||||
C:\GAMADV-XTD3>gam version
|
C:\GAMADV-XTD3>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.66.13 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAMADV-XTD3 6.66.13 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@@ -16,7 +16,7 @@ Time: 2023-06-02T21:10:00-07: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
|
||||||
GAMADV-XTD3 6.66.13 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@@ -28,7 +28,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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAMADV-XTD3 6.66.13 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/Admin/bin/gamadv-xtd3
|
Path: /Users/Admin/bin/gamadv-xtd3
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 6.66.13
|
Latest: 6.66.14
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -73,7 +73,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
6.66.13
|
6.66.14
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -83,7 +83,7 @@ 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 6.66.13 - https://github.com/taers232c/GAMADV-XTD3
|
GAM 6.66.14 - https://github.com/taers232c/GAMADV-XTD3
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
|
|||||||
@@ -1457,7 +1457,7 @@ gam print alertfeedback [todrive <ToDriveAttribute>*] [alert <AlertID>] [filter
|
|||||||
gam create|add alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
gam create|add alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||||
[verifynotinvitable]
|
[verifynotinvitable]
|
||||||
gam update alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
gam update alias|aliases <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||||
[notargetverify]
|
[notargetverify] [waitafterdelete <Integer>]
|
||||||
gam delete alias|aliases [user|group|target] <EmailAddressEntity>
|
gam delete alias|aliases [user|group|target] <EmailAddressEntity>
|
||||||
gam remove aliases|nicknames <EmailAddress> user|group <EmailAddressEntity>
|
gam remove aliases|nicknames <EmailAddress> user|group <EmailAddressEntity>
|
||||||
gam <UserTypeEntity> delete alias|aliases
|
gam <UserTypeEntity> delete alias|aliases
|
||||||
|
|||||||
@@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
Merged GAM-Team version
|
Merged GAM-Team version
|
||||||
|
|
||||||
|
6.66.14
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> modify messages` to recognize the following error:
|
||||||
|
```
|
||||||
|
ERROR: 400: invalid - Invalid label: SENT
|
||||||
|
```
|
||||||
|
|
||||||
|
Updated `gam update alias <EmailAddressEntity> user|group|target <EmailAddress>`
|
||||||
|
to avoid the following problem.
|
||||||
|
```
|
||||||
|
$ gam update alias testalias@domain.com user testuser
|
||||||
|
User Alias: testalias@domain.com, Deleted
|
||||||
|
User Alias: testalias@domain.com, User: testuser@domain.com, Update Failed: Duplicate, Email Address: testalias@domain.com
|
||||||
|
```
|
||||||
|
GAM updates an alias to point to a new target by deleting the alias and then recreating the alias pointing to the new target.
|
||||||
|
Unfortunately, if these commands are executed back-to-back; Google generates the `Update Failed: Duplicate` error.
|
||||||
|
Now, GAM waits 2 seconds between the delete and the insert which seems to eliminate the problem. If the problem persists,
|
||||||
|
the option `waitafterdelete <Integer>` can be used to increase the wait time to a maximum of 10 seconds.
|
||||||
|
|
||||||
6.66.13
|
6.66.13
|
||||||
|
|
||||||
Updated functionality of option `preservefiletimes` in `gam <UserTypeEntity> update drivefile <DriveFileEntity>`.
|
Updated functionality of option `preservefiletimes` in `gam <UserTypeEntity> update drivefile <DriveFileEntity>`.
|
||||||
|
|||||||
@@ -17333,7 +17333,7 @@ ALIAS_TARGET_TYPES = ['user', 'group', 'target']
|
|||||||
# gam create aliases|nicknames <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
# gam create aliases|nicknames <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||||
# [verifynotinvitable]
|
# [verifynotinvitable]
|
||||||
# gam update aliases|nicknames <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
# gam update aliases|nicknames <EmailAddressEntity> user|group|target <UniqueID>|<EmailAddress>
|
||||||
# [notargetverify]
|
# [notargetverify] [waitafterdelete <Integer>]
|
||||||
def doCreateUpdateAliases():
|
def doCreateUpdateAliases():
|
||||||
def verifyAliasTargetExists():
|
def verifyAliasTargetExists():
|
||||||
if targetType != 'group':
|
if targetType != 'group':
|
||||||
@@ -17355,6 +17355,42 @@ def doCreateUpdateAliases():
|
|||||||
GAPI.badRequest, GAPI.invalid, GAPI.systemError):
|
GAPI.badRequest, GAPI.invalid, GAPI.systemError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def deleteAliasOnUpdate():
|
||||||
|
# User alias
|
||||||
|
if targetType != 'group':
|
||||||
|
try:
|
||||||
|
callGAPI(cd.users().aliases(), 'delete',
|
||||||
|
throwReasons=[GAPI.USER_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.FORBIDDEN, GAPI.INVALID_RESOURCE,
|
||||||
|
GAPI.CONDITION_NOT_MET],
|
||||||
|
userKey=aliasEmail, alias=aliasEmail)
|
||||||
|
printEntityKVList([Ent.USER_ALIAS, aliasEmail], [Act.PerformedName(Act.DELETE)], i, count)
|
||||||
|
time.sleep(waitAfterDelete)
|
||||||
|
return True
|
||||||
|
except GAPI.conditionNotMet as e:
|
||||||
|
entityActionFailedWarning([Ent.USER_ALIAS, aliasEmail], str(e), i, count)
|
||||||
|
return False
|
||||||
|
except (GAPI.userNotFound, GAPI.badRequest, GAPI.invalid, GAPI.forbidden, GAPI.invalidResource):
|
||||||
|
if targetType == 'user':
|
||||||
|
entityUnknownWarning(Ent.USER_ALIAS, aliasEmail, i, count)
|
||||||
|
return False
|
||||||
|
# Group alias
|
||||||
|
try:
|
||||||
|
callGAPI(cd.groups().aliases(), 'delete',
|
||||||
|
throwReasons=[GAPI.GROUP_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.FORBIDDEN, GAPI.INVALID_RESOURCE,
|
||||||
|
GAPI.CONDITION_NOT_MET],
|
||||||
|
groupKey=aliasEmail, alias=aliasEmail)
|
||||||
|
time.sleep(waitAfterDelete)
|
||||||
|
return True
|
||||||
|
except GAPI.conditionNotMet as e:
|
||||||
|
entityActionFailedWarning([Ent.GROUP_ALIAS, aliasEmail], str(e), i, count)
|
||||||
|
return False
|
||||||
|
except GAPI.forbidden:
|
||||||
|
entityUnknownWarning(Ent.GROUP_ALIAS, aliasEmail, i, count)
|
||||||
|
return False
|
||||||
|
except (GAPI.groupNotFound, GAPI.badRequest, GAPI.invalid, GAPI.invalidResource):
|
||||||
|
entityUnknownWarning(Ent.GROUP_ALIAS, aliasEmail, i, count)
|
||||||
|
return False
|
||||||
|
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
ci = None
|
ci = None
|
||||||
updateCmd = Act.Get() == Act.UPDATE
|
updateCmd = Act.Get() == Act.UPDATE
|
||||||
@@ -17364,12 +17400,15 @@ def doCreateUpdateAliases():
|
|||||||
entityLists = targetEmails if isinstance(targetEmails, dict) else None
|
entityLists = targetEmails if isinstance(targetEmails, dict) else None
|
||||||
verifyNotInvitable = False
|
verifyNotInvitable = False
|
||||||
verifyTarget = updateCmd
|
verifyTarget = updateCmd
|
||||||
|
waitAfterDelete = 2
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if (not updateCmd) and myarg == 'verifynotinvitable':
|
if (not updateCmd) and myarg == 'verifynotinvitable':
|
||||||
verifyNotInvitable = True
|
verifyNotInvitable = True
|
||||||
elif updateCmd and myarg == 'notargetverify':
|
elif updateCmd and myarg == 'notargetverify':
|
||||||
verifyTarget = False
|
verifyTarget = False
|
||||||
|
elif updateCmd and myarg == 'waitafterdelete':
|
||||||
|
waitAfterDelete = getInteger(minVal=2, maxVal=10)
|
||||||
else:
|
else:
|
||||||
unknownArgumentExit()
|
unknownArgumentExit()
|
||||||
i = 0
|
i = 0
|
||||||
@@ -17394,30 +17433,9 @@ def doCreateUpdateAliases():
|
|||||||
if targetType is None:
|
if targetType is None:
|
||||||
entityUnknownWarning(Ent.ALIAS_TARGET, targetEmail, i, count)
|
entityUnknownWarning(Ent.ALIAS_TARGET, targetEmail, i, count)
|
||||||
continue
|
continue
|
||||||
if updateCmd:
|
if updateCmd and not deleteAliasOnUpdate():
|
||||||
try:
|
|
||||||
callGAPI(cd.users().aliases(), 'delete',
|
|
||||||
throwReasons=[GAPI.USER_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.FORBIDDEN, GAPI.INVALID_RESOURCE,
|
|
||||||
GAPI.CONDITION_NOT_MET],
|
|
||||||
userKey=aliasEmail, alias=aliasEmail)
|
|
||||||
printEntityKVList([Ent.USER_ALIAS, aliasEmail], [Act.PerformedName(Act.DELETE)], i, count)
|
|
||||||
except GAPI.conditionNotMet as e:
|
|
||||||
entityActionFailedWarning([Ent.USER_ALIAS, aliasEmail], str(e), i, count)
|
|
||||||
continue
|
continue
|
||||||
except (GAPI.userNotFound, GAPI.badRequest, GAPI.invalid, GAPI.forbidden, GAPI.invalidResource):
|
# User alias
|
||||||
try:
|
|
||||||
callGAPI(cd.groups().aliases(), 'delete',
|
|
||||||
throwReasons=[GAPI.GROUP_NOT_FOUND, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.FORBIDDEN, GAPI.INVALID_RESOURCE,
|
|
||||||
GAPI.CONDITION_NOT_MET],
|
|
||||||
groupKey=aliasEmail, alias=aliasEmail)
|
|
||||||
except GAPI.conditionNotMet as e:
|
|
||||||
entityActionFailedWarning([Ent.GROUP_ALIAS, aliasEmail], str(e), i, count)
|
|
||||||
continue
|
|
||||||
except GAPI.forbidden:
|
|
||||||
entityUnknownWarning(Ent.GROUP_ALIAS, aliasEmail, i, count)
|
|
||||||
continue
|
|
||||||
except (GAPI.groupNotFound, GAPI.badRequest, GAPI.invalid, GAPI.invalidResource):
|
|
||||||
entityUnknownWarning(Ent.ALIAS, aliasEmail, i, count)
|
|
||||||
if targetType != 'group':
|
if targetType != 'group':
|
||||||
try:
|
try:
|
||||||
callGAPI(cd.users().aliases(), 'insert',
|
callGAPI(cd.users().aliases(), 'insert',
|
||||||
@@ -17440,6 +17458,7 @@ def doCreateUpdateAliases():
|
|||||||
if targetType == 'user':
|
if targetType == 'user':
|
||||||
entityUnknownWarning(Ent.ALIAS_TARGET, targetEmail, i, count)
|
entityUnknownWarning(Ent.ALIAS_TARGET, targetEmail, i, count)
|
||||||
continue
|
continue
|
||||||
|
# Group alias
|
||||||
try:
|
try:
|
||||||
callGAPI(cd.groups().aliases(), 'insert',
|
callGAPI(cd.groups().aliases(), 'insert',
|
||||||
throwReasons=[GAPI.GROUP_NOT_FOUND, GAPI.USER_NOT_FOUND, GAPI.BAD_REQUEST,
|
throwReasons=[GAPI.GROUP_NOT_FOUND, GAPI.USER_NOT_FOUND, GAPI.BAD_REQUEST,
|
||||||
@@ -25169,16 +25188,18 @@ def createChatMember(users):
|
|||||||
entityPerformActionNumItems(kvList, jcount, entityType, i, count)
|
entityPerformActionNumItems(kvList, jcount, entityType, i, count)
|
||||||
if jcount == 0:
|
if jcount == 0:
|
||||||
return
|
return
|
||||||
|
kvList.extend([entityType, ''])
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
j = 0
|
j = 0
|
||||||
for body in members:
|
for body in members:
|
||||||
|
j += 1
|
||||||
kvList[-1] = body[field]['name']
|
kvList[-1] = body[field]['name']
|
||||||
try:
|
try:
|
||||||
member = callGAPI(chat.spaces().members(), 'create',
|
member = callGAPI(chat.spaces().members(), 'create',
|
||||||
bailOnInternalError=True,
|
bailOnInternalError=True,
|
||||||
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||||
parent=parent, body=body)
|
parent=parent, body=body)
|
||||||
if role != 'ROLE_MEMBER':
|
if role != 'ROLE_MEMBER' and entityType == Ent.CHAT_MANAGER_USER:
|
||||||
member = callGAPI(chat.spaces().members(), 'patch',
|
member = callGAPI(chat.spaces().members(), 'patch',
|
||||||
bailOnInternalError=True,
|
bailOnInternalError=True,
|
||||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||||
@@ -25193,7 +25214,7 @@ def createChatMember(users):
|
|||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
else:
|
else:
|
||||||
writeStdout(f'{member["name"]}\n')
|
writeStdout(f'{member["name"]}\n')
|
||||||
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||||
entityActionFailedWarning(kvList, str(e))
|
entityActionFailedWarning(kvList, str(e))
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
|
|
||||||
@@ -25230,6 +25251,7 @@ def createChatMember(users):
|
|||||||
missingArgumentExit('space')
|
missingArgumentExit('space')
|
||||||
if not userList and not groupList:
|
if not userList and not groupList:
|
||||||
missingArgumentExit('user|members|group|groups')
|
missingArgumentExit('user|members|group|groups')
|
||||||
|
userEntityType = Ent.CHAT_MEMBER_USER if role == 'ROLE_MEMBER' else Ent.CHAT_MANAGER_USER
|
||||||
userMembers = []
|
userMembers = []
|
||||||
for user in userList:
|
for user in userList:
|
||||||
name = normalizeEmailAddressOrUID(user)
|
name = normalizeEmailAddressOrUID(user)
|
||||||
@@ -25244,10 +25266,12 @@ def createChatMember(users):
|
|||||||
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent])
|
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent])
|
||||||
if not chat:
|
if not chat:
|
||||||
continue
|
continue
|
||||||
|
Ind.Increment()
|
||||||
if userMembers:
|
if userMembers:
|
||||||
addMembers(userMembers, 'member', Ent.CHAT_MEMBER_USER, i, count)
|
addMembers(userMembers, 'member', userEntityType, i, count)
|
||||||
if groupMembers:
|
if groupMembers:
|
||||||
addMembers(groupMembers, 'groupMember', Ent.CHAT_MEMBER_GROUP, i, count)
|
addMembers(groupMembers, 'groupMember', Ent.CHAT_MEMBER_GROUP, i, count)
|
||||||
|
Ind.Decrement()
|
||||||
|
|
||||||
def _deleteChatMembers(chat, kvList, jcount, memberNames, i, count):
|
def _deleteChatMembers(chat, kvList, jcount, memberNames, i, count):
|
||||||
j = 0
|
j = 0
|
||||||
@@ -25323,7 +25347,7 @@ def deleteUpdateChatMember(users):
|
|||||||
i, count, users = getEntityArgument(users)
|
i, count, users = getEntityArgument(users)
|
||||||
for user in users:
|
for user in users:
|
||||||
i += 1
|
i += 1
|
||||||
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count)
|
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent] if parent is not None else None)
|
||||||
if not chat:
|
if not chat:
|
||||||
continue
|
continue
|
||||||
jcount = len(memberNames)
|
jcount = len(memberNames)
|
||||||
@@ -25360,12 +25384,12 @@ CHAT_SYNC_PREVIEW_TITLES = ['space', 'member', 'role', 'action', 'message']
|
|||||||
# [preview [actioncsv]]
|
# [preview [actioncsv]]
|
||||||
# (users <UserTypeEntity>)* (groups <GroupEntity>)*
|
# (users <UserTypeEntity>)* (groups <GroupEntity>)*
|
||||||
def syncChatMembers(users):
|
def syncChatMembers(users):
|
||||||
def _previewAction(members, jcount, action):
|
def _previewAction(members, entityType, jcount, action):
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
j = 0
|
j = 0
|
||||||
for member in members:
|
for member in members:
|
||||||
j += 1
|
j += 1
|
||||||
entityActionPerformed([Ent.CHAT_SPACE, parent, Ent.CHAT_MEMBER, member, Ent.ROLE, role], j, jcount)
|
entityActionPerformed([Ent.CHAT_SPACE, parent, entityType, member, Ent.ROLE, role], j, jcount)
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
if csvPF:
|
if csvPF:
|
||||||
for member in members:
|
for member in members:
|
||||||
@@ -25373,11 +25397,11 @@ def syncChatMembers(users):
|
|||||||
|
|
||||||
def addMembers(memberNames, members, entityType, i, count):
|
def addMembers(memberNames, members, entityType, i, count):
|
||||||
jcount = len(memberNames)
|
jcount = len(memberNames)
|
||||||
entityPerformActionNumItems(kvList, jcount, Ent.CHAT_MEMBER, i, count)
|
entityPerformActionNumItems(kvList, jcount, entityType, i, count)
|
||||||
if jcount == 0:
|
if jcount == 0:
|
||||||
return
|
return
|
||||||
if preview:
|
if preview:
|
||||||
_previewAction(memberNames, jcount, Act.REMOVE)
|
_previewAction(memberNames, entityType, jcount, Act.REMOVE)
|
||||||
return
|
return
|
||||||
kvList.extend([entityType, ''])
|
kvList.extend([entityType, ''])
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
@@ -25389,26 +25413,26 @@ def syncChatMembers(users):
|
|||||||
try:
|
try:
|
||||||
callGAPI(chat.spaces().members(), 'create',
|
callGAPI(chat.spaces().members(), 'create',
|
||||||
bailOnInternalError=True,
|
bailOnInternalError=True,
|
||||||
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.NOT_FOUND, GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||||
parent=parent, body=body)
|
parent=parent, body=body)
|
||||||
if role != 'ROLE_MEMBER':
|
if role != 'ROLE_MEMBER' and entityType == Ent.CHAT_MANAGER_USER:
|
||||||
callGAPI(chat.spaces().members(), 'patch',
|
callGAPI(chat.spaces().members(), 'patch',
|
||||||
bailOnInternalError=True,
|
bailOnInternalError=True,
|
||||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||||
name=memberName, updateMask='role', body={'role': role})
|
name=memberName, updateMask='role', body={'role': role})
|
||||||
entityActionPerformed(kvList, j, jcount)
|
entityActionPerformed(kvList, j, jcount)
|
||||||
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
except (GAPI.alreadyExists, GAPI.notFound, GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
del kvList[-2:]
|
del kvList[-2:]
|
||||||
|
|
||||||
def deleteMembers(memberNames, entityType, i, count):
|
def deleteMembers(memberNames, entityType, i, count):
|
||||||
jcount = len(memberNames)
|
jcount = len(memberNames)
|
||||||
entityPerformActionNumItems(kvList, jcount, Ent.CHAT_MEMBER, i, count)
|
entityPerformActionNumItems(kvList, jcount, entityType, i, count)
|
||||||
if jcount == 0:
|
if jcount == 0:
|
||||||
return
|
return
|
||||||
if preview:
|
if preview:
|
||||||
_previewAction(memberNames, jcount, Act.ADD)
|
_previewAction(memberNames, entityType, jcount, Act.ADD)
|
||||||
return
|
return
|
||||||
kvList.extend([entityType, ''])
|
kvList.extend([entityType, ''])
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
@@ -25417,7 +25441,6 @@ def syncChatMembers(users):
|
|||||||
del kvList[-2:]
|
del kvList[-2:]
|
||||||
|
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
kwargs = {}
|
|
||||||
parent = None
|
parent = None
|
||||||
role = CHAT_MEMBER_ROLE_MAP['member']
|
role = CHAT_MEMBER_ROLE_MAP['member']
|
||||||
mtype = CHAT_MEMBER_TYPE_MAP['human']
|
mtype = CHAT_MEMBER_TYPE_MAP['human']
|
||||||
@@ -25456,6 +25479,7 @@ def syncChatMembers(users):
|
|||||||
unknownArgumentExit()
|
unknownArgumentExit()
|
||||||
if not parent:
|
if not parent:
|
||||||
missingArgumentExit('space')
|
missingArgumentExit('space')
|
||||||
|
userEntityType = Ent.CHAT_MEMBER_USER if role == 'ROLE_MEMBER' else Ent.CHAT_MANAGER_USER
|
||||||
userMembers = {}
|
userMembers = {}
|
||||||
syncUsersSet = set()
|
syncUsersSet = set()
|
||||||
for user in userList:
|
for user in userList:
|
||||||
@@ -25470,12 +25494,11 @@ def syncChatMembers(users):
|
|||||||
memberName = f'{parent}/members/{name}'
|
memberName = f'{parent}/members/{name}'
|
||||||
groupMembers[memberName] = {'groupMember': {'name': f'groups/{name}'}}
|
groupMembers[memberName] = {'groupMember': {'name': f'groups/{name}'}}
|
||||||
syncGroupsSet.add(memberName)
|
syncGroupsSet.add(memberName)
|
||||||
kwargs['filter'] = f'member.type = "{mtype}" AND role = "{role}"'
|
qfilter = f'{Ent.Singular(Ent.CHAT_SPACE)}: {parent}'
|
||||||
qfilter = f'{Ent.Singular(Ent.CHAT_SPACE)}: {parent}, {kwargs["filter"]}'
|
|
||||||
i, count, users = getEntityArgument(users)
|
i, count, users = getEntityArgument(users)
|
||||||
for user in users:
|
for user in users:
|
||||||
i += 1
|
i += 1
|
||||||
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count)
|
user, chat, kvList = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count, [Ent.CHAT_SPACE, parent])
|
||||||
if not chat:
|
if not chat:
|
||||||
continue
|
continue
|
||||||
currentUsersSet = set()
|
currentUsersSet = set()
|
||||||
@@ -25484,12 +25507,14 @@ def syncChatMembers(users):
|
|||||||
members = callGAPIpages(chat.spaces().members(), 'list', 'memberships',
|
members = callGAPIpages(chat.spaces().members(), 'list', 'memberships',
|
||||||
pageMessage=_getChatPageMessage(Ent.CHAT_MEMBER, user, i, count, qfilter),
|
pageMessage=_getChatPageMessage(Ent.CHAT_MEMBER, user, i, count, qfilter),
|
||||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||||
pageSize=CHAT_PAGE_SIZE, parent=parent, **kwargs)
|
pageSize=CHAT_PAGE_SIZE, parent=parent, showGroups=groupsSpecified)
|
||||||
for member in members:
|
for member in members:
|
||||||
_getChatMemberEmail(cd, member)
|
|
||||||
if 'member' in member:
|
if 'member' in member:
|
||||||
|
if member['member']['type'] == mtype and member['role'] == role:
|
||||||
|
_getChatMemberEmail(cd, member)
|
||||||
currentUsersSet.add(f"{parent}/members/{member['member']['email']}")
|
currentUsersSet.add(f"{parent}/members/{member['member']['email']}")
|
||||||
elif 'groupMember' in member:
|
elif 'groupMember' in member:
|
||||||
|
_getChatMemberEmail(cd, member)
|
||||||
currentGroupsSet.add(f"{parent}/members/{member['groupMember']['email']}")
|
currentGroupsSet.add(f"{parent}/members/{member['groupMember']['email']}")
|
||||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||||
@@ -25497,13 +25522,13 @@ def syncChatMembers(users):
|
|||||||
if syncOperation != 'addonly':
|
if syncOperation != 'addonly':
|
||||||
Act.Set([Act.REMOVE, Act.REMOVE_PREVIEW][preview])
|
Act.Set([Act.REMOVE, Act.REMOVE_PREVIEW][preview])
|
||||||
if usersSpecified:
|
if usersSpecified:
|
||||||
deleteMembers(currentUsersSet-syncUsersSet, Ent.CHAT_MEMBER_USER, i, count)
|
deleteMembers(currentUsersSet-syncUsersSet, userEntityType, i, count)
|
||||||
if groupsSpecified:
|
if groupsSpecified:
|
||||||
deleteMembers(currentGroupsSet-syncGroupsSet, Ent.CHAT_MEMBER_GROUP, i, count)
|
deleteMembers(currentGroupsSet-syncGroupsSet, Ent.CHAT_MEMBER_GROUP, i, count)
|
||||||
if syncOperation != 'removeonly':
|
if syncOperation != 'removeonly':
|
||||||
Act.Set([Act.ADD, Act.ADD_PREVIEW][preview])
|
Act.Set([Act.ADD, Act.ADD_PREVIEW][preview])
|
||||||
if usersSpecified:
|
if usersSpecified:
|
||||||
addMembers(syncUsersSet-currentUsersSet, userMembers, Ent.CHAT_MEMBER_USER, i, count)
|
addMembers(syncUsersSet-currentUsersSet, userMembers, userEntityType, i, count)
|
||||||
if groupsSpecified:
|
if groupsSpecified:
|
||||||
addMembers(syncGroupsSet-currentGroupsSet, groupMembers, Ent.CHAT_MEMBER_GROUP, i, count)
|
addMembers(syncGroupsSet-currentGroupsSet, groupMembers, Ent.CHAT_MEMBER_GROUP, i, count)
|
||||||
if csvPF:
|
if csvPF:
|
||||||
@@ -65484,20 +65509,27 @@ def _processMessagesThreads(users, entityType):
|
|||||||
bcount = min(jcount-mcount, GC.Values[GC.MESSAGE_BATCH_SIZE])
|
bcount = min(jcount-mcount, GC.Values[GC.MESSAGE_BATCH_SIZE])
|
||||||
while bcount > 0:
|
while bcount > 0:
|
||||||
body['ids'] = messageIds[mcount:mcount+bcount]
|
body['ids'] = messageIds[mcount:mcount+bcount]
|
||||||
|
idsCount = min(5, bcount)
|
||||||
|
idsList = ','.join(body['ids'][0:idsCount])
|
||||||
|
if bcount > 5:
|
||||||
|
idsList += ',...'
|
||||||
try:
|
try:
|
||||||
callGAPI(gmail.users().messages(), function,
|
callGAPI(gmail.users().messages(), function,
|
||||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.FAILED_PRECONDITION],
|
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.INVALID, GAPI.FAILED_PRECONDITION],
|
||||||
userId='me', body=body)
|
userId='me', body=body)
|
||||||
for messageId in body['ids']:
|
for messageId in body['ids']:
|
||||||
mcount += 1
|
mcount += 1
|
||||||
entityActionPerformed([Ent.USER, user, entityType, messageId], mcount, jcount)
|
entityActionPerformed([Ent.USER, user, entityType, messageId], mcount, jcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||||
mcount += bcount
|
mcount += bcount
|
||||||
|
except GAPI.invalid as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user, entityType, idsList], f'{str(e)} ({mcount+1}-{mcount+bcount}/{jcount})')
|
||||||
|
mcount += bcount
|
||||||
except GAPI.invalidMessageId:
|
except GAPI.invalidMessageId:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, Msg.BATCH], f'{Msg.INVALID_MESSAGE_ID} ({mcount+1}-{mcount+bcount}/{jcount})')
|
entityActionFailedWarning([Ent.USER, user, entityType, idsList], f'{Msg.INVALID_MESSAGE_ID} ({mcount+1}-{mcount+bcount}/{jcount})')
|
||||||
mcount += bcount
|
mcount += bcount
|
||||||
except GAPI.failedPrecondition:
|
except GAPI.failedPrecondition:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, Msg.BATCH], f'{Msg.FAILED_PRECONDITION} ({mcount+1}-{mcount+bcount}/{jcount})')
|
entityActionFailedWarning([Ent.USER, user, entityType, idsList], f'{Msg.FAILED_PRECONDITION} ({mcount+1}-{mcount+bcount}/{jcount})')
|
||||||
mcount += bcount
|
mcount += bcount
|
||||||
bcount = min(jcount-mcount, GC.Values[GC.MESSAGE_BATCH_SIZE])
|
bcount = min(jcount-mcount, GC.Values[GC.MESSAGE_BATCH_SIZE])
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class GamEntity():
|
|||||||
CHANNEL_PRODUCT = 'chpr'
|
CHANNEL_PRODUCT = 'chpr'
|
||||||
CHANNEL_SKU = 'chsk'
|
CHANNEL_SKU = 'chsk'
|
||||||
CHAT_BOT = 'chbo'
|
CHAT_BOT = 'chbo'
|
||||||
|
CHAT_MANAGER_USER = 'chgu'
|
||||||
CHAT_MEMBER = 'chme'
|
CHAT_MEMBER = 'chme'
|
||||||
CHAT_MEMBER_GROUP = 'chmg'
|
CHAT_MEMBER_GROUP = 'chmg'
|
||||||
CHAT_MEMBER_USER = 'chmu'
|
CHAT_MEMBER_USER = 'chmu'
|
||||||
@@ -416,6 +417,7 @@ class GamEntity():
|
|||||||
CHANNEL_PRODUCT: ['Channel Products', 'Channel Product'],
|
CHANNEL_PRODUCT: ['Channel Products', 'Channel Product'],
|
||||||
CHANNEL_SKU: ['Channel SKUs', 'Channel SKU'],
|
CHANNEL_SKU: ['Channel SKUs', 'Channel SKU'],
|
||||||
CHAT_BOT: ['Chat BOTs', 'Chat BOT'],
|
CHAT_BOT: ['Chat BOTs', 'Chat BOT'],
|
||||||
|
CHAT_MANAGER_USER: ['Chat User Managers', 'Chat User Manager'],
|
||||||
CHAT_MESSAGE: ['Chat Messages', 'Chat Message'],
|
CHAT_MESSAGE: ['Chat Messages', 'Chat Message'],
|
||||||
CHAT_MESSAGE_ID: ['Chat Message IDs', 'Chat Message ID'],
|
CHAT_MESSAGE_ID: ['Chat Message IDs', 'Chat Message ID'],
|
||||||
CHAT_MEMBER: ['Chat Members', 'Chat Member'],
|
CHAT_MEMBER: ['Chat Members', 'Chat Member'],
|
||||||
|
|||||||
Reference in New Issue
Block a user