Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Photon (iMessage)

Conecte o Hermes ao iMessage pelo Photon, um serviço gerenciado que cuida da alocação de linhas da Apple e da camada de prevenção de abuso, para você não precisar manter o seu próprio relay em um Mac.

O plano gratuito usa o pool de linhas de iMessage compartilhadas do Photon — destinatários diferentes podem ver números de envio diferentes, mas cada conversa se mantém estável. O plano pago Business dá a mesma linha dedicada para todo usuário; o plugin funciona com os dois, e o plano gratuito é o ponto de partida recomendado.

Começar é de graça

O pool de linhas compartilhadas do Photon é gratuito. Não é preciso assinatura para mandar o seu primeiro iMessage pelo Hermes — só um número de telefone que possamos vincular à sua conta.

Arquitetura​

O Photon é um canal de conexão persistente, como o Discord ou o Slack — sem webhook, sem URL pública, sem segredo de assinatura para administrar.

O SDK spectrum-ts mantém um stream gRPC de vida longa com o Photon, nas duas direções. Como o SDK só existe em TypeScript, o Hermes o roda num pequeno sidecar Node supervisionado e conversa com ele por loopback:

  • Entrada — o sidecar consome o stream gRPC app.messages do SDK e encaminha cada mensagem ao adaptador Python por um GET /inbound em loopback (NDJSON). O adaptador deduplica e despacha para o agente, reconectando sozinho se o stream cair.
  • Saída — as respostas são POSTs em loopback para o sidecar, que chama space.send(...) no SDK.

O plugin Python inicia, supervisiona e encerra o sidecar automaticamente.

Pré-requisitos​

  • Uma conta no Photon — cadastre-se em app.photon.codes
  • Node.js 18.17 ou mais novo no PATH (node --version)
  • Um número de telefone que receba iMessage (usado para vincular a sua conta)

É só isso — não há URL pública nem túnel para configurar.

Configuração inicial​

Rode o assistente unificado do gateway e escolha Photon iMessage:

hermes gateway setup

…ou rode a configuração do Photon direto (o assistente chama o mesmo fluxo):

# Login por device code + projeto + usuário + dependências do sidecar, tudo de uma vez
hermes photon setup --phone +15551234567

A configuração, em ordem:

  1. Login do dispositivo (client_id=photon-cli) — abre https://app.photon.codes/ para aprovação e guarda o bearer token.
  2. Encontra ou cria o projeto Hermes Agent na sua conta.
  3. Habilita o Spectrum, lê o id de Spectrum do projeto e gira o segredo do projeto.
  4. Registra o seu número de telefone como usuário do Spectrum — pula se já existir um usuário com aquele número, então rodar de novo é seguro.
  5. Imprime a linha de iMessage atribuída a você — o número para o qual você manda mensagem para falar com o seu agente.
  6. Roda npm install dentro do diretório do sidecar do plugin. Em árvores de instalação somente leitura ou imutáveis (imagens Docker hospedadas, Podman, Nix), o sidecar recorre automaticamente a um espelho gravável em ~/.hermes/photon/sidecar; defina PHOTON_SIDECAR_DIR para fixar um local explícito.

As credenciais de runtime são gravadas no ~/.hermes/.env (PHOTON_PROJECT_ID = o id do projeto Spectrum, PHOTON_PROJECT_SECRET), no mesmo lugar em que todo outro canal guarda o seu token. Os metadados de gerenciamento (token do dispositivo, id do projeto no painel) ficam no ~/.hermes/auth.json, em credential_pool.photon / credential_pool.photon_project.

Autorizar usuários​

O Photon usa o mesmo modelo de autorização de todos os outros canais do Hermes. Escolha uma abordagem:

Pareamento por DM (padrão). Quando um número desconhecido escreve para a sua linha do Photon, o Hermes responde com um código de pareamento. Aprove com:

hermes pairing approve photon <CODE>

Use hermes pairing list para ver os códigos pendentes e os usuários aprovados.

Autorize números específicos de antemão (no ~/.hermes/.env):

PHOTON_ALLOWED_USERS=+15551234567,+15559876543

Acesso aberto (só para desenvolvimento, no ~/.hermes/.env):

PHOTON_ALLOW_ALL_USERS=true

Quando PHOTON_ALLOWED_USERS está definido, remetentes desconhecidos são ignorados em silêncio, em vez de receberem um código de pareamento (a lista de permissão sinaliza que você restringiu o acesso de propósito).

Exigir menção em conversas de grupo​

Por padrão o Hermes responde a toda DM e a toda mensagem de grupo autorizada. Para tornar as conversas de grupo opt-in, habilite o portão por menção (as DMs continuam sempre funcionando):

gateway:
platforms:
photon:
enabled: true
require_mention: true

Com require_mention: true, mensagens de grupo são ignoradas a menos que casem com um padrão de palavra de ativação. Os padrões default casam com Hermes e variações de @Hermes agent. Para um nome de agente personalizado, defina padrões de regex:

gateway:
platforms:
photon:
require_mention: true
mention_patterns:
- '(?<![\w@])@?amos\b[,:\-]?'

