Fonte de dados: SMTP
1Apresentação
Esta fonte de dados é um cliente SMTP minimalista, que envia e-mails conectando-se a um configurável relay SMTP: um servidor externo (Gmail, Mailgun, Mailjet, Brevo…) ou um local (Postfix/Exim em smtp://localhost).
Ela não depende de nenhuma biblioteca externa (usa sockets PHP diretamente) e se conecta a um único relay. A entrega direta ao servidor MX do destinatário não é suportada: um relay é sempre necessário.
Assim como as fontes de dados Slack ou Discord, esta é uma fonte de dados somente para escrita: os métodos de leitura (get(), read(), find()…) são inertes ou lançam uma exceção.
Se você configurou corretamente os parâmetros de conexão, o Temma cria automaticamente um objeto do tipo \Temma\Datasources\Smtp. Por convenção, vamos supor que você nomeou essa conexão smtp no arquivo etc/temma.php (veja a documentação de configuração).
Nos controladores, a conexão fica então disponível da seguinte forma:
$smtp = $this->smtp;
Nos demais objetos gerenciados pelo componente de injeção de dependências, a conexão é acessível da seguinte forma:
$smtp = $loader->dataSources->smtp;
$smtp = $loader->dataSources['smtp'];
2Configuração
2.1DSN
No arquivo etc/temma.php (veja a documentação de configuração), você declara o DSN (Data Source Name) usado para se conectar ao relay SMTP. Três esquemas estão disponíveis, dependendo do modo de criptografia da conexão:
-
smtp://[user:password@]server[:port]
Conexão em texto puro. Porta padrão: 25. -
smtp+tls://[user:password@]server[:port]
Conexão criptografada via STARTTLS (a criptografia é negociada após a conexão). Porta padrão: 587. -
smtps://[user:password@]server[:port]
Conexão criptografada desde o início (TLS implícito). Porta padrão: 465.
A autenticação é opcional: ela só é ativada se o DSN contiver um par user:password (mecanismos PLAIN ou LOGIN, de preferência sobre uma conexão criptografada). Um relay local como smtp://localhost:25 se conecta, portanto, sem autenticação.
Exemplos:
// relay do Gmail com STARTTLS e autenticação
'smtp+tls://user:password@smtp.gmail.com:587'
// relay local sem autenticação
'smtp://localhost:25'
A fábrica de fontes de dados reconhece os prefixos smtp://, smtp+tls:// e smtps://. A forma genérica também pode ser usada: [\Temma\Datasources\Smtp]smtp://….
2.2Parâmetros opcionais
O DSN aceita parâmetros de consulta opcionais:
- helo: nome anunciado no comando EHLO/HELO.
- timeout: tempo limite de rede, em segundos.
- verify: verificação do certificado TLS (1 para ativar, 0 para desativar; ativado por padrão).
smtp+tls://user:pass@smtp.example.com:587?helo=mysite.com&timeout=10&verify=1
2.3Construção a partir de parâmetros
Uma senha (ou nome de usuário) contendo caracteres especiais é incômoda de codificar em um DSN. Você pode então descrever a conexão usando parâmetros separados em vez de um DSN. Os parâmetros aceitos são: host, port, user, password, security (none, starttls ou tls), helo, timeout e verify.
'x-email' => [
'transport' => [
'host' => 'smtp.example.com',
'port' => 587,
'user' => 'user@example.com',
'password' => 'p@ss:w/rd!',
'security' => 'starttls',
],
],
Essa forma é equivalente ao DSN correspondente. Ela é usada, em particular, pelo helper Email através da diretiva transport em forma de array.
3Envelope e mensagem
O envio de um e-mail SMTP se baseia em duas noções distintas:
- o envelope: o remetente (MAIL FROM) e a lista de destinatários (RCPT TO) realmente usados pelo protocolo SMTP;
- a mensagem: o fluxo completo RFC 5322 (From, To, Cc, Subject, Date, Message-ID, cabeçalhos MIME… e o corpo).
O envelope e a mensagem são independentes. Por exemplo, os destinatários em cópia oculta aparecem no envelope (para que a entrega seja feita) mas não nos cabeçalhos da mensagem (sem cabeçalho Bcc).
A fonte de dados cuida da transparência SMTP (normalização das quebras de linha para CRLF e "dot-stuffing" das linhas do corpo que começam com um ponto). Você fornece uma mensagem RFC 5322 normal; a conformidade no nível do protocolo é automática.
4Envio
4.1set()
O método set() é o caminho normal de envio (é o que é usado pelo helper Email). Ele espera um valor em array estruturado descrevendo o envelope e a mensagem:
$smtp->set($id, [
'from' => 'sender@example.com',
'recipients' => ['dest1@example.com', 'dest2@example.com'],
'message' => $rawRfc5322Message,
]);
- from: remetente do envelope, usado para MAIL FROM.
- recipients: lista de destinatários, um RCPT TO por entrada.
- message: fluxo RFC 5322 completo, enviado em DATA.
O primeiro parâmetro ($id) é um simples identificador (Message-ID ou identificador da aplicação), usado para o log.
Essa estrutura "portátil" é o que possibilita usar qualquer fonte de dados como transporte: uma fonte SMTP entrega a mensagem, uma fonte File ou S3 a arquiva, uma fonte de fila de mensagens a coloca na fila, e assim por diante. O envelope viaja no valor, nunca nas opções nem na chave.
4.2write()
O método write() oferece acesso bruto: o valor é diretamente o fluxo RFC 5322, e o envelope é passado no terceiro parâmetro ($options).
$smtp->write($id, $rawRfc5322Message, [
'from' => 'sender@example.com',
'recipients' => ['dest1@example.com', 'dest2@example.com'],
]);
O envio é imediato em ambos os casos.
5Uso do helper Email
Na prática, esta fonte de dados serve principalmente como transporte para o helper Email. Você então não chama nem set() nem write() diretamente: o helper monta a mensagem e o envelope, e então delega o envio. Consulte a seção Envio por meio de um relay SMTP do helper Email.