Added support for alternative output when creating contacts

This commit is contained in:
Ross Scroggs
2023-08-15 07:58:23 -07:00
parent bea1c1c22d
commit a017621a3d
8 changed files with 193 additions and 19 deletions

View File

@@ -185,7 +185,21 @@
## Create domain shared contacts
```
gam create contact <ContactAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
By default, the domain name and contact ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write domain name and contact ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contact ID on stdout
To retrieve the contact ID with `returnidonly`:
```
Linux/MacOS
contactId=$(gam create contact ... returnidonly)
Windows PowerShell
$contactId = & gam create contact ... returnidonly
```
## Select domain shared contacts
You specify contacts by ID or by selection qualifiers.
```

View File

@@ -10,6 +10,30 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation.
### 6.62.08
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
### 6.62.07
Added option `csv [todrive <ToDriveAttribute>*]` to these commands that causes GAM to output
the contact creator and contact ID in CSV form. This will be useful when bulk contacts are created.
Added `returnidonly` to these commands that causes GAM to return just the
contact ID as output. This will be useful in scripts that create a contact and then
want to perform subsequent GAM commands on the contact.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
### 6.62.06
Added output `Item cap` to `gam <UserTypeEntity> print filecounts select select <SharedDriveEntity>` that

View File

@@ -329,7 +329,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAMADV-XTD3 6.62.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.62.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.10.8 64-bit final
MacOS High Sierra 10.13.6 x86_64
@@ -969,7 +969,7 @@ writes the credentials into the file oauth2.txt.
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
C:\GAMADV-XTD3>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAMADV-XTD3 6.62.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.62.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
Windows-10-10.0.17134 AMD64

View File

@@ -250,10 +250,24 @@ then filters the list to only those in `<PeopleContactGroupItem>`; quota limits
gam <UserTypeEntity> create contact
[<PeopleContactAttribute>+]
(contactgroup <PeopleContactGroupItem>)*
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
You may specify zero or more contact groups with `(contactgroup <PeopleContactGroupItem>)*`;
these contact groups define the complete contact group list for the contact.
By default, the user name and contact ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write user name and contact ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contact ID on stdout
To retrieve the contact ID with `returnidonly`:
```
Linux/MacOS
contactId=$(gam user user@domain.com create contact ... returnidonly)
Windows PowerShell
$contactId = & gam user user@domain.com create contact ... returnidonly
```
## Update User Contacts
```
gam <UserTypeEntity> update contacts
@@ -546,6 +560,21 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Manage User Contact Groups
```
gam <UserTypeEntity> create contactgroup <PeopleContactGroupAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
By default, the user name and contactgroup ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write user name and contactgroup ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contactgroup ID on stdout
To retrieve the contactgroup ID with `returnidonly`:
```
Linux/MacOS
contactGroupId=$(gam user user@domain.com create contactgroup ... returnidonly)
Windows PowerShell
$contactGroupId = & gam user user@domain.com create contactgroup ... returnidonly
```
```
gam <UserTypeEntity> update contactgroup <PeopleContactGroupItem> <PeopleContactGroupAttribute>+
gam <UserTypeEntity> delete contactgroups <PeopleContactGroupEntity>
```
@@ -614,4 +643,3 @@ the quote character itself, the column delimiter (comma by default) and new-line
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.

View File

