Ir a la documentación
Python

Miembros

`members.list`, `list_all`, `iterate`, `get`, `add`, `update`, `remove`, `grant_address`, `revoke_address` y los métodos de invitaciones junto a ellos.

Todos los métodos

members.py
from openemail import openemail roles = openemail.roles.list_all()support = next(role for role in roles if role['name'] == 'Support')viewer = next(role for role in roles if role['builtin'] == 'viewer') invitation = openemail.members.add({    'email': '[email protected]',    'roleId': support['id'],    'addressIds': ['2b81de07-…'],    'access': 'member',}) people = openemail.members.list_all()sam = next(person for person in people if person['email'] == '[email protected]')member = openemail.members.get(sam['userId']) openemail.members.update(sam['userId'], {'roleId': viewer['id']}) openemail.members.grant_address(sam['userId'], {    'addressId': 'c40a95f2-…',    'access': 'viewer',})openemail.members.revoke_address(sam['userId'], 'c40a95f2-…') openemail.members.remove(sam['userId'])

Dos concesiones por persona, y no deben fusionarse. role es lo que puede hacer; addresses es aquello sobre lo que puede hacerlo. Ambas tienen que coincidir: un rol con emails:send y 'access': 'viewer' sobre invoices@ es alguien que puede enviar correo y no puede enviarlo desde esa dirección. La excepción es un rol con addresses:all, que llega a todas las direcciones liste lo que liste addresses, porque esa lista solo contiene concesiones directas, así que comprueba permissions antes de leerla como todo el alcance de alguien.

Todos los métodos reciben el userId, no el correo. add es la única excepción, porque invita a una dirección: la persona solo tiene un userId una vez que acepta, y list_invitations sigue la invitación hasta entonces.

'implied': True significa que nadie eligió el rol. La persona tiene direcciones y ninguna fila de rol, así que se dedujo a partir de la concesión más amplia que posee. Trátalo como «aún sin decidir»: update es lo que convierte la inferencia en una decisión. Hasta entonces, ampliar su acceso a direcciones amplía en silencio lo que puede hacer.

El propietario del espacio de trabajo es la primera fila, marcada con 'isOwner': True, mientras que add, update y remove lo siguen rechazando con member_is_owner. Un espacio de trabajo sin compartir informa de un miembro y no de ninguno, así que excluye isOwner cuando cuentes puestos.

remove actúa sobre los dos ejes: el rol Y todas las concesiones de direcciones en este espacio de trabajo, e informa de addressesRevoked. revoke_address es el acotado, para alguien que cambió de equipo y no para alguien que se marchó.

Parámetros

emailstrobligatorio
A quién invitar, recortado y en minúsculas. Todavía no necesita una cuenta: se invita a cualquiera, y el rol y las concesiones se aplican cuando acepta. Alguien que ya está en el espacio de trabajo devuelve `member_is_owner` (422).
roleIdstrobligatorio
El rol que tendrá, de 1 a 128 caracteres, y debe ser un rol de este espacio de trabajo: un id desconocido es `role_not_found` (404). El rol de propietario no se puede repartir y devuelve `role_immutable` (409), porque convertir a alguien en propietario es una transferencia del espacio de trabajo y aquí no hay ninguna llamada para eso.
addressIdslist[str]
Direcciones que lleva la invitación, como máximo 64 ids de 1 a 128 caracteres cada uno, concedidas cuando se acepta. Cada id se comprueba antes de escribir nada, así que uno que no corresponde a una dirección de este espacio de trabajo hace que se rechace toda la llamada con 422 `member_not_found` y no se envía nada. Invitar de nuevo a la misma dirección en menos de diez minutos es 409 `invitation_too_soon`.
accessLiteral['member', 'viewer']
Lo que puede hacer con cada id de `addressIds`: `member` lee la dirección y envía desde ella; `viewer` solo la lee. El valor por defecto es `member`, el nivel que siempre han usado la consola y la antigua vía de compartición, de modo que la misma llamada significa lo mismo desde un script y desde una pantalla; para conceder una combinación, llama después a `grant_address` para las que difieran.

Respuesta

