Mail indy10: multipart/related messageparts

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 391 fois - Téléchargée 21 fois

Contenu du snippet

Pour les 2 ou 3 personnes que ça va interesser vu le succès mondial de mes sources sur les mails avec Indy :(

90% des mails ne posent pas de problème ... Par contre, pour les autres 10% il faut s' accrocher:
- embedded images : http://www.delphifr.com/codes/MAILS-AVEC-INDY10-CONTENTTYPE-CONTENTID-PARENTPART_45372.aspx
- des attachments qui contiennent un mail?!
etc ...

Bref, tous ces problèmes viennent souvent des mails qui sont envoyés par OutLook bien souvent à cause d' un forward d' un forward d' un forward...

Cette source vient dans l' esprit de celle-ci et est d' ailleurs reprise ici afin que celle-ci regroupe toutes les possibilités:
http://www.delphifr.com/codes/MAILS-AVEC-INDY-FAIRE-POURQUOI-LORSQUE-ANEXE-NE_44335.aspx

Le fait est que multipart/related MessageParts contiennent elles mêmes plusieurs parties de mails.
La fontion EXTRACT_MAIL_EMBEDDED_IN_TEXT(IdTexto: TIdText); permet de récupérer les parties contenues.

Je vous conseille aussi de regarder ma source:
MAILS AVEC INDY10, RÉSOLUTION DU PROBLÈME LORSQUE CHARSET = UTF-8
http://www.delphifr.com/codes/MAILS-AVEC-INDY10-RESOLUTION-PROBLEME-LORSQUE-CHARSET-UTF_43582

Source / Exemple :


Mensagem est de type TIdMessage
IndMsg est l' indice du message que l' on veut récupérer 
IdPOP31 est un compo de type TIdPOP3 qui est sur la form FrmPreview
IdMsg est un compo de type TIdMessage qui est sur la form FrmPreview

procedure PREVIEW_MAIL;
var
  TOT_MSG, M: Integer;
  _Ok: Boolean;
begin
    FrmPreview := TFrmPreview.Create(nil);
    with FrmPreview do
    begin
      try
        _Ok := false;
        RETexto.Lines.Clear;  // RichEdit qui contiendra le Body du mail au format Texte 
        REHtml.Lines.Clear;   // RichEdit qui contiendra le Body du mail au format Html
        LBAnexos.Items.Clear; // ListBox avec les noms des anexes
        IdPOP31.Host       := xxx;
        IdPOP31.Port       := xxx;
        IdPOP31.Username   := xxx;
        IdPOP31.Password   := xxx;
        IdPOP31.Connect;
        TOT_MSG := IdPOP31.CheckMessages;  // Nombre de messages
        MemUID.Lines.Clear; // memo avec les UID, qui est une valeur unique pour chaque message
        IdPOP31.UIDL(MemUID.Lines, -1);  // Récupérer les UID des messages ...
        IdMsg.Clear;
        IdPOP31.Retrieve(IndMsg, IdMsg);
        IDMESSAGE_EXTRACT_INFO(IdMsg);
        _Ok := true;
      finally
        if IdPOP31.Connected
        then IdPOP31.Disconnect;   // Fermer la conexion 
        if LBAnexos.Items.Count = 0
        then LBAnexos.Items.Add('(Aucun anexe)');
        if _Ok
        then Caption := ' Preview mail'
        else Caption := ' Error Preview mail !!!';
        ShowModal;
      end;
    end;
    FrmPreview.Release;
  end;
end;
// Fonction qui permet de récupérer le Body et les anexes : 
procedure TFrmPreview.IDMESSAGE_EXTRACT_INFO(Mensagem: TIdMessage);
var
  _a: Integer;
  DuplicatedBody: Boolean;

      procedure EXTRACT_MAIL_EMBEDDED_IN_TEXT(IdTexto: TIdText);
      var
        aTmpStream: TMemoryStream;
        aTmpIdMsg: TIdMessage;
      begin
        aTmpStream := TMemoryStream.Create;
        aTmpIdMsg := TIdMessage.Create(self);

        try
          IdTexto.Body.SaveToStream(aTmpStream);
          aTmpStream.Position := 0;      // Revenir au début des données du Stream ...
          aTmpIdMsg.Clear;
          aTmpIdMsg.LoadFromStream(aTmpStream);
          IDMESSAGE_EXTRACT_INFO(aTmpIdMsg);
        finally
          FreeAndNil(aTmpStream);
          aTmpIdMsg.Free;
        end;
      end;

      procedure OPEN_MAIL_EMBEDDED_IN_ATTACHMENT(Anexo: TIdAttachment);
      var
        aTmpStream: TMemoryStream;
        aTmpIdMsg: TIdMessage;
      begin
        aTmpStream := TMemoryStream.Create;
        aTmpIdMsg := TIdMessage.Create(self);
        try
          Anexo.SaveToStream(aTmpStream);
          aTmpStream.Position := 0;      // Revenir au début des données du Stream ...
          aTmpIdMsg.Clear;
          aTmpIdMsg.LoadFromStream(aTmpStream);
          IDMESSAGE_EXTRACT_INFO(aTmpIdMsg);    // On rapelle la fonction pou y retirer les infos ...
        finally
          FreeAndNil(aTmpStream);
          aTmpIdMsg.Free;
        end;
      end;
begin
  DuplicatedBody := False;
  for _a := 0 to Mensagem.MessageParts.Count -  1 do
  begin
    if (Mensagem.MessageParts.Items[_a] is TIdText)        // Texte ...
    then begin
      try
        if Mensagem.Body = TIdText(Mensagem.MessageParts.Items[_a]).Body
        then DuplicatedBody := True;

        if TIdText(Mensagem.MessageParts.Items[_a]).ContentType = 'multipart/related'  // il y aura des parties dans cette partie de mail !
        then begin
          EXTRACT_MAIL_EMBEDDED_IN_TEXT(TIdText(Mensagem.MessageParts.Items[_a]));
        end
        else
          if TIdText(Mensagem.MessageParts.Items[_a]).ContentType = 'text/html'
          then REHtml.Lines.AddStrings(TIdText(Mensagem.MessageParts.Items[_a]).Body)    // text/html
          else RETexto.Lines.AddStrings(TIdText(Mensagem.MessageParts.Items[_a]).Body);  // text/plain e outros ...
      except
      end;
    end
    else begin
      if TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName <> ''  // Pas de nom pour l' anexe!!!
      then begin
        LBAnexos.Items.Add('<' + TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName + '>');
Activez cette ligne si vous voulez faire le download de l' anexe:
//
TIdAttachment(Mensagem.MessageParts.Items[_a]).SaveToFile('c:\_output\'
+ TIdAttachment(Mensagem.MessageParts.Items[_a]).FileName);
      end
      else
        OPEN_MAIL_EMBEDDED_IN_ATTACHMENT(TIdAttachment(Mensagem.MessageParts.Items[_a]));
    end;
  end;
  if Pos('This is a multi-part message in MIME format.', Mensagem.Body.Text) = 0
  then
    if not DuplicatedBody
    then RETexto.Lines.AddStrings(Mensagem.Body);
end;

Conclusion :


Bem c' est pas très propre comme solution mais ça a le mérite de fonctionner.
Tout le monde sait que les compos de mails Indy auraient besoin d' être complètement refaits mais y a t-il quelqu'un d' assez courageux pour le faire?
Moi? Je ne suis pas un héros ... (clin d' oeil à Daniel Balavoine sniff)

A voir également

Ajouter un commentaire

Commentaires

mirage36
Messages postés
2
Date d'inscription
lundi 21 mars 2005
Statut
Membre
Dernière intervention
17 mai 2010

Oui merci pour l'information.
Effectivement j'ai finit mon programme depuis décembre et j'ai opter pour cette solution.
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Salut Mirage36,

le plus simple est d' utiliser le protocol mailto appelé avec ShellExecute
mirage36
Messages postés
2
Date d'inscription
lundi 21 mars 2005
Statut
Membre
Dernière intervention
17 mai 2010

Merci d'avance pour tes codes que je télécharge tous anfin d'espérer trouver ma solution.

Je souhaite faire afficher un mail outlook préremplit avec piéces jointe, destinataires ect... via delphi. Jusque là pas de problème.

Ce que j'arrive pas à faire c'est lui dire quelle type de formulaire je souhaite remplir et afficher (par exemple IMP.Note.testformulaire).
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
Merci DelphiProg,

non, je ne connais pas les compos sur le bout des doigts.
Je trouve d' ailleurs qu' ils sont une source d' un savoir bien plus grand que le miens: le problème est qu' ils n' évoluent plus.
Ce que j' apporte donc se sont juste des corrections "grâce" à des problèmes concrets.

A+
cs_Delphiprog
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
26
A notre dévoué et laborieux Mauricio, moi je dis qu'il faudrait décerner une médaille. Ciel, quelle persévérance !

Un jour, tu connaitras le succès que tu mérites !
Ne désespère pas et tiens bon en attendant. On compte sur toi.

Trêve de plaisanterie, c'est vrai que tu fais un sacré boulot et que tu dois maintenant connaitre les composants Indy sur le bout des doigts. Alors, rien que pour cela, je dis bravo ;)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.