Contactos
`contacts->list`, `get`, `create`, `save`, `update`, `setAudiences`, `delete`, `deleteMany`, `listPeople`, `setPhoto`, `removePhoto`, `block`, `unblock`, `listThreads` e `activity`.
Todos os métodos
$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' => null]);$client->contacts->setAudiences('[email protected]', ['audienceIds' => ['aud_4c1b8e2a7d9f05c36b4e8a71']]);$client->contacts->delete('[email protected]'); echo count($page), ' ', $page->hasMore ? 'more to come' : 'that is all', PHP_EOL;echo $contact['source'], ' ', $contact['lastSeenAt'] ?? 'never mailed', ' ', $saved['source'], PHP_EOL;list devolve primeiro os contactos vistos mais recentemente, e no fim os contactos que nunca receberam email. source é auto quando a linha foi escrita porque um membro enviou uma mensagem para esse endereço a partir do editor de mensagens da aplicação, o que é uma afirmação materialmente diferente de alguém o ter guardado. O correio recebido de um endereço não escreve nada, e um envio através desta API também não.
O livro de endereços pertence ao espaço de trabalho e não a uma pessoa, pelo que um contacto guardado por qualquer membro é o contacto que todos os membros e todas as chaves veem. create escreve source como manual e coloca o contacto na audiência predefinida no momento da escrita. Indique listas suas em audienceIds para o associar a elas na mesma chamada, o que também exige audiences:write, ou adicione o contacto mais tarde com audiences->addContact, de que trata a página Audiências. setAudiences diz exatamente em que listas está um contacto, numa só chamada.
Os endereços são guardados em minúsculas e o cliente codifica o que passar, pelo que [email protected] chega à linha certa. Um endereço vazio lança InvalidArgumentException antes de qualquer envio. O endereço é a identidade, pelo que update não o pode alterar: mudar um contacto de endereço é um delete seguido de um create.
Parâmetros: contacts->list
limitint- Quantos contactos devolver por página: um número inteiro de 1 a 200, com 50 por predefinição. Um valor fora do intervalo dá 422 em vez de ser ajustado ao limite. O argumento é do tipo `int`, por isso converta primeiro com `(int)` um valor lido de uma query string.
cursorstring- O `nextCursor` da página anterior. Nunca construa um manualmente: um cursor que refere um contacto que já não existe dá 400 `invalid_cursor`, lançado como `InvalidRequestException`, o que significa que o seu estado de paginação está desatualizado e o percurso deve recomeçar sem cursor.
sourcestring- `manual` para os contactos que alguém guardou intencionalmente, `auto` para os que o editor de mensagens da aplicação registou. Omita-o para obter todo o livro de endereços.
qstring- Pesquisa o nome e o endereço, até 200 caracteres. Quando nada coincide exatamente na primeira página, são devolvidas grafias próximas, e as páginas seguintes continuam a pesquisar da mesma forma.
Resposta: um contacto
contacts->list devolve uma OpenEmail\Result\Page, pelo que as linhas estão em $page->items e o percurso segue $page->nextCursor enquanto $page->hasMore for true. listAll devolve todas as linhas como um único array, e iterate devolve um Generator que as entrega uma de cada vez. get, create, update, save e setAudiences devolvem cada um um contacto como array com chaves em camelCase, a mesma linha mais audiences. O livro de endereços não tem limite, e é por isso que esta rota pagina em vez de devolver um array que parava silenciosamente nas 200 linhas.
objectstring- Sempre a string `contact`, tanto nas linhas da lista como em `get`.
emailstring- O endereço, convertido para minúsculas na escrita para que `[email protected]` e `[email protected]` sejam um só contacto, e o identificador que todos os métodos de contactos recebem, já que nenhum id de contacto é exposto. As linhas pertencem ao espaço de trabalho e não ao membro ou à chave que as escreveu, pelo que todos os membros e todas as chaves do espaço de trabalho leem e escrevem um único livro de endereços.
namestring or null- O nome de apresentação, ou null quando nunca foi registado nenhum nome para o endereço. Uma escrita automática só inclui um quando o cabeçalho forneceu algo diferente do próprio endereço, e nunca pode substituir um nome que o utilizador escreveu.
sourcestring- `auto` significa que a linha foi escrita porque o utilizador enviou correio para esse endereço. `manual` significa que alguém o introduziu à mão, uma afirmação materialmente diferente, e um upsert nunca rebaixa `manual` para `auto`. O correio recebido de um endereço não escreve nenhuma linha, de propósito, pelo que alguém que apenas lhe escreveu não está aqui. Trate o valor como uma string aberta, porque a coluna é texto livre com `manual` como predefinição.
notesstring or null- Texto livre que alguém escreveu sobre esta pessoa, na aplicação ou através de `update`, nunca gerado. É null quando ninguém escreveu nada, e `'notes' => null` em `update` limpa-o.
lastSeenAtstring or null- Uma string ISO 8601 UTC, atualizada sempre que um membro envia para esse endereço a partir do editor de mensagens da aplicação, e não quando chega correio dele, o que não escreve nada. É null num contacto guardado através de `create` que nunca recebeu email, e esses ficam em último lugar na ordem descendente por `lastSeenAt` que esta rota devolve.
audiencesarray- Só em `get`, `create`, `update`, `save` e `setAudiences`, nunca nas linhas da lista. Todas as audiências a que o contacto pertence, incluindo a predefinida, como um array com `id`, `name` e `builtin`. `builtin` é `default` na audiência a que todos os contactos pertencem e null numa criada por alguém, por isso baseie a lógica nele e não no nome, que qualquer pessoa pode alterar.
photoUrlstring or null- Onde a foto do contacto é servida, ou null quando o contacto não tem nenhuma. `setPhoto` define-a e cada carregamento recebe um URL novo.
Definir as audiências de um contacto
setAudiences($email, ['audienceIds' => [...]]) diz exatamente em que audiências está um contacto, num só pedido. O contacto entra em cada audiência indicada onde ainda não está e sai de todas as outras, e a chamada devolve o contacto depois da alteração, com as suas audiences. Requer audiences:write, porque escreve pertenças e não o contacto, e repeti-la não muda nada, por isso o cliente repete-a depois de uma falha de rede.
A audiência predefinida é sempre mantida, pelo que 'audienceIds' => [] deixa o contacto apenas na audiência predefinida. Aceita até 100 ids. Um id que não designa nenhuma audiência deste espaço de trabalho dá um 404 audience_not_found e nada muda, e um endereço que não é contacto dá um 404 contact_not_found. Ambos lançam NotFoundException.
Todos os que estão na página de Contactos
listPeople lista as pessoas que a página de Contactos da app mostra: os contactos guardados e cada endereço visto no correio, cada um com saved, threads e lastAt, e devolve uma OpenEmail\Result\PeoplePage, que acrescenta seen a items, hasMore e nextCursor. list são só os contactos guardados. Os endereços vistos no correio só vêm quando a chave também tem threads:read, e $page->seen diz se vieram. sort: é recent, name ou threads, e OpenEmail\Constants\PeopleSorts nomeia-os. q: pesquisa nomes, endereços e notas, e blocked: true fica com as pessoas que a lista de bloqueio do espaço de trabalho bloqueia, incluindo regras de domínio inteiro. blockedBy indica a regra em cada linha.
use OpenEmail\Constants\PeopleSorts; $page = $client->contacts->listPeople(sort: PeopleSorts::THREADS, limit: 50); foreach ($page as $person) { if (!$person['saved'] && $person['threads'] > 5) { $client->contacts->save($person['email']); }} $blocked = $client->contacts->listAllPeople(blocked: true);echo $page->seen ? 'saved and seen' : 'saved only', ', ', count($blocked), ' blocked', PHP_EOL;listAllPeople devolve todas as páginas como um único array, e iteratePeople devolve um Generator que entrega cada pessoa. Nenhum dos dois indica seen, por isso leia uma página com listPeople para o saber. O cursor é opaco, por isso devolva nextCursor como cursor: exatamente como veio, com os mesmos sort:, q: e blocked:.
Guardar, eliminar e fotos
save($email), com um array opcional de name e notes, é Adicionar aos contactos e Manter nos contactos: guarda um endereço que ainda não é contacto, mantém como guardado à mão um registado a partir de um envio e traz de volta um eliminado. delete é Eliminar: tira o contacto guardado e oculta o endereço, para que o editor não o volte a registar, e aceita também um endereço só visto no correio. wasSaved, no array que devolve, diz qual dos casos era. deleteMany elimina até 200 numa só chamada.
$client->contacts->save('[email protected]', ['name' => 'Grace Hopper']); $contact = $client->contacts->setPhoto('[email protected]', file_get_contents('photo.jpg'), contentType: 'image/jpeg');echo $contact['photoUrl'], PHP_EOL; $client->contacts->setPhoto('[email protected]', new \SplFileInfo('avatar.png')); $client->contacts->removePhoto('[email protected]');$client->contacts->deleteMany(['[email protected]', '[email protected]']);setPhoto envia os bytes da imagem tal como estão: PNG, JPEG, WebP ou GIF até 5 MB, ajustados a um quadrado de 512 píxeis. Os bytes são uma string, um recurso de stream de fopen, um SplFileInfo, ou um stream PSR-7 ou ficheiro carregado. Passe contentType:, ou bytes que levem o seu próprio tipo: um ficheiro carregado PSR-7, ou um upload do Symfony ou do Laravel, com o seu tipo de media, ou um ficheiro ou stream cujo nome termine em .png, .jpg, .jpeg, .webp ou .gif. Sem tipo, os bytes seguem como application/octet-stream, que o servidor recusa com um 422 invalid_image. OpenEmail\Constants\ContactPhotoTypes nomeia os quatro tipos. O endereço tem de ser primeiro um contacto guardado.
Bloqueio
block($email) põe o endereço na lista de bloqueio do espaço de trabalho para que o correio dele seja recusado, descartando qualquer etiqueta com mais, e unblock($email) tira cada regra que o bloqueia. Ambos precisam de settings:write, porque alteram a lista de bloqueio e não o contacto, e nenhum precisa que o endereço seja um contacto.
Quando unblock levanta uma regra de domínio inteiro, removed lista-a com list em blockedDomains, e todos nesse domínio ficam desbloqueados com ela. OpenEmail\Constants\ContactBlockLists nomeia as duas listas.
Conversas e atividade
listThreads($email) percorre por páginas as conversas que o endereço escreveu ou em que lhe escreveram, em todas as pastas, e listAllThreads e iterateThreads percorrem-nas todas. activity($email) devolve os números por trás do separador Atividade de um contacto: recebidos e enviados por intervalo, conversas à espera da sua resposta e o tempo mediano de resposta em cada sentido. Ambos precisam de threads:read.
$threads = $client->contacts->listThreads('[email protected]', q: 'invoice'); $activity = $client->contacts->activity( '[email protected]', minutes: 30 * 24 * 60, grain: 'day', offsetMinutes: intdiv((int) date('Z'), 60),); echo count($threads), ' threads, ', $activity['totals']['waiting'], ' waiting on you', PHP_EOL;activity aceita argumentos nomeados. minutes: define a janela, que é de 90 dias quando omitida. grain: define a largura de cada intervalo: minute, hour ou day. offsetMinutes: define os minutos a leste de UTC em que os dias mudam, e intdiv((int) date('Z'), 60) é o desvio do fuso que o PHP tem configurado.