objectLiteral['member']
Siempre `member`. Una eliminación responde con el mismo valor, su `userId`, `'deleted': True` y `addressesRevoked`, y ninguno de los demás campos de abajo.
userIdstr
El id de su cuenta, y el identificador que todas las demás llamadas de miembros reciben en la ruta: get, update, remove y las dos llamadas de direcciones. Añadir a alguien es la única llamada que funciona a partir de un correo, porque quien añade a un compañero conoce su dirección y no su id.
emailstr
El correo de su cuenta, devuelto tal como lo guarda esa fila. Este recurso nunca lo escribe, y la conversión a minúsculas de `add` se aplica a la dirección que envías para la búsqueda, no a lo que vuelve. Después del propietario, la lista de miembros se ordena por él y no por la fecha de incorporación, porque la lista se lee para encontrar a una persona y no para ver qué cambió.
namestr | None
Su nombre visible, tomado de su cuenta, donde la columna es NOT NULL. El `None` del tipo es defensivo, no un estado que se haya visto producir a esta API. Pertenece a la persona y no al espacio de trabajo, así que nada de este recurso puede establecerlo.
imagestr | None
Su avatar, tomado de su cuenta, y null cuando no ha configurado ninguno.
role.idstr | None
El id del rol que tiene, o null cuando nadie lo eligió. Véase `implied`. Un null aquí es el único caso en el que `role` informa de una inferencia y no de una decisión que alguien tomó.
role.namestr
El nombre del rol. Para un miembro implícito es el nombre de la plantilla integrada a la que se resolvió su acceso, no una fila de este espacio de trabajo.
role.builtinLiteral['owner', 'admin', 'member', 'viewer', 'developer', 'billing'] | None
Qué rol integrado es, o null si es personalizado. `owner` aparece únicamente en la fila del propio propietario, junto a `'isOwner': True`; asignar ese rol a alguien se rechaza con `role_immutable` (409).
isOwnerbool
True en exactamente una fila: la cuenta a la que está vinculado el espacio de trabajo. Tiene todos los permisos diga lo que diga su fila de rol, se ordena en primer lugar, y `add`, `update` y `remove` la rechazan con `member_is_owner`. Exclúyela cuando cuentes puestos.
impliedbool
True cuando esta persona tiene concesiones de direcciones y ninguna fila de miembro, de modo que su rol se dedujo en vez de elegirse: cualquier concesión de `member` se resuelve al rol integrado Member; en caso contrario, Viewer. Nunca es true para el propietario. Muéstralo como «implícito por acceso». Hasta que un PATCH convierta la inferencia en una decisión, ampliar su acceso a direcciones amplía en silencio lo que puede hacer.
permissionslist[Permission]
Los permisos del rol aplanados sobre el miembro, de modo que una sola lectura responde a «¿puede hacerlo?» sin tener que obtener el rol. Para un miembro implícito provienen de la TEMPLATE integrada y no de la fila de rol de este espacio de trabajo, así que editar el rol Member integrado no cambia lo que tiene un miembro implícito.
addresseslist[MemberAddressResource]
Las direcciones que se le han dado, ordenadas por dirección, cada una con su propio nivel de acceso. Vacío para alguien que tiene un rol y ninguna concesión, que es el aspecto de un miembro nuevo hasta que se le concede una dirección, y es el fallo correcto mientras todavía estás decidiendo qué debería ver.
addresses[].addressIdstr
El id de la dirección, y lo que reciben `grant_address` y `revoke_address`. Un id que no corresponde a una dirección de este espacio de trabajo se rechaza en ambos, en lugar de informar de una revocación que nunca ocurrió.
addresses[].addressstr
La dirección completa, en minúsculas, reconstruida a partir de su parte local y su dominio.
addresses[].accessLiteral['member', 'viewer']
Lo que puede hacer con esta dirección concreta: `member` la lee y envía desde ella; `viewer` solo la lee. Tanto esto como el rol tienen que permitir un envío para que se produzca, así que un rol con `emails:send` sobre una concesión `viewer` no envía desde ninguna dirección; la columna almacenada se llama `role`, y aquí se renombra para que un mismo objeto no lleve dos `role` procedentes de dos vocabularios distintos.
createdAtstr | None
Cuándo se escribió su fila de miembro, en ISO-8601, y null cuando no existe ninguna fila de miembro. Ese null describe el mismo grupo que `'implied': True`: personas con direcciones de antes de que existieran los roles y a las que nadie ha asignado un rol desde entonces.

Invitaciones

invitations.py
from openemail import openemail waiting = openemail.members.list_all_invitations() for invitation in waiting:    if invitation['expired']:        openemail.members.resend_invitation(invitation['id']) openemail.members.revoke_invitation('winv_6bb640f5b99e47deb758f1f5')

add responde con una invitación, y estas son las llamadas que le dan seguimiento: list_invitations, list_all_invitations e iterate_invitations leen las que nadie ha aceptado todavía, resend_invitation vuelve a enviar una con un enlace nuevo y catorce días más, y revoke_invitation la retira. Una invitación pendiente no concede nada hasta que se acepta.

resend_invitation rechaza la misma dirección dos veces en diez minutos con 409 invitation_too_soon, y revoke_invitation rechaza una que se aceptó antes con 409 invitation_accepted.

Códigos de verificación

add, update, remove, grant_address y revoke_address piden a un token de acceso OAuth un código de verificación antes de cambiar nada, y resend_invitation y revoke_invitation no. La llamada lanza un OpenEmailApiError cuyo is_step_up_required es True: pide un código con security.begin_step_up(), comprueba el que te dé la persona con security.verify_step_up({'code': ...}) y vuelve a hacer la llamada. Una verificación dura 60 minutos, y a una clave de API nunca se le pide.

Referencia