Contacts
`contacts.list`, `get`, `create`, `save`, `update`, `set_audiences`, `delete`, `delete_many`, `list_people`, `set_photo`, `remove_photo`, `block`, `unblock`, `list_threads` et `activity`.
Toutes les méthodes
page = client.contacts.list(limit: 100)contact = client.contacts.get("[email protected]") saved = client.contacts.create( email: "[email protected]", name: "Grace Hopper", notes: "Met at the compiler workshop") client.contacts.update("[email protected]", notes: nil)client.contacts.set_audiences("[email protected]", audienceIds: ["aud_4c1b8e2a7d9f05c36b4e8a71"])client.contacts.delete("[email protected]") puts page.items.size, page.has_more?, contact[:source], contact[:lastSeenAt], saved[:source]list renvoie d'abord les contacts vus le plus récemment, et en dernier les contacts à qui rien n'a jamais été envoyé. source vaut auto quand la ligne a été écrite parce qu'un membre a envoyé un message à cette adresse depuis le compositeur de l'application, ce qui est une affirmation sensiblement différente de « quelqu'un l'a enregistrée ». Le courrier qui arrive d'une adresse n'écrit rien, et un envoi via cette API non plus.
Le carnet appartient à l'espace de travail plutôt qu'à une personne : un contact enregistré par un membre est donc le contact que voient tous les membres et toutes les clés. create écrit source à manual et place le contact dans l'audience par défaut au moment de l'écriture. Nommez vos propres listes dans audienceIds pour l'y ajouter dans le même appel, ce qui exige aussi audiences:write, ou ajoutez le contact plus tard avec audiences.add_contact, que couvre la page Audiences. set_audiences indique exactement dans quelles listes se trouve un contact, en un seul appel.
Les adresses sont stockées en minuscules et la gem encode celle que vous passez : [email protected] atteint donc la bonne ligne. Une adresse nil ou vide lève ArgumentError avant tout envoi. L'adresse est l'identité : update ne peut donc pas la changer, et déplacer un contact, c'est un delete puis un create.
Paramètres : contacts.list
limitInteger- Combien de contacts renvoyer par page : un entier de 1 à 200, 50 par défaut. Il est converti : une String comme `"100"` lue dans une query string convient donc, et une valeur hors de l'intervalle donne un 422 plutôt qu'une valeur ramenée aux bornes.
cursorString- Le `next_cursor` de la page précédente. N'en construisez jamais un vous-même : un curseur nommant un contact qui n'existe plus donne un 400 `invalid_cursor`, levé sous forme d'`OpenEmail::InvalidRequestError`, ce qui signifie que votre état de pagination est périmé et que le parcours doit repartir sans curseur.
sourceString- `manual` pour les contacts que quelqu'un a enregistrés exprès, `auto` pour ceux qu'a enregistrés le compositeur de l'application. Omettez-le pour le carnet entier.
qString- Cherche dans le nom et l'adresse, jusqu'à 200 caractères. Si rien ne correspond exactement sur la première page, des orthographes proches sont renvoyées à la place, et les pages suivantes continuent de chercher de la même façon.
Réponse : un contact
contacts.list renvoie une OpenEmail::Page : les lignes sont donc dans page.items et le parcours suit page.next_cursor tant que page.has_more? vaut true. list_all renvoie toutes les lignes dans un seul Array, et iterate les passe une par une. get, create, update, save et set_audiences renvoient chacun un contact sous forme de Hash à clés Symbol, la même ligne plus audiences. Le carnet d'adresses est illimité, c'est pourquoi cette route pagine plutôt que de renvoyer un Array qui s'arrêterait silencieusement à 200.
objectString- Toujours la chaîne `contact`, sur les lignes de liste comme sur `get`.
emailString- L'adresse, mise en minuscules à l'écriture pour que `[email protected]` et `[email protected]` ne fassent qu'un seul contact, et la clé que prend chaque méthode contacts, puisqu'aucun id de contact n'est exposé. Les lignes appartiennent à l'espace de travail plutôt qu'au membre ou à la clé qui les a écrites : chaque membre et chaque clé de l'espace lisent et écrivent donc un seul carnet d'adresses.
nameString or nil- Le nom affiché, ou nil quand aucun nom n'a jamais été enregistré pour l'adresse. Une écriture automatique n'en porte un que si l'en-tête fournissait autre chose que l'adresse elle-même, et elle ne peut jamais écraser un nom saisi par l'utilisateur.
sourceString- `auto` signifie que la ligne a été écrite parce que l'utilisateur a envoyé du courrier à cette adresse. `manual` signifie que quelqu'un l'a saisie à la main, une affirmation sensiblement différente, et un upsert ne rétrograde jamais `manual` en `auto`. Le courrier qui arrive d'une adresse n'écrit aucune ligne, délibérément : quelqu'un qui n'a jamais fait que vous écrire ne figure donc pas ici. Traitez la valeur comme une String ouverte, car la colonne est un texte libre qui vaut `manual` par défaut.
notesString or nil- Texte libre que quelqu'un a écrit sur cette personne, dans l'application ou via `update`, jamais généré. nil quand personne n'en a écrit, et `notes: nil` sur `update` l'efface.
lastSeenAtString or nil- Une chaîne ISO 8601 UTC, avancée chaque fois qu'un membre écrit à cette adresse depuis le compositeur de l'application, et non quand du courrier en arrive, ce qui n'écrit rien. nil sur un contact enregistré via `create` à qui rien n'a jamais été envoyé, et ceux-là arrivent en dernier dans l'ordre décroissant de `lastSeenAt` que renvoie cette route.
audiencesArray<Hash>- Uniquement sur `get`, `create`, `update`, `save` et `set_audiences`, jamais sur les lignes de liste. Chaque audience dont le contact fait partie, l'audience par défaut comprise, sous forme de Hash avec `id`, `name` et `builtin`. `builtin` vaut `default` sur l'audience à laquelle appartient chaque contact et nil sur une audience créée par quelqu'un : branchez-vous donc dessus plutôt que sur le nom, que n'importe qui peut changer.
photoUrlString or nil- L'endroit où la photo du contact est servie, ou nil quand le contact n'en a pas. `set_photo` la définit et chaque téléversement reçoit une nouvelle URL.
Définir les audiences d'un contact
set_audiences(email, audienceIds: [...]) dit exactement dans quelles audiences se trouve un contact, en une seule requête. Le contact rejoint chaque audience indiquée où il n'est pas encore et quitte toutes les autres, et l'appel renvoie le contact après le changement, avec ses audiences. Il nécessite audiences:write, car il écrit des appartenances et non le contact, et le répéter ne change rien : la gem le réessaie donc après un échec réseau.
L'audience par défaut est toujours conservée : audienceIds: [] laisse donc le contact dans la seule audience par défaut. Il accepte jusqu'à 100 ids. Un id qui ne désigne aucune audience de cet espace de travail donne un 404 audience_not_found et rien ne change, et une adresse qui n'est pas un contact donne un 404 contact_not_found. Les deux lèvent OpenEmail::NotFoundError.
Tout le monde sur la page Contacts
list_people liste les personnes que montre la page Contacts de l'application : les contacts enregistrés et chaque adresse vue dans le courrier, chacune avec saved, threads et lastAt, et renvoie une OpenEmail::PeoplePage, qui ajoute seen à items, has_more? et next_cursor. list ne donne en revanche que les contacts enregistrés. Les adresses vues dans le courrier ne viennent que si la clé détient aussi threads:read, et page.seen dit si c'est le cas. sort: vaut recent, name ou threads, et OpenEmail::PEOPLE_SORTS les nomme. q: cherche dans les noms, les adresses et les notes, et blocked: true garde les personnes que bloque la liste de blocage de l'espace de travail, règles sur des domaines entiers comprises. blockedBy nomme la règle sur chaque ligne.
page = client.contacts.list_people(sort: "threads", limit: 50) page.items.each do |person| client.contacts.save(person[:email]) if !person[:saved] && person[:threads].to_i > 5end blocked = client.contacts.list_all_people(blocked: true)puts page.seen, blocked.sizelist_all_people renvoie toutes les pages dans un seul Array, et iterate_people passe chaque personne à un bloc, ou renvoie un Enumerator sans bloc. Aucun des deux n'indique seen : lisez donc une page avec list_people pour le connaître. Le curseur est opaque : renvoyez next_cursor comme cursor: exactement tel qu'il est venu, avec les mêmes sort:, q: et blocked:.
Enregistrer, supprimer et photos
save(email), avec name: et notes: optionnels, correspond à Ajouter aux contacts et Garder dans les contacts : il enregistre une adresse qui n'est pas encore un contact, garde comme enregistrée à la main une adresse relevée lors d'un envoi, et ramène une adresse supprimée. delete correspond à Supprimer : il retire le contact enregistré et masque l'adresse, pour que le compositeur ne l'enregistre plus, et il accepte aussi une adresse seulement vue dans le courrier. wasSaved, dans le Hash qu'il renvoie, indique de quel cas il s'agissait. delete_many en supprime jusqu'à 200 en un seul appel.
client.contacts.save("[email protected]", name: "Grace Hopper") contact = client.contacts.set_photo("[email protected]", File.binread("photo.jpg"), content_type: "image/jpeg")puts contact[:photoUrl] client.contacts.set_photo("[email protected]", Pathname("photo.png")) client.contacts.remove_photo("[email protected]")client.contacts.delete_many(["[email protected]", "[email protected]"])set_photo envoie les octets de l'image tels quels : PNG, JPEG, WebP ou GIF jusqu'à 5 Mo, ajusté dans un carré de 512 pixels. Les octets sont une String binaire, un IO ou un Pathname. Passez content_type:, ou des octets qui portent leur propre type : un objet qui répond à content_type, comme un upload Rails, ou un File ou un Pathname dont le nom se termine par .png, .jpg, .jpeg, .webp ou .gif. Sans type, les octets partent en application/octet-stream, que le serveur refuse avec un 422 invalid_image. OpenEmail::CONTACT_PHOTO_TYPES nomme les quatre types. L'adresse doit d'abord être un contact enregistré.
Blocage
block(email) met l'adresse sur la liste de blocage de l'espace de travail pour que son courrier soit refusé, en retirant toute étiquette plus, et unblock(email) retire chaque règle qui la bloque. Les deux demandent settings:write, car ils modifient la liste de blocage et non le contact, et aucun n'exige que l'adresse soit un contact.
Quand unblock lève une règle sur un domaine entier, removed la liste avec list à blockedDomains, et tout le monde sur ce domaine est débloqué avec elle. OpenEmail::CONTACT_BLOCK_LISTS nomme les deux listes.
Conversations et activité
list_threads(email) parcourt page par page les fils que l'adresse a écrits ou qui lui ont été écrits, dans tous les dossiers, et list_all_threads et iterate_threads les parcourent entièrement. activity(email) renvoie les chiffres derrière l'onglet Activité d'un contact : reçus et envoyés par intervalle, fils qui attendent votre réponse, et temps de réponse médian dans chaque sens. Les deux demandent threads:read.
threads = client.contacts.list_threads("[email protected]", q: "invoice") activity = client.contacts.activity( "[email protected]", minutes: 30 * 24 * 60, grain: "day", offset_minutes: Time.now.utc_offset / 60) puts threads.items.size, activity.dig(:totals, :waiting)activity prend des mots-clés en snake_case. minutes: définit la fenêtre, de 90 jours quand il est omis. grain: définit la largeur des intervalles : minute, hour ou day. offset_minutes: définit le nombre de minutes à l'est d'UTC où les jours se coupent. Time.now.utc_offset / 60 est le décalage local, et la gem l'envoie comme offsetMinutes de l'API.