@@ -3,7 +3,7 @@
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.62.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.62.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.62.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Version Check:
Current: 5.35.08
Latest: 6.22.00
Latest: 6.62.08
echo $?
1
```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.22.00
6.62.08
```
In Linux/MacOS you can do:
```
@@ -82,7 +82,7 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 6.22.00 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.62.08 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64

View File

@@ -3162,6 +3162,7 @@ gam show domainaliases|aliasdomains [formatjson]
[updated_min <Date>]
gam create contact <ContactAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
gam update contacts <ContactEntity>|<ContactSelection> <ContactAttribute>+
gam clear contacts <ContactEntity>|<ContactSelection>
[emailclearpattern <RegularExpression>] [emailcleartype work|home|other|<String>]
@@ -7141,6 +7142,7 @@ gam <UserTypeEntity> sync license <SKUIDList> [product|productid <ProductID>] [a
gam <UserTypeEntity> create contact
[<PeopleContactAttribute>+]
(contactgroup <ContactGroupItem>)*
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
gam <UserTypeEntity> update contacts
<PeopleResourceNameEntity>|(<PeopleUserContactSelection> endquery)
[<PeopleContactAttribute>+]
@@ -7237,6 +7239,7 @@ gam <UserTypeEntity> print othercontacts [todrive <ToDriveAttribute>*]
<PeopleContactGroupFieldList> ::= "<PeopleContactGroupField>(,<PeopleContactGroupField>)*"
gam <UserTypeEntity> create contactgroup <PeopleContactGroupAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
gam <UserTypeEntity> update contactgroup <PeopleContactGroupItem> <PeopleContactGroupAttribute>+
gam <UserTypeEntity> delete contactgroups <PeopleContactGroupEntity>

View File

@@ -2,6 +2,30 @@
Merged GAM-Team version
6.62.08
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
6.62.07
Added option `csv [todrive <ToDriveAttribute>*]` to these commands that causes GAM to output
the contact creator and contact ID in CSV form. This will be useful when bulk contacts are created.
Added `returnidonly` to these commands that causes GAM to return just the
contact ID as output. This will be useful in scripts that create a contact and then
want to perform subsequent GAM commands on the contact.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
6.62.06
Added output `Item cap` to `gam <UserTypeEntity> print filecounts select select <SharedDriveEntity>` that

View File

@@ -17637,6 +17637,21 @@ def doPrintAddresses():
# Contact commands utilities
#
def _getCreateContactReturnOptions(parameters):
myarg = getArgument()
if myarg == 'returnidonly':
parameters['returnIdOnly'] = True
elif myarg == 'csv':
parameters['csvPF'] = CSVPrintFile(parameters['titles'], 'sortall')
elif parameters['csvPF'] and myarg == 'todrive':
parameters['csvPF'].GetTodriveParameters()
elif parameters['csvPF'] and myarg == 'addcsvdata':
k = getString(Cmd.OB_STRING)
parameters['addCSVData'][k] = getString(Cmd.OB_STRING, minLen=0)
else:
return False
return True
#
CONTACT_JSON = 'JSON'
CONTACT_ID = 'ContactID'
@@ -18104,7 +18119,7 @@ class ContactsManager():
return full_id[full_id.rfind('/')+1:]
@staticmethod
def GetContactFields():
def GetContactFields(parameters=None):
fields = {}
@@ -18155,6 +18170,10 @@ class ContactsManager():
primary = {}
while Cmd.ArgumentsRemaining():
if parameters is not None:
if _getCreateContactReturnOptions(parameters):
continue
Cmd.Backup()
fieldName = getChoice(ContactsManager.CONTACT_ARGUMENT_TO_PROPERTY_MAP, mapChoice=True)
if fieldName == CONTACT_BIRTHDAY:
fields[fieldName] = getYYYYMMDD(minLen=0)
@@ -18690,7 +18709,13 @@ def dedupEmailAddressMatches(contactsManager, emailMatchType, fields):
def _createContact():
entityType = Ent.DOMAIN
contactsManager = ContactsManager()
fields = contactsManager.GetContactFields()
parameters = {'csvPF': None, 'titles': ['Domain', CONTACT_ID], 'addCSVData': {}, 'returnIdOnly': False}
fields = contactsManager.GetContactFields(parameters)
csvPF = parameters['csvPF']
addCSVData = parameters['addCSVData']
if addCSVData:
csvPF.AddTitles(sorted(addCSVData.keys()))
returnIdOnly = parameters['returnIdOnly']
contactEntry = contactsManager.FieldsToContact(fields)
user, contactsObject = getContactsObject(True)
try:
@@ -18698,15 +18723,27 @@ def _createContact():
throwErrors=[GDATA.BAD_REQUEST, GDATA.SERVICE_NOT_APPLICABLE, GDATA.FORBIDDEN],
retryErrors=[GDATA.INTERNAL_SERVER_ERROR],
new_contact=contactEntry, insert_uri=contactsObject.GetContactFeedUri(contact_list=user))
entityActionPerformed([entityType, user, Ent.CONTACT, contactsManager.GetContactShortId(contact)])
contactId = contactsManager.GetContactShortId(contact)
if returnIdOnly:
writeStdout(f'{contactId}\n')
elif not csvPF:
entityActionPerformed([entityType, user, Ent.CONTACT, contactId])
else:
row = {'Domain': user, CONTACT_ID: contactId}
if addCSVData:
row.update(addCSVData)
csvPF.WriteRow(row)
except GDATA.badRequest as e:
entityActionFailedWarning([entityType, user, Ent.CONTACT, ''], str(e))
except GDATA.forbidden:
entityServiceNotApplicableWarning(entityType, user)
except GDATA.serviceNotApplicable:
entityUnknownWarning(entityType, user)
if csvPF:
csvPF.writeCSVfile('Contacts')
# gam create contact <ContactAttribute>+
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
def doCreateDomainContact():
_createContact()
@@ -19648,7 +19685,7 @@ class PeopleManager():
}
@staticmethod
def GetPersonFields(entityType, allowAddRemove):
def GetPersonFields(entityType, allowAddRemove, parameters=None):
person = {}
contactGroupsLists = {
PEOPLE_GROUPS_LIST: [],
@@ -19717,6 +19754,10 @@ class PeopleManager():
person[fieldName].append(entry)
while Cmd.ArgumentsRemaining():
if parameters is not None:
if _getCreateContactReturnOptions(parameters):
continue
Cmd.Backup()
locations['fieldName'] = Cmd.Location()
fieldName = getChoice(PeopleManager.PEOPLE_ARGUMENT_TO_PROPERTY_MAP, mapChoice=True)
if '.' in fieldName:
@@ -19890,9 +19931,13 @@ class PeopleManager():
contactEntry[PEOPLE_MEMBERSHIPS].append({'contactGroupMembership': {'contactGroupResourceName': groupId}})
@staticmethod
def GetContactGroupFields():
def GetContactGroupFields(parameters=None):
contactGroup = {}
while Cmd.ArgumentsRemaining():
if parameters is not None:
if _getCreateContactReturnOptions(parameters):
continue
Cmd.Backup()
fieldName = getChoice(PeopleManager.PEOPLE_GROUP_ARGUMENT_TO_PROPERTY_MAP, mapChoice=True)
if fieldName == PEOPLE_GROUP_NAME:
contactGroup[PEOPLE_GROUP_NAME] = getString(Cmd.OB_STRING)
@@ -20238,12 +20283,19 @@ def validatePeopleContactGroupsList(people, contactId,
# gam <UserTypeEntity> create contact <PeopleContactAttribute>+
# (contactgroup <ContactGroupItem>)*
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
def createUserPeopleContact(users):
entityType = Ent.USER
peopleManager = PeopleManager()
peopleEntityType = Ent.CONTACT
sources = PEOPLE_READ_SOURCES_CHOICE_MAP['contact']
body, personFields, contactGroupsLists = peopleManager.GetPersonFields(entityType, False)
parameters = {'csvPF': None, 'titles': ['User', 'resourceName'], 'addCSVData': {}, 'returnIdOnly': False}
body, personFields, contactGroupsLists = peopleManager.GetPersonFields(entityType, False, parameters)
csvPF = parameters['csvPF']
addCSVData = parameters['addCSVData']
if addCSVData:
csvPF.AddTitles(sorted(addCSVData.keys()))
returnIdOnly = parameters['returnIdOnly']
i, count, users = getEntityArgument(users)
for user in users:
i += 1
@@ -20260,15 +20312,26 @@ def createUserPeopleContact(users):
else:
personFields.discard(PEOPLE_MEMBERSHIPS)
try:
person = callGAPI(people.people(), 'createContact',
result = callGAPI(people.people(), 'createContact',
throwReasons=GAPI.PEOPLE_ACCESS_THROW_REASONS+[GAPI.INVALID_ARGUMENT],
retryReasons=[GAPI.SERVICE_NOT_AVAILABLE],
personFields=','.join(personFields), body=body, sources=sources)
entityActionPerformed([entityType, user, peopleEntityType, person['resourceName']], i, count)
resourceName = result['resourceName']
if returnIdOnly:
writeStdout(f'{resourceName}\n')
elif not csvPF:
entityActionPerformed([entityType, user, peopleEntityType, resourceName], i, count)
else:
row = {'User': user, 'resourceName': resourceName}
if addCSVData:
row.update(addCSVData)
csvPF.WriteRow(row)
except GAPI.invalidArgument as e:
entityActionFailedWarning([entityType, user, peopleEntityType, None], str(e), i, count)
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
if csvPF:
csvPF.writeCSVfile('People Contacts')
def localPeopleContactSelects(contactQuery, contact):
if contactQuery['emailMatchPattern']:
@@ -21602,10 +21665,17 @@ def deleteUserPeopleContactPhoto(users):
_processPeopleContactPhotos(users, 'deleteContactPhoto')
# gam <UserTypeEntity> create contactgroup <ContactGroupAttribute>+
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
def createUserPeopleContactGroup(users):
peopleManager = PeopleManager()
entityType = Ent.USER
body, _ = peopleManager.GetContactGroupFields()
parameters = {'csvPF': None, 'titles': ['User', 'resourceName'], 'addCSVData': {}, 'returnIdOnly': False}
body, _ = peopleManager.GetContactGroupFields(parameters)
csvPF = parameters['csvPF']
addCSVData = parameters['addCSVData']
if addCSVData:
csvPF.AddTitles(sorted(addCSVData.keys()))
returnIdOnly = parameters['returnIdOnly']
i, count, users = getEntityArgument(users)
for user in users:
i += 1
@@ -21623,11 +21693,22 @@ def createUserPeopleContactGroup(users):
result = callGAPI(people.contactGroups(), 'create',
throwReasons=GAPI.PEOPLE_ACCESS_THROW_REASONS,
body={'contactGroup': body}, fields='resourceName')
entityActionPerformed([entityType, user, Ent.CONTACT_GROUP, result['resourceName']], i, count)
resourceName = result['resourceName']
if returnIdOnly:
writeStdout(f'{resourceName}\n')
elif not csvPF:
entityActionPerformed([entityType, user, Ent.CONTACT_GROUP, resourceName], i, count)
else:
row = {'User': user, 'resourceName': resourceName}
if addCSVData:
row.update(addCSVData)
csvPF.WriteRow(row)
except GAPI.forbidden:
entityServiceNotApplicableWarning(entityType, user, i, count)
except GAPI.serviceNotAvailable:
entityUnknownWarning(entityType, user, i, count)
if csvPF:
csvPF.writeCSVfile('People Contact Groups')
# gam <UserTypeEntity> update contactgroups <ContactGroupItem> <ContactAttribute>+
def updateUserPeopleContactGroup(users):