As duas chaves também aceitam variáveis de ambiente (PHOTON_REQUIRE_MENTION, PHOTON_MENTION_PATTERNS). É o mesmo modelo de portão por menção que o canal iMessage do BlueBubbles usa.

Suba o gateway​

hermes gateway start

Você vai ver algo assim:

[photon] connected — sidecar on 127.0.0.1:8789, streaming inbound over gRPC

Mande um iMessage para o número atribuído a você e o Hermes responde.

Status e resolução de problemas​

hermes photon status

Imprime as credenciais salvas, a saúde do sidecar, o seu número registrado e a linha de iMessage atribuída que o Hermes usa. Quando há um token do Photon e um projeto no painel disponíveis, o status atualiza as linhas de número que estiverem faltando a partir do painel, sem provisionar linhas novas.

Photon iMessage status
──────────────────────
device token : ✓ stored
dashboard project : 3c90c3cc-0d44-4b50-...
spectrum project id : sp-...
project secret : ✓ stored
my number : +15551234567
assigned number : +16282679185
node binary : /usr/bin/node
sidecar deps : ✓ installed

Problemas comuns:

  • sidecar deps : ✗ run hermes photon install-sidecar — o Node está instalado, mas o spectrum-ts não. Rode o comando sugerido.
  • device token : ✗ missing — rode hermes photon setup para fazer login.
  • No iMessage line assigned yet — o Spectrum está habilitado, mas nenhuma linha foi provisionada; rode hermes photon setup de novo ou confira o painel.
  • O sidecar não sobe — confirme que node --version é 18.17 ou superior e que o hermes photon install-sidecar terminou sem erros.

Limitações de hoje​

  • Anexos de entrada trazem só metadados. Os eventos de entrada carregam o nome do arquivo e o tipo MIME; o agente vê um marcador, mas ainda não consegue ler os bytes. O SDK expõe os bytes do anexo por content.read(), então isso é um trabalho pendente no sidecar.
  • Anexos de saída são suportados. O Hermes envia imagens, notas de voz, vídeo e documentos pelos construtores de conteúdo attachment() / voice() do spectrum-ts, através do endpoint /send-attachment do sidecar. As legendas chegam como um balão de iMessage separado, depois da mídia.
  • Enquetes nativas são suportadas. O Hermes envia conteúdo de enquete pelo construtor poll() do spectrum-ts, através do endpoint /send-poll do sidecar.
  • Efeitos de mensagem são suportados. O Hermes envia texto com efeitos nativos de balão e de tela do iMessage pelo construtor effect() de iMessage do spectrum-ts, através do endpoint /send-effect do sidecar.
  • Cotas gratuitas do Photon: 5.000 mensagens por servidor por dia e 50 conversas novas iniciadas por linha compartilhada por dia. Dá para aumentar — escreva para help@photon.codes.
  • Envios por cron e avulsos exigem o gateway rodando. Remetentes fora do processo (cron jobs, hermes send, o painel) reaproveitam o sidecar que o gateway criou — eles leem a porta e o token dele em <hermes-home>/runtime/photon-sidecar.json, gravado assim que o sidecar passa na verificação de saúde e removido quando ele para. Se um envio avulso avisar que o gateway parece estar fora do ar, suba (ou reinicie) o gateway antes.
  • Linhas compartilhadas do plano gratuito não iniciam conversas com destinos novos. É política do lado do Photon: uma linha compartilhada só pode escrever para um número depois que aquele número tiver escrito para a linha primeiro. Um envio por cron ou avulso para um destinatário totalmente novo é rejeitado pelo Photon, mesmo com o Hermes configurado corretamente — ou peça para o destinatário escrever para a linha uma vez, ou migre para uma linha dedicada.

Variáveis de ambiente​

VariávelPadrãoObservações
PHOTON_PROJECT_IDdo .envId do projeto Spectrum (o projectId do SDK); definido pela configuração
PHOTON_PROJECT_SECRETdo .envSegredo do projeto; definido pela configuração
PHOTON_SIDECAR_PORT8789Porta de loopback para o controle do sidecar e o canal de entrada
PHOTON_SIDECAR_AUTOSTARTtrueSe o adaptador deve criar o sidecar
PHOTON_NODE_BINwhich nodeSobrescreve o caminho do binário do Node
PHOTON_HOME_CHANNEL(não definida)Id de space padrão para cron e notificações
PHOTON_HOME_CHANNEL_NAME(não definida)Rótulo legível do canal principal
PHOTON_ALLOWED_USERS(não definida)Lista de permissão em E.164, separada por vírgula
PHOTON_ALLOW_ALL_USERSfalseSó para desenvolvimento — aceita qualquer remetente
PHOTON_REQUIRE_MENTIONfalseExige palavra de ativação antes de responder em grupos
PHOTON_MENTION_PATTERNSpalavras de ativação do HermesPadrões de regex para menções em grupo, em lista JSON, separados por vírgula ou por quebra de linha
PHOTON_DASHBOARD_HOSTapp.photon.codesSobrescreve o host do painel e do login por dispositivo
PHOTON_SPECTRUM_HOSTspectrum.photon.codesSobrescreve o host da API do Spectrum