Ao criar mensagens de e-mail, você deve definir o Tipo de conteúdo para multipart/alternativequando enviar HTML e TEXT ou multipart/mixedquando enviar TEXT e anexos.
Então, o que você faz se deseja enviar HTML, Texto e anexos? Use ambos?
Não sei ao certo qual é a maneira "correta" de fazer isso. Eu certamente já vi mensagens mp / alt que tinham uma parte mp / texto e uma parte mp / mista contendo HTML e anexo ... mas isso significava que o anexo só estava visível ao visualizar HTML e não ao visualizar TEXT, por isso 'cheira' errado. Você pode tentar mp / misturado com uma parte mp / alt que contém os formatos de mensagem e uma segunda parte para conter o anexo, mas não sei o que os clientes considerariam.
@Iain Sua resposta é muito especial por ser a única a conter a estrutura (muito estranha) esperada pelo Gmail. Vou conceder recompensa a ele.
Aqui está uma arte ASCII agradável: stackoverflow.com/a/40420648/633961
Eu enfrentei esse desafio hoje e achei essas respostas úteis, mas não suficientemente explícitas para mim.
Edit : Acabei de encontrar o e- mail do Apache Commons que encerra isso muito bem, o que significa que você não precisa saber abaixo.
Se sua exigência for um email com:
versões de texto e html
a versão html incorporou imagens (em linha)
A única estrutura que encontrei que funciona com o Gmail / Outlook / iPad é:
E um exemplo de como usá-lo no Gmail
Alguém poderia comentar sobre como fazer isso em PHP?
— RightHandedMonkey 27/02
@RightHandedMonkey Você pode fazer isso como uma nova pergunta, não posso falar por php.
Obrigado pela excelente resposta @Iain! Estou com dificuldade para tentar obter a estrutura MIME correta para o meu caso, na qual tento adicionar um 'prefixo' da parte HTML ao corpo do email; mas alguns clientes obtêm o corpo vazio sem anexos, outros o corpo apenas nos anexos (corpo vazio) (Outlook no Windows) e outros funcionam bem (web do GMail, Android App etc.). Dê uma olhada, se possível: stackoverflow.com/questions/47312409/…
Resposta incrível. Ajudei a corrigir meu problema sem saber como enviar uma versão HTML e texto de um email em um.
— Dinukadev 17/12/19
Não está na forma de "<" id-left "@" id-right ">".
Use multipart/mixedcom a primeira parte como multipart/alternativee peças subsequentes para os anexos. Por sua vez, use text/plaine text/htmlpeças dentro da multipart/alternativepeça.
Um cliente de e-mail capaz deve reconhecer a multipart/alternativeparte e exibir a parte de texto ou parte html, conforme necessário. Também deve mostrar todas as peças subseqüentes como peças de fixação.
O importante a ser observado aqui é que, nas mensagens MIME de várias partes, é perfeitamente válido ter partes dentro de partes. Em teoria, esse aninhamento pode se estender a qualquer profundidade. Qualquer cliente de email com capacidade razoável deve poder processar recursivamente todas as partes da mensagem.
Não se esqueça de encomendar as subpartes multipart/alternativecorretamente. A última entrada é a parte da melhor / mais alta prioridade, então você provavelmente deseja colocar a text/htmlparte como a última subparte. Por RFC1341 .
O que dizer multipart/relatede quando usar isso?
@Wilt: multipart/alternativeindica que apenas uma das partes incluídas deve ser exibida - por exemplo, uma parte é text/plaine uma parte é text/html. Portanto, o cliente de email não deve exibir as duas partes, mas apenas uma. ou seja, eles não estão relacionados. multipart/relatedindica que as várias subpartes fazem parte da parte raiz principal, por exemplo, a parte principal é text/htmle as subpartes são imagens incorporadas. Veja aqui para mais informações.
Apenas uma dica rápida - Se você tiver acesso a uma caixa * nix, poderá usar o muttcliente CLI para verificar se configurou corretamente suas mensagens MIME de várias partes. Se você pressionar venquanto visualiza uma mensagem, ela será exibida e permitirá a travessia da árvore aninhada de partes MIME.
— Rinogo 11/06
As mensagens têm conteúdo. O conteúdo pode ser texto, html, DataHandler ou Multipart, e pode haver apenas um conteúdo. As multipartes possuem apenas BodyParts, mas podem ter mais de um. As BodyParts, como as Mensagens, podem ter conteúdo que já foi descrito.
Uma mensagem com HTML, texto e um anexo pode ser visualizada hierarquicamente assim:
E o código para criar essa mensagem:
@ splahout Muito obrigado e parabéns pela sua resposta clara e ampla, para mim tem sido tão útil.
Eu bati nesta edição. Essa arquitetura (da resposta de Lain) funcionou para mim. Aqui está a solução em Python.
Aqui está a principal função de criação de email:
Aqui está o código completo para enviar um email contendo html / text / attachment:
Com base no exemplo de Iain, tive uma necessidade semelhante de compor esses emails com texto sem formatação separado, HTML e vários anexos, mas usando PHP. Como estamos usando o Amazon SES para enviar emails com anexos, a API atualmente exige que você crie o email do zero usando a função sendRawEmail (...).
Depois de muita investigação (e maior do que a frustração normal), o problema foi resolvido e o código-fonte PHP publicado, para que ele possa ajudar outras pessoas com um problema semelhante. Espero que isso ajude alguém - a tropa de macacos que eu forcei a trabalhar nesse problema agora está esgotada.
Código-fonte PHP para enviar e-mails com anexos usando o Amazon SES.
Este é o homem genial da solução. Geralmente $boundarycontêm corpo inteiro com anexos, mas apenas $boundary2HTML ou texto sem formatação. Solução genial. Diga-me, por favor, esta é sua solução para o envio de texto sem formatação. Essa é uma mensagem alternativa se o cliente de email não suportar HTML? Obrigado!
Obrigado. Sim, envio texto sem formatação e HTML com a solução acima. O código simplesmente retira o HTML usando as strip_tags ($ body) para fornecer texto sem formatação nos casos de navegadores que não desejam usar o HTML. Se desejar, você pode colocar sua própria string personalizada lá (por exemplo, $ body_plain_text).
Ótima resposta Lain!
Eu fiz algumas coisas para fazer isso funcionar em um conjunto mais amplo de dispositivos. No final, listarei os clientes nos quais testei.
Eu adicionei um novo construtor de compilação que não continha os anexos de parâmetro e não usava MimeMultipart ("mixed"). Não é necessário misturar se você estiver enviando apenas imagens embutidas.
No método addTextVersion, adicionei charset ao adicionar conteúdo, isso provavelmente poderia / deveria ser passado, mas apenas o adicionei estaticamente.
O último item foi adicionado ao método addImagesInline. Eu adicionei a configuração do nome do arquivo da imagem no cabeçalho pelo código a seguir. Se você não fizer isso, pelo menos no cliente de e-mail padrão do Android, ele terá imagens embutidas com o nome de Desconhecido e não fará o download automaticamente e o apresentará no e-mail.
Então, finalmente, esta é a lista de clientes em que testei. Outlook 2010, Outlook Web App, Internet Explorer 11, Firefox, Chrome, Outlook usando o aplicativo nativo da Apple, Email passando pelo Gmail - Cliente de email do navegador, Internet Explorer 11, Firefox, Chrome, cliente de email padrão Android, cliente de email padrão osx IPhone, Gmail cliente de email no Android, cliente de email do Gmail no iPhone, email através do Yahoo - cliente de email do navegador, Internet Explorer 11, Firefox, Chrome, cliente de email padrão do Android, cliente de email padrão do osx IPhone.
Espero que ajude mais alguém.
Obrigado pelo feedback, todos os bons pontos. Vou ver como incluí-los na minha resposta.
Aqui está o melhor: Mensagem MIME de várias partes / mista com anexos e imagens embutidas
E imagem: https://www.qcode.co.uk/images/mime-nesting-structure.png
Esquema multipart / relacionado / alternativo
Os links para recursos externos são incentivados, mas adicione contexto ao redor do link para que seus colegas usuários tenham uma idéia do que é e por que está lá. Sempre cite a parte mais relevante de um link importante, caso o site de destino esteja inacessível ou fique permanentemente offline. Veja como responder
Esta resposta não funciona para mim. Apenas o primeiro anexo é realmente enviou ...
O subtipo "misto" de "multipartes" deve ser usado quando as partes do corpo são independentes e precisam ser agrupadas em uma ordem específica. Qualquer subtipo "multipartes" que uma implementação não reconheça deve ser tratado como sendo do subtipo "misto".
Subtipo alternativo
O tipo "multipart / alternativo" é sintaticamente idêntico a "multipart / misto", mas a semântica é diferente. Em particular, cada uma das partes do corpo é uma versão "alternativa" da mesma informação