メンバー
`members.list`、`list_all`、`iterate`、`get`、`add`、`update`、`remove`、`grant_address`、`revoke_address`、そしてその隣の招待のメソッド。
すべてのメソッド
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'])1 人につき付与は 2 種類あり、これらを 1 つにまとめてはならない。role は何ができるか、addresses はどのアドレスに対してできるかを表す。両者が揃って初めて許可される。emails:send を持つロールでも invoices@ に対する 'access': 'viewer' であれば、その人はメールを送信できるが、そのアドレスを差出人にして送信することはできない。例外は addresses:all を持つロールで、addresses に何が並んでいてもすべてのアドレスに届く。その配列には直接の付与しか入らないので、それを届く範囲のすべてと読む前に permissions を確認すること。
どのメソッドもメールアドレスではなく userId を受け取る。唯一の例外が add であり、それはこの呼び出しがアドレスを招待するものだからである。相手が userId を持つのは招待を承諾してからであり、それまでは list_invitations がその招待を追跡する。
'implied': True は、そのロールを誰も選んでいないことを意味する。アドレスの付与はあるがロールの行がないため、保持している最も広い付与からロールが推定されている。これは「まだ決まっていない」状態として扱うこと。推定を決定に変えるのが update である。それまでは、アドレスへのアクセスを広げると、その人にできることも黙って広がる。
ワークスペースのオーナーは最初の行に現れ、'isOwner': True が付く。一方で add、update、remove はオーナーに対しては member_is_owner で拒否される。共有されていないワークスペースでもメンバーは 0 人ではなく 1 人として報告されるため、シート数を数えるときは isOwner の行を除外すること。
remove は両方の軸、すなわちロールとこのワークスペース上のすべてのアドレス付与を取り除き、addressesRevoked を報告する。範囲が狭いのは revoke_address の方で、退職した人ではなくチームを異動した人に使う。
パラメーター
emailstr必須- 招待する相手。トリムして小文字化される。相手はまだアカウントを持っていなくてよい。全員に招待が送られ、ロールと付与は相手が承諾した時点で反映される。すでにワークスペースにいる相手は `member_is_owner`(422)になる。
roleIdstr必須- その人が持つことになるロール。1 〜 128 文字で、このワークスペース上に存在するロールでなければならない。未知の id は `role_not_found`(404)になる。オーナーのロールは付与できず `role_immutable`(409)が返る。誰かをオーナーにすることはワークスペースの譲渡であり、そのための呼び出しはここにはないからである。
addressIdslist[str]- 招待に含めるアドレス。id は最大 64 個、それぞれ 1 〜 128 文字で、招待が承諾された時点で付与される。何かが書き込まれる前にすべての id が検査されるため、このワークスペースのアドレスではない id が 1 つでもあると、呼び出し全体が 422 `member_not_found` で拒否され、何も送信されない。同じアドレスを 10 分以内に再度招待すると 409 `invitation_too_soon` になる。
accessLiteral['member', 'viewer']- `addressIds` に含まれるすべての id に対して何ができるか。`member` はそのアドレスを読み、そのアドレスとして送信できる。`viewer` は読むだけである。既定値は `member` で、これはコンソールおよび以前の共有経路が一貫して使ってきたレベルである。そのため同じ呼び出しは、スクリプトから行っても画面から行っても同じ意味になる。レベルを混在させたい場合は、異なるものについて後から `grant_address` を呼ぶこと。
レスポンス
objectLiteral['member']- 常に `member`。削除時も同じ値に加えて対象の `userId`、`'deleted': True`、`addressesRevoked` が返り、以下の他のフィールドは返らない。
userIdstr- その人のアカウント id であり、他のすべてのメンバー呼び出しがパスで受け取る識別子である。get、update、remove とアドレス関連の 2 つの呼び出しがこれにあたる。唯一メールアドレスから動作するのが追加の呼び出しで、同僚を追加する人が知っているのは id ではなくアドレスだからである。
emailstr- その人のアカウントに登録されたメールアドレス。行に保存されているとおりに返される。このリソースがこの値を書き込むことはなく、`add` での小文字化は検索のために送ったアドレスに適用されるものであって、返ってくる値には適用されない。メンバー一覧はオーナーの次から、参加時期ではなくこの値で並ぶ。一覧は変更点を見るためではなく、特定の 1 人を探すために読まれるものだからである。
namestr | None- その人の表示名。アカウントから取得され、そちらの列は NOT NULL である。型に `None` が含まれているのは防御的な措置であり、この API がその状態を返したことが確認されているわけではない。表示名はワークスペースではなく本人に属するため、このリソースから設定する手段はない。
imagestr | None- その人のアバター。アカウントから取得され、設定されていない場合は null。
role.idstr | None- その人が持つロールの id。誰も選んでいない場合は null。`implied` を参照。ここが null のときだけ、`role` は誰かが下した決定ではなく推定を報告している。
role.namestr- ロールの名前。推定されたメンバーの場合、これはそのアクセスが解決した組み込みテンプレートの名前であり、このワークスペース上の行ではない。
role.builtinLiteral['owner', 'admin', 'member', 'viewer', 'developer', 'billing'] | None- そのロールがどの組み込みロールにあたるか。カスタムロールの場合は null。`owner` はオーナー自身の行にのみ `'isOwner': True` と並んで現れる。このロールを誰かに割り当てようとすると `role_immutable`(409)で拒否される。
isOwnerbool- ちょうど 1 行、ワークスペースの所有者となっているアカウントの行でのみ true になる。その人はロールの行が何を示していてもすべての権限を持ち、並び順では先頭に来る。`add`、`update`、`remove` はいずれも `member_is_owner` で拒否する。シート数を数えるときはこの行を除外すること。
impliedbool- その人にアドレスの付与はあるがメンバーの行がなく、ロールが選ばれたのではなく推定された場合に true になる。`member` の付与が 1 つでもあれば組み込みの Member に、なければ Viewer に解決される。オーナーで true になることはない。UI には「アクセスから推定」と表示すること。PATCH によって推定が決定に変わるまでは、アドレスへのアクセスを広げると、その人にできることも黙って広がる。
permissionslist[Permission]- ロールの権限をメンバー上に平坦化したもの。1 回の読み取りで、ロールを取得せずに「この人はできるか」に答えられる。推定されたメンバーの場合、権限はこのワークスペースのロール行ではなく組み込みのテンプレートから取られるため、組み込みの Member ロールを編集しても、推定されたメンバーが持つ権限は変わらない。
addresseslist[MemberAddressResource]- その人に付与されたアドレス。アドレス順に並び、それぞれに固有のアクセスレベルが付く。ロールだけを持ち付与がない人では空になる。アドレスが付与されるまでの新規メンバーはこの状態であり、その人に何を見せるかを決めている間はこれが望ましい失敗の仕方である。
addresses[].addressIdstr- アドレスの id であり、`grant_address` と `revoke_address` が受け取る値。このワークスペースのアドレスではない id は両方で拒否される。実際には行われなかった取り消しを報告することはない。
addresses[].addressstr- 完全なアドレス。小文字化され、ローカル部とドメインから再構成される。
addresses[].accessLiteral['member', 'viewer']- この 1 つのアドレスに対して何ができるか。`member` は読み取りとそのアドレスからの送信ができ、`viewer` は読み取りのみである。送信が行われるにはこの値とロールの両方が許可している必要があるため、`viewer` の付与の上に `emails:send` を持つロールがあっても、送信できるアドレスは 1 つもない。保存されている列名は `role` だが、1 つのオブジェクトが異なる語彙に由来する 2 つの `role` を持たないよう、ここでは名前を変えている。
createdAtstr | None- メンバーの行が書き込まれた日時。ISO 8601 で表され、メンバーの行がまったく存在しない場合は null。この null が示す集団は `'implied': True` と同じであり、ロールという仕組みができる前からアドレスを持ち、その後も誰もロールを与えていない人たちである。
招待
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 は招待を返し、その後に続く呼び出しがこれらである。list_invitations、list_all_invitations、iterate_invitations はまだ誰も承諾していない招待を読み、resend_invitation は新しいリンクとさらに 14 日の期限を付けて再送し、revoke_invitation は取り消す。承諾待ちの招待は、承諾されるまで何も与えない。
resend_invitation は同じアドレスへの 10 分以内の 2 回目を 409 invitation_too_soon で拒否し、revoke_invitation は先に承諾された招待を 409 invitation_accepted で拒否する。
確認コード
add、update、remove、grant_address、revoke_address は、何かを変更する前に OAuth アクセストークンに確認コードを求めるが、resend_invitation と revoke_invitation は求めない。呼び出しは is_step_up_required が True の OpenEmailApiError を送出する。security.begin_step_up() でコードを求め、本人から受け取ったコードを security.verify_step_up({'code': ...}) で確認してから、もう一度呼び出すこと。1 回の確認は 60 分間有効で、API キーが求められることはない。
リファレンス
members.list()完全なリファレンスmembers.list_all()完全なリファレンスmembers.iterate()完全なリファレンスmembers.get()完全なリファレンスmembers.add()完全なリファレンスmembers.update()完全なリファレンスmembers.remove()完全なリファレンスmembers.grant_address()完全なリファレンスmembers.revoke_address()完全なリファレンスmembers.list_invitations()完全なリファレンスmembers.list_all_invitations()完全なリファレンスmembers.iterate_invitations()完全なリファレンスmembers.resend_invitation()完全なリファレンスmembers.revoke_invitation()完全なリファレンス