Contactos
`contacts.list`, `get`, `create`, `save`, `update`, `set_audiences`, `delete`, `delete_many`, `list_people`, `set_photo`, `remove_photo`, `block`, `unblock`, `list_threads` 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: 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 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.add_contact, de que trata a página Audiências. set_audiences diz exatamente em que listas está um contacto, numa só chamada.
Os endereços são guardados em minúsculas e a gem codifica o que passar, pelo que [email protected] chega à linha certa. Um endereço nil ou vazio lança ArgumentError 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
limitInteger- Quantos contactos devolver por página: um número inteiro de 1 a 200, com 50 por predefinição. O valor é convertido, pelo que uma String como `"100"` lida de uma query string é aceite, e um valor fora do intervalo dá 422 em vez de ser ajustado ao limite.
cursorString- O `next_cursor` 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 `OpenEmail::InvalidRequestError`, 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::Page, pelo que as linhas estão em page.items e o percurso segue page.next_cursor enquanto page.has_more? for true. list_all devolve todas as linhas como um único Array, e iterate entrega-as uma de cada vez. get, create, update, save e set_audiences devolvem cada um um contacto como Hash com chaves Symbol, 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 nil- O nome de apresentação, ou nil 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 nil- Texto livre que alguém escreveu sobre esta pessoa, na aplicação ou através de `update`, nunca gerado. É nil quando ninguém escreveu nada, e `notes: nil` em `update` limpa-o.
lastSeenAtString or nil- 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. É nil 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<Hash>- Só em `get`, `create`, `update`, `save` e `set_audiences`, nunca nas linhas da lista. Todas as audiências a que o contacto pertence, incluindo a predefinida, como um Hash com `id`, `name` e `builtin`. `builtin` é `default` na audiência a que todos os contactos pertencem e nil numa criada por alguém, por isso baseie a lógica nele e não no nome, que qualquer pessoa pode alterar.
photoUrlString or nil- Onde a foto do contacto é servida, ou nil quando o contacto não tem nenhuma. `set_photo` define-a e cada carregamento recebe um URL novo.
Definir as audiências de um contacto
set_audiences(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 a gem 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 OpenEmail::NotFoundError.
Todos os que estão na página de Contactos
list_people 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::PeoplePage, que acrescenta seen a items, has_more? e next_cursor. 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::PEOPLE_SORTS 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.
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 devolve todas as páginas como um único Array, e iterate_people passa cada pessoa a um bloco, ou devolve um Enumerator sem bloco. Nenhum dos dois indica seen, por isso leia uma página com list_people para o saber. O cursor é opaco, por isso devolva next_cursor como cursor: exatamente como veio, com os mesmos sort:, q: e blocked:.
Guardar, eliminar e fotos
save(email), com name: e notes: opcionais, é 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 Hash que devolve, diz qual dos casos era. delete_many elimina até 200 numa só chamada.
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 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 binária, um IO ou um Pathname. Passe content_type:, ou bytes que levem o seu próprio tipo: um objeto que responda a content_type, como um ficheiro carregado no Rails, ou um File ou Pathname 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::CONTACT_PHOTO_TYPES 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::CONTACT_BLOCK_LISTS nomeia as duas listas.
Conversas e atividade
list_threads(email) percorre por páginas as conversas que o endereço escreveu ou em que lhe escreveram, em todas as pastas, e list_all_threads e iterate_threads 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.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 aceita argumentos nomeados em snake_case. minutes: define a janela, que é de 90 dias quando omitida. grain: define a largura de cada intervalo: minute, hour ou day. offset_minutes: define os minutos a leste de UTC em que os dias mudam. Time.now.utc_offset / 60 é o fuso local, e a gem envia-o como o offsetMinutes da API.