#1 2020-08-11 16:27:27

larand54
Member
Registered: 2018-12-25
Posts: 104

How do I load a file into the body of a http-request

In a new project I need to send mail using OAUTH2. The mail can contain attachments like pdf-files and they need to be Base64 encoded.
I feel lost in all alternatives so I need some help to move forward.
I use TWinHttp.post sending mail. It works good with simple mail.


Delphi-11, WIN10

Offline

#2 2020-08-11 17:11:17

tbo
Member
Registered: 2015-04-20
Posts: 353

Re: How do I load a file into the body of a http-request

I create the email data with the Indy components TIdMessage and TIdMessageBuilderHTML. This is very simple. I send this data with a slightly modified version of the function SendEmail() from the unit SynCrtSock.

idMessage := TIdMessage.Create(Nil);
try
  idMessage.Subject := 'New Mail';
  idMessage.From.Name := 'Hallo2020';
  idMessage.From.Address := 'mail@hallo2020.com';
  idMessage.Recipients.EMailAddresses := 'your@gmail.com';
  idMessageBuilder := TIdMessageBuilderHTML.Create;
  try
    idMessageBuilder.Html.Text := StringFromFile('EMail.html');
    idMessageBuilder.Attachments.Add('Data.pdf');
    idMessageBuilder.FillMessage(idMessage);
  finally
    idMessageBuilder.Free;
  end;
  
  idMessage.SaveToStream(strStream);
  SendEmail(..., strStream.DataString) 

With best regards
Thomas

Offline

#3 2020-08-11 18:54:09

larand54
Member
Registered: 2018-12-25
Posts: 104

Re: How do I load a file into the body of a http-request

Ok, thank's for an answer but I has to send the mail through a service where everything is built around OAuth2. I have everything working and can send the mail but I need to know how I should do with the files that needs to be attached to the mail.
Indy will not help here.


Delphi-11, WIN10

Offline

#4 2020-08-11 20:38:46

tbo
Member
Registered: 2015-04-20
Posts: 353

Re: How do I load a file into the body of a http-request

If I understood your question correctly, my source code should provide the solution. I only use Indy to create the right format. Just have a look at what happens in my example when you display the result in a memo (Memo1.Text := strStream.DataString).

Here you can find a blog article: New HTML Message Builder class
You should use a more recent Indy version from Github than the one shipped with Delphi before version 10.4.

With best regards
Thomas

Offline

#5 2020-08-11 20:44:52

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: How do I load a file into the body of a http-request

I believe he is referring to sending via HTTP.

Make a Post to upload the file.

In this case, SynCurl can help you.

After @mpv creates a separate unit for SynCurl, you can now use all the features that Curl offers.

Offline

#6 2020-08-12 07:46:14

larand54
Member
Registered: 2018-12-25
Posts: 104

Re: How do I load a file into the body of a http-request

Yes, it's about a http-request.
The service requires a body that contans mailFrom, mailto, message etc. and the attached files with name and contentents encoded in Base64 .
Al is wrapped in a json structure:

{
    "SendUser": "senderName@somwhere.on.earth",
    "Message": "Hello",
    "Subject": "HelloSubject",
    "ToRecipients": [
        "receiver.theMartian@mons.olympus.on.mars"
    ],
    "CcRecipients": [
        "flash@titan.on.saturn"
    ],
    "FileAttachments": [
        {
            "Name": "spacetraveling.pdf",
            "Value": "N7I+GuZ4KclTXP7KXM3YRdh0BfKxnMpOv8s....        } // Filecontents base64-encoded
    ]
}

Part of the code that calls the sendmail service

var
  messageID: sockString;
  body: variant;
  atm: variant;
begin
  if getToken = '' then
    result := -1
  else begin
    TDocVariant.new(body);
    body.SendUser := aFrom;
    body.Message := aMessage;
    body.Subject := aSubject;
    body.ToRecipients := _Arr([stringReplace(aMailTo,';',',')]);
    body.CcRecipients := _Arr([stringReplace(aCC,';',',')]);
    if high(aAttachments) > -1 then begin
       TDocVariant.new(atm);
       atm.name := aAttachments[0];
	   .
	   . read and add file contents here - all attachments should be put into an array and then added to the body.
	   
    messageID := TWinHTTP.Post(fOaSec.getMailURL,body,fOaSec.getMailHeader);

Delphi-11, WIN10

Offline

#7 2020-08-12 13:59:17

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: How do I load a file into the body of a http-request

I've looked into thread several times already, but so far I didn't understand the problem you have. I guess others have the same confusion.

Could you specify a particular place, where you have the problem? Reading pdf file, converting to base64, forming 'body', something else?

Offline

#8 2020-08-12 14:11:22

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: How do I load a file into the body of a http-request

Take a look in SynCommons.BinToBase64

Offline

#9 2020-08-14 10:04:32

larand54
Member
Registered: 2018-12-25
Posts: 104

Re: How do I load a file into the body of a http-request

Thank's a lot, I've just solved it this way:

    TDocVariant.new(body);
    body.SendUser := aFrom;
    body.Message := aMessage;
    body.Subject := aSubject;
    body.ToRecipients := _Arr([stringReplace(aMailTo, ';', ',', [rfReplaceAll, rfIgnoreCase])]);
    body.CcRecipients := _Arr([stringReplace(aCC, ';', ',', [rfReplaceAll, rfIgnoreCase])]);
    if high(aAttachments) > -1 then
    begin
      for i := 0 to high(aAttachments) do
      begin
        TDocVariant.new(atm[i]);
        atm[i].name := extractFileName(aAttachments[i]);
        atm[i].value := fileToBase64(aAttachments[i]);
      end;
    body.FileAttachments := _Arr([atm]);
    end;

    messageID := TWinHTTP.Post(fOaSec.getMailURL, body, fOaSec.getMailHeader);

function FileToBase64(const aFileName: RawUTF8): RawUTF8;
var
  f: TStream;
  bytes: TBytes;
begin
  result := '';
  f := TFileStream.Create(afilename, fmOpenRead);
  try
    if f.Size > 0 then
    begin
      SetLength(bytes, f.Size);
      f.Read(bytes[0], f.Size);
    end;
    result := binToBase64(@bytes[0], f.size); //String(sb);
  finally
    f.free;
  end;
end;

Delphi-11, WIN10

Offline

#10 2020-09-29 12:54:14

fileriver
Member
Registered: 2020-09-29
Posts: 1
Website

Re: How do I load a file into the body of a http-request

Thank you dear it worked for me i have also got sloved.

Offline

Board footer

Powered by FluxBB