Clojure wrapper for the Google People API v1.
Provides idiomatic Clojure functions for the personal-contacts surface (CRUD on a user's own contacts + photos), contact-group labels (the user's organizational scheme on top of those contacts — list / get / batchGet / create / update / delete / members.modify), domain directory lookups (search + list), and the auto-collected "Other contacts" surface.
Auth: use csl/scoped-delegated-credentials with the appropriate scope and the impersonation target whose contacts you operate on:
This library wraps the contacts + contactGroups + directory + otherContacts surface. It does NOT wrap batchCreateContacts / batchUpdateContacts / batchDeleteContacts, otherContacts.copyOtherContactToMyContactsGroup, or the legacy Google Contacts v3 GData API — each waits for a real consumer need before being wrapped.
REQUIRED OPTS — VALIDATED AT THE WRAPPER The People API treats personFields / readMask / updatePersonFields as load-bearing. Omitting them produces opaque HTTP-400s from Google with poor diagnostics. The wrapper enforces them up-front:
contactGroups carries THREE distinct field-mask opts:
When required, omitted opts return {:error {:message "..." :type :missing-required-opt :opt :<the-key>}} without hitting the network.
ETAG CONTRACT (update-contact, update-contact-group) People API uses optimistic concurrency on Person AND ContactGroup updates. Caller must:
PAGINATION All list / search functions return {:data [...] :next-page-token "..."}. :next-page-token is absent when there are no further pages. Compatible with csl/execute-list-all for callers that want the full result set.
CLASS COLLISIONS Person, Name, EmailAddress, PhoneNumber, Address, Organization, Date, Status, Empty, Membership, Event, ContactGroup, CreateContactGroupRequest, UpdateContactGroupRequest, ModifyContactGroupMembersRequest model classes are intentionally NOT imported. Typed bodies are constructed via JSON round-trip through csl/clj->json + GsonFactory; responses are read via csl/->clj (java.util.Map walking). Only the service classes (PeopleService, PeopleService$Builder, PeopleServiceScopes) and GoogleNetHttpTransport are imported.
All functions return {:data ...} on success or {:error ...} on failure.
Clojure wrapper for the Google People API v1.
Provides idiomatic Clojure functions for the personal-contacts surface
(CRUD on a user's own contacts + photos), contact-group labels (the
user's organizational scheme on top of those contacts — list / get /
batchGet / create / update / delete / members.modify), domain
directory lookups (search + list), and the auto-collected "Other
contacts" surface.
Auth: use csl/scoped-delegated-credentials with the appropriate scope
and the impersonation target whose contacts you operate on:
- PeopleServiceScopes/CONTACTS_READONLY — reads on personal contacts
- PeopleServiceScopes/CONTACTS — full read+write on personal contacts
- PeopleServiceScopes/CONTACTS_OTHER_READONLY — reads on Other contacts only
- PeopleServiceScopes/DIRECTORY_READONLY — reads on the domain directory
- PeopleServiceScopes/USERINFO_EMAIL,
PeopleServiceScopes/USERINFO_PROFILE,
PeopleServiceScopes/USER_*_READ (granular per-field reads on the
authenticated user's own profile)
This library wraps the contacts + contactGroups + directory +
otherContacts surface. It does NOT wrap batchCreateContacts /
batchUpdateContacts / batchDeleteContacts,
otherContacts.copyOtherContactToMyContactsGroup, or the legacy Google
Contacts v3 GData API — each waits for a real consumer need before
being wrapped.
REQUIRED OPTS — VALIDATED AT THE WRAPPER
The People API treats personFields / readMask / updatePersonFields as
load-bearing. Omitting them produces opaque HTTP-400s from Google with
poor diagnostics. The wrapper enforces them up-front:
- Every read (get-person, get-people, list-connections, search-contacts,
create-contact, update-contact-photo, delete-contact-photo) REQUIRES
:person-fields — a comma-separated string of Person field paths
(e.g. "names,emailAddresses,phoneNumbers").
- Every directory + otherContacts read (search-directory-people,
list-directory-people, list-other-contacts, search-other-contacts)
REQUIRES :read-mask — same shape as :person-fields, distinct
parameter name in Google's API; we preserve that distinction.
- update-contact REQUIRES :etag (on the body, threaded through
:update-person-fields opt — the API uses optimistic concurrency).
- update-contact REQUIRES :update-person-fields — controls which
fields the API will modify (separate from :person-fields, which
controls the response shape).
- update-contact-group REQUIRES :update-group-fields (in opts —
controls which ContactGroup body fields the API will apply) AND
:etag (on the :contact-group body — optimistic concurrency).
- modify-contact-group-members REQUIRES at least one of
:resource-names-to-add / :resource-names-to-remove (non-empty).
contactGroups carries THREE distinct field-mask opts:
- :group-fields — query-param mask on list / get / batchGet,
controlling response shape. OPTIONAL —
Google does not reject if omitted, but
omitting yields a sparse ContactGroup
(resourceName + etag only). Strongly
recommended to pass it.
- :read-group-fields — body field on create / update, controlling
the RESPONSE shape after the write.
Optional.
- :update-group-fields — body field on update only, controlling
WHICH fields the API applies. Required.
When required, omitted opts return
{:error {:message "..."
:type :missing-required-opt
:opt :<the-key>}}
without hitting the network.
ETAG CONTRACT (update-contact, update-contact-group)
People API uses optimistic concurrency on Person AND ContactGroup
updates. Caller must:
1. Fetch the current resource via (get-person ...) / (get-contact-
group ...); the response carries :etag.
2. Pass that :etag through unchanged on the body of update-contact
(:etag on the Person body) or update-contact-group (:etag on the
:contact-group body, threaded inside the UpdateContactGroupRequest).
3. If the etag mismatches (concurrent write happened), Google rejects
with HTTP 400; caller refetches and retries.
The wrapper does NOT auto-refetch — it would hide a network call in
what is otherwise a thin pass-through layer.
PAGINATION
All list / search functions return {:data [...] :next-page-token "..."}.
:next-page-token is absent when there are no further pages. Compatible
with csl/execute-list-all for callers that want the full result set.
CLASS COLLISIONS
Person, Name, EmailAddress, PhoneNumber, Address, Organization,
Date, Status, Empty, Membership, Event, ContactGroup,
CreateContactGroupRequest, UpdateContactGroupRequest,
ModifyContactGroupMembersRequest model classes are intentionally NOT
imported. Typed bodies are constructed via JSON round-trip through
csl/clj->json + GsonFactory; responses are read via csl/->clj
(java.util.Map walking). Only the service classes
(PeopleService, PeopleService$Builder, PeopleServiceScopes) and
GoogleNetHttpTransport are imported.
All functions return {:data ...} on success or {:error ...} on failure.(create-contact client person & [opts])Create a new personal contact. person is a Clojure map of Person
fields with kebab-case keys (e.g. {:names [{:given-name "Alice"}]
:email-addresses [{:value "alice@example.com"}]}). JSON round-trip
populates the typed Person body.
:person-fields is OPTIONAL here (controls the response's Person shape; the create itself succeeds regardless). All other personal-contact writes require it; create is the exception.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Create a new personal contact. `person` is a Clojure map of Person
fields with kebab-case keys (e.g. {:names [{:given-name "Alice"}]
:email-addresses [{:value "alice@example.com"}]}). JSON round-trip
populates the typed Person body.
:person-fields is OPTIONAL here (controls the response's Person shape;
the create itself succeeds regardless). All other personal-contact
writes require it; create is the exception.
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :person-fields — optional; comma-separated field paths
controlling the returned Person shape.
- :sources — vector of READ_SOURCE_TYPE_* strings.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(create-contact-group client body & [opts])Create a new contact-group label. body is a Clojure map shaped
{:contact-group {:name "..."} :read-group-fields "..."}; only the
group :name is required by Google. JSON round-trip populates the typed
CreateContactGroupRequest body.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Create a new contact-group label. `body` is a Clojure map shaped
{:contact-group {:name "..."} :read-group-fields "..."}; only the
group :name is required by Google. JSON round-trip populates the typed
CreateContactGroupRequest body.
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(delete-contact client resource-name & [opts])Delete a personal contact by resource name (e.g. "people/c123"). Returns {:data :deleted} on success.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Delete a personal contact by resource name (e.g. "people/c123").
Returns {:data :deleted} on success.
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(delete-contact-group client resource-name & [opts])Delete a contact-group label by resource name.
:delete-contacts defaults to false at Google — passing it as true is DESTRUCTIVE: it deletes every contact contained in the group in addition to the group label itself. The wrapper does NOT default- guard; callers must opt in explicitly.
System contact-groups (e.g. "myContacts", "starred") cannot be deleted — Google rejects with HTTP 400.
Returns {:data :deleted} on success.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Delete a contact-group label by resource name.
:delete-contacts defaults to false at Google — passing it as true is
DESTRUCTIVE: it deletes every contact contained in the group in
addition to the group label itself. The wrapper does NOT default-
guard; callers must opt in explicitly.
System contact-groups (e.g. "myContacts", "starred") cannot be
deleted — Google rejects with HTTP 400.
Returns {:data :deleted} on success.
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :delete-contacts — boolean (default false). TRUE also deletes
the contacts contained in the group.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(delete-contact-photo client resource-name & [opts])Delete a contact's photo. The contact resource itself remains; only its photo URL is removed. Returns the updated person (sans photo) on success.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Delete a contact's photo. The contact resource itself remains; only its photo URL is removed. Returns the updated person (sans photo) on success. Scope: PeopleServiceScopes/CONTACTS. opts: - :person-fields — optional; controls the returned Person shape. - :sources — vector of READ_SOURCE_TYPE_* strings. - :fields — partial response field mask string. - :read-timeout-ms — per-request read timeout override. - :connect-timeout-ms — per-request connect timeout override.
(get-contact-group client resource-name & [opts])Get a single contact-group by resource name (e.g. "contactGroups/abc123").
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
Get a single contact-group by resource name (e.g. "contactGroups/abc123").
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
- :group-fields — OPTIONAL but strongly recommended. Comma-
separated ContactGroup field paths
(e.g. "name,formattedName,memberCount,
groupType"). Omitting yields a sparse
ContactGroup with only resourceName + etag.
Google does not reject omission.
- :max-members — int; when set, inlines up to this many
member resource names on the returned group.
Omit to return no members.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(get-contact-groups client & [opts])Batch-fetch contact-groups by resource name (Google caps at 200 per call). Returns a BatchGetContactGroupsResponse with :responses (list of ContactGroupResponse, each carrying its own :status + :contact-group). Use csl/execute-get; this is NOT a paginated list.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
Batch-fetch contact-groups by resource name (Google caps at 200 per
call). Returns a BatchGetContactGroupsResponse with :responses
(list of ContactGroupResponse, each carrying its own :status +
:contact-group). Use csl/execute-get; this is NOT a paginated list.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
- :resource-names — vector of "contactGroups/{id}" strings (cap 200).
- :group-fields — OPTIONAL but strongly recommended; same shape
as get-contact-group.
- :max-members — int; inlines up to this many members per
group on the response.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(get-people client resource-names & [{:keys [person-fields] :as opts}])Batch-lookup people by a vector of resource names. Up to 200 names per call per Google's documented limit (the wrapper does NOT enforce — let Google reject if exceeded so we don't drift if the limit moves).
Response shape carries :responses (vector of {:requested-resource-name :status :person}), one per requested name.
:person-fields is REQUIRED.
Scope: CONTACTS_READONLY (personal contacts) / DIRECTORY_READONLY (directory entries, when :sources includes a DIRECTORY_SOURCE_TYPE_*).
opts:
Batch-lookup people by a vector of resource names. Up to 200 names per
call per Google's documented limit (the wrapper does NOT enforce — let
Google reject if exceeded so we don't drift if the limit moves).
Response shape carries :responses (vector of {:requested-resource-name
:status :person}), one per requested name.
`:person-fields` is REQUIRED.
Scope: CONTACTS_READONLY (personal contacts) / DIRECTORY_READONLY
(directory entries, when :sources includes a DIRECTORY_SOURCE_TYPE_*).
opts:
- :person-fields — REQUIRED.
- :sources — vector of READ_SOURCE_TYPE_* strings.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(get-person client resource-name & [{:keys [person-fields] :as opts}])Get a single person by resource name (e.g. "people/c123" for a contact, "people/me" for the impersonated user).
:person-fields is REQUIRED.
Scope: PeopleServiceScopes/CONTACTS_READONLY (for personal contacts); USERINFO_* / USER_*_READ for the authenticated-user surface; DIRECTORY_READONLY when fetching a directory person.
opts:
Get a single person by resource name (e.g. "people/c123" for a contact, "people/me" for the impersonated user). `:person-fields` is REQUIRED. Scope: PeopleServiceScopes/CONTACTS_READONLY (for personal contacts); USERINFO_* / USER_*_READ for the authenticated-user surface; DIRECTORY_READONLY when fetching a directory person. opts: - :person-fields — REQUIRED. - :sources — vector of READ_SOURCE_TYPE_* strings. - :fields — partial response field mask string. - :read-timeout-ms — per-request read timeout override. - :connect-timeout-ms — per-request connect timeout override.
(list-connections client & [{:keys [person-fields] :as opts}])List a user's personal contacts (Connections). The response key is :connections.
:person-fields is REQUIRED. Returns {:error ...} without hitting
the network when omitted.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
List a user's personal contacts (Connections). The response key is
:connections.
`:person-fields` is REQUIRED. Returns {:error ...} without hitting
the network when omitted.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
- :resource-name — the user whose contacts to list. Defaults to
"people/me" (the impersonated user); pass
"people/{accountId}" to list another
account's contacts (admin scope required).
- :person-fields — REQUIRED. Comma-separated Person field paths
(e.g. "names,emailAddresses,phoneNumbers").
- :sources — vector of READ_SOURCE_TYPE_* strings (e.g.
["READ_SOURCE_TYPE_CONTACT"
"READ_SOURCE_TYPE_PROFILE"]).
- :sort-order — :first-name-ascending | :last-name-ascending |
:last-modified-ascending |
:last-modified-descending (or raw string).
- :page-size, :page-token — pagination. Compatible with
csl/execute-list-all.
- :sync-token — opaque token from a prior response with
:request-sync-token true; returns only
changes since that point.
- :request-sync-token — boolean; when true, the response includes
a :next-sync-token suitable for future
incremental sync.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(list-contact-groups client & [opts])List the impersonated user's contact-groups. Items key: :contact-groups.
Compatible with csl/execute-list-all for full enumeration.
For typical inventory use cases (e.g., counting user-created groups), filter the response on :group-type — Google returns both "USER_CONTACT_GROUP" (user-created) and "SYSTEM_CONTACT_GROUP" (built-ins like "myContacts", "starred", "all", "chatBuddies", "friends", "family", "coworkers"). The wrapper does not filter.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
List the impersonated user's contact-groups. Items key: :contact-groups.
Compatible with csl/execute-list-all for full enumeration.
For typical inventory use cases (e.g., counting user-created groups),
filter the response on :group-type — Google returns both
"USER_CONTACT_GROUP" (user-created) and "SYSTEM_CONTACT_GROUP"
(built-ins like "myContacts", "starred", "all", "chatBuddies",
"friends", "family", "coworkers"). The wrapper does not filter.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
- :group-fields — OPTIONAL but strongly recommended.
- :page-size, :page-token — pagination.
- :sync-token — opaque token from a prior response; subsequent
calls return only changes since that point.
(No :request-sync-token flag — Google returns
:next-sync-token automatically when you reach
the last page.)
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(list-directory-people client & [{:keys [read-mask sources] :as opts}])List people in the domain directory (paginated full enumeration). Complements search-directory-people for cases where the consumer wants the entire directory rather than a query match. Response key is :people.
:read-mask and :sources are REQUIRED — the API rejects calls without
a source selection.
Scope: PeopleServiceScopes/DIRECTORY_READONLY.
opts:
List people in the domain directory (paginated full enumeration).
Complements search-directory-people for cases where the consumer wants
the entire directory rather than a query match. Response key is :people.
`:read-mask` and `:sources` are REQUIRED — the API rejects calls without
a source selection.
Scope: PeopleServiceScopes/DIRECTORY_READONLY.
opts:
- :read-mask — REQUIRED.
- :sources — REQUIRED. Vector of DIRECTORY_SOURCE_TYPE_*
strings.
- :merge-sources — vector of DIRECTORY_MERGE_SOURCE_TYPE_* strings.
- :page-size, :page-token — pagination; compatible with
csl/execute-list-all.
- :sync-token — opaque token from a prior response with
:request-sync-token true; returns only
changes since that point.
- :request-sync-token — boolean; response includes :next-sync-token
for future incremental sync.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(list-other-contacts client & [{:keys [read-mask] :as opts}])List "Other contacts" — auto-suggested people the user has interacted with but not explicitly added to their personal contacts. Response key is :other-contacts.
:read-mask is REQUIRED (not :person-fields — the API uses readMask
on the otherContacts surface).
Scope: PeopleServiceScopes/CONTACTS_OTHER_READONLY (or CONTACTS).
opts:
List "Other contacts" — auto-suggested people the user has interacted
with but not explicitly added to their personal contacts. Response key
is :other-contacts.
`:read-mask` is REQUIRED (not :person-fields — the API uses readMask
on the otherContacts surface).
Scope: PeopleServiceScopes/CONTACTS_OTHER_READONLY (or CONTACTS).
opts:
- :read-mask — REQUIRED. Comma-separated Person field paths.
Only emailAddresses / phoneNumbers / names /
metadata / photos are supported (per Google
docs; the wrapper does not enforce — let the
API reject if invalid).
- :sources — vector of READ_SOURCE_TYPE_* strings.
- :page-size, :page-token — pagination; compatible with
csl/execute-list-all.
- :sync-token — opaque token from a prior response with
:request-sync-token true.
- :request-sync-token — boolean; response includes :next-sync-token.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(modify-contact-group-members client resource-name body & [opts])Add and/or remove members from a contact-group. Returns ModifyContactGroupMembersResponse carrying :not-found-resource-names and :can-not-remove-last-contact-group-resource-names — the wrapper does NOT pre-validate that the named contacts exist or that the group permits removal; Google reports these failures in the response body.
System contact-groups reject modify with HTTP 400 — members are auto-managed.
At least one of :resource-names-to-add / :resource-names-to-remove must be non-empty; the wrapper rejects empty modifies up-front (Google does too with HTTP 400, but the wrapper saves the round-trip).
Scope: PeopleServiceScopes/CONTACTS.
body:
opts:
Add and/or remove members from a contact-group. Returns
ModifyContactGroupMembersResponse carrying :not-found-resource-names
and :can-not-remove-last-contact-group-resource-names — the wrapper
does NOT pre-validate that the named contacts exist or that the group
permits removal; Google reports these failures in the response body.
System contact-groups reject modify with HTTP 400 — members are
auto-managed.
At least one of :resource-names-to-add / :resource-names-to-remove
must be non-empty; the wrapper rejects empty modifies up-front (Google
does too with HTTP 400, but the wrapper saves the round-trip).
Scope: PeopleServiceScopes/CONTACTS.
body:
- :resource-names-to-add — vector of "people/{accountId}" strings.
- :resource-names-to-remove — vector of "people/{accountId}" strings.
opts:
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(people-client credentials)(people-client credentials opts)Build an authenticated People API v1 client.
credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with one of the PeopleServiceScopes values and the user whose contacts/directory you intend to operate on.
opts (optional):
Per-request opts on individual call sites override the client-level defaults.
Build an authenticated People API v1 client. credentials — a com.google.auth.oauth2.GoogleCredentials instance, typically from csl/scoped-delegated-credentials with one of the PeopleServiceScopes values and the user whose contacts/directory you intend to operate on. opts (optional): - :read-timeout-ms per-client default read timeout (default 120000 / 120s) - :connect-timeout-ms per-client default connect timeout (default 30000 / 30s) Per-request opts on individual call sites override the client-level defaults.
(search-contacts client & [{:keys [query read-mask] :as opts}])Search the impersonated user's personal contacts. Response shape carries :results (vector of {:person ...} maps).
:query and :read-mask are REQUIRED.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
Search the impersonated user's personal contacts. Response shape carries
:results (vector of {:person ...} maps).
`:query` and `:read-mask` are REQUIRED.
Scope: PeopleServiceScopes/CONTACTS_READONLY (or CONTACTS).
opts:
- :query — REQUIRED. Free-text query (matches against
names, emails, phone, etc.).
- :read-mask — REQUIRED. Comma-separated field paths
(e.g. "names,emailAddresses").
- :sources — vector of READ_SOURCE_TYPE_* strings.
- :page-size — int (no :page-token; not paginated).
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(search-directory-people client & [{:keys [query read-mask] :as opts}])Search the domain directory (people in the same Workspace org). Response shape carries :people (vector of Person maps).
:query and :read-mask are REQUIRED. :sources is also
effectively required by the API in most cases (the wrapper does
not enforce this — see Google docs).
Scope: PeopleServiceScopes/DIRECTORY_READONLY (NOT contacts.readonly, despite what some external docs suggest).
opts:
Search the domain directory (people in the same Workspace org).
Response shape carries :people (vector of Person maps).
`:query` and `:read-mask` are REQUIRED. `:sources` is also
effectively required by the API in most cases (the wrapper does
not enforce this — see Google docs).
Scope: PeopleServiceScopes/DIRECTORY_READONLY (NOT contacts.readonly,
despite what some external docs suggest).
opts:
- :query — REQUIRED. Free-text query.
- :read-mask — REQUIRED.
- :sources — vector of DIRECTORY_SOURCE_TYPE_* strings
(e.g. ["DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE"
"DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT"]).
- :merge-sources — vector of DIRECTORY_MERGE_SOURCE_TYPE_*
strings, controlling how directory + connection
data are merged.
- :page-size, :page-token — pagination; compatible with
csl/execute-list-all.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(search-other-contacts client & [{:keys [query read-mask] :as opts}])Search "Other contacts". Response key is :results (vector of {:person}).
:query and :read-mask are REQUIRED.
Scope: PeopleServiceScopes/CONTACTS_OTHER_READONLY (or CONTACTS).
opts:
Search "Other contacts". Response key is :results (vector of {:person}).
`:query` and `:read-mask` are REQUIRED.
Scope: PeopleServiceScopes/CONTACTS_OTHER_READONLY (or CONTACTS).
opts:
- :query — REQUIRED. Free-text query.
- :read-mask — REQUIRED.
- :page-size — int (no :page-token; not paginated).
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(update-contact client
resource-name
person
&
[{:keys [update-person-fields] :as opts}])Update an existing personal contact. People API uses optimistic concurrency — caller must:
person (the body of this call), unchanged.If the etag mismatches (concurrent write happened), Google rejects with HTTP 400; refetch and retry.
:update-person-fields and (:etag person) are BOTH REQUIRED — the wrapper validates both before hitting the network.
Scope: PeopleServiceScopes/CONTACTS.
opts:
Update an existing personal contact. People API uses optimistic
concurrency — caller must:
1. Fetch the contact via get-person; response carries :etag.
2. Include that :etag on `person` (the body of this call), unchanged.
3. Pass :update-person-fields naming which fields the API should
apply from the body. Fields outside this mask are NOT modified
even if present in the body.
If the etag mismatches (concurrent write happened), Google rejects
with HTTP 400; refetch and retry.
:update-person-fields and (:etag person) are BOTH REQUIRED — the
wrapper validates both before hitting the network.
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :update-person-fields — REQUIRED. Comma-separated field paths the
API should apply (e.g.
"names,emailAddresses,phoneNumbers").
- :person-fields — optional; controls the returned Person shape.
- :sources — vector of READ_SOURCE_TYPE_* strings.
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(update-contact-group client resource-name body & [opts])Update an existing contact-group (typically renaming it). People API uses optimistic concurrency — caller must:
:update-group-fields and (:etag (:contact-group body)) are BOTH REQUIRED — the wrapper validates both before hitting the network.
On etag mismatch (concurrent write happened), Google rejects with HTTP 400; caller refetches and retries.
Scope: PeopleServiceScopes/CONTACTS.
body:
opts:
Update an existing contact-group (typically renaming it). People API
uses optimistic concurrency — caller must:
1. Fetch the current group via get-contact-group; response carries
:etag.
2. Include that :etag on the :contact-group body, unchanged.
3. Pass :update-group-fields naming which fields the API should apply
from the body. Fields outside this mask are NOT modified even if
present in the body.
:update-group-fields and (:etag (:contact-group body)) are BOTH
REQUIRED — the wrapper validates both before hitting the network.
On etag mismatch (concurrent write happened), Google rejects with
HTTP 400; caller refetches and retries.
Scope: PeopleServiceScopes/CONTACTS.
body:
- :contact-group — map of fields to send. MUST include :etag
from a prior get-contact-group. The :name
field is the only mutable user field for
USER_CONTACT_GROUP.
- :update-group-fields — REQUIRED. Comma-separated ContactGroup
field paths the API should apply
(e.g. "name,clientData").
- :read-group-fields — optional; controls returned ContactGroup shape.
opts:
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.(update-contact-photo client resource-name body & [opts])Update a contact's photo. body is a Clojure map:
{:photo-bytes "<base64-encoded-image-bytes>"
:person-fields "names,photos" ; optional; response shape
:sources ["READ_SOURCE_TYPE_CONTACT"]} ; optional
Returns the updated person (with the new photo URL) on success.
:photo-bytes is REQUIRED on the body — the wrapper validates before hitting the network. The API expects standard base64 (not URL-safe variant); callers encoding image bytes should use (.encodeToString (java.util.Base64/getEncoder) bytes).
Scope: PeopleServiceScopes/CONTACTS.
opts:
Update a contact's photo. `body` is a Clojure map:
{:photo-bytes "<base64-encoded-image-bytes>"
:person-fields "names,photos" ; optional; response shape
:sources ["READ_SOURCE_TYPE_CONTACT"]} ; optional
Returns the updated person (with the new photo URL) on success.
:photo-bytes is REQUIRED on the body — the wrapper validates before
hitting the network. The API expects standard base64 (not URL-safe
variant); callers encoding image bytes should use
(.encodeToString (java.util.Base64/getEncoder) bytes).
Scope: PeopleServiceScopes/CONTACTS.
opts:
- :fields — partial response field mask string.
- :read-timeout-ms — per-request read timeout override.
- :connect-timeout-ms — per-request connect timeout override.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |