Search code examples
delphiindy10delphi-10.3-rio

Send email with Sendblue API and TIdHTTP


I am trying to send an e-mail by sendblue api.

Using Postman app I can send the e-mail using something as:

curl -X POST \
  https://api.sendinblue.com/v3/smtp/email \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 497' \
  -H 'Cookie: __cfduid=d49b2d4eb12e019d10adc31e48c2682001573229677' \
  -H 'Host: api.sendinblue.com' \
  -H 'Postman-Token: 79980bf9-b0f5-442d-a93e-0835ef471bac,6653fb5c-29da-4a00-83bc-cecb1c70b0bb' \
  -H 'User-Agent: PostmanRuntime/7.19.0' \
  -H 'accept: application/json' \
  -H 'api-key: xkeysib-728f8759d3fdbasdasdasdasd5asdsq083a48387459eba9cc57f9ad7904e-dqLADTR6vxw4y3GQ' \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{  
   "sender":{  
      "name":"Sender Alex",
      "email":"gestaaloud@outlook.com"
   },
   "to":[  
      {  
         "email":"cprmlasasaao@gmail.com",
         "name":"John Doe"
      }
   ],
   "subject":"test mail",
   "htmlContent":"<html><head></head><body><h1>Hello this is a test email from sib</h1></body></html>",
   "headers":{  
      "X-Mailin-custom":"custom_header_1:custom_value_1|custom_header_2:custom_value_2|custom_header_3:custom_value_3",
      "charset":"iso-8859-1"
   }
}'

I did the next function to send the email using delphi 10.3 with indy, but I am getting a 404 error. What am I doing wrong?

procedure Test_Email();
var  fIdHTTP : TIdHTTP;
     hdlSocket:TIdSSLIOHandlerSocketOpenSSL;
     RequestUTF8 : TStringStream;
     js,jso : TJSONobject;
     ja :TJsonArray;
     function GetJsonMail: String;
      begin
      js := TJSONobject.Create;
      try
         jso:= TJSONobject.Create;
         jso.AddPair(TJSONPair.Create('name'  , 'Gestan'));
         jso.AddPair(TJSONPair.Create('email'  , 'gestancsadfasd@outlook.com'));
         js.AddPair('sender',jso);

         ja := TJSONArray.Create;
         jso:= TJSONobject.Create;
         jso.AddPair(TJSONPair.Create('email'  , 'cprmlasdaao@gmail.com'));
         jso.AddPair(TJSONPair.Create('name'  , 'Luiz'));
         ja.AddElement(jso);
         js.AddPair(TJSONPair.Create('to'  , ja));


         js.AddPair(TJSONPair.Create('subject'  , 'Teste email'));
         js.AddPair(TJSONPair.Create('htmlContent'  , '<b>Teste email</b>'));

         jso:= TJSONobject.Create;
         jso.AddPair(TJSONPair.Create('X-Mailin-custom'  , 'custom_header_1:custom_value_1|custom_header_2:custom_value_2|custom_header_3:custom_value_3'));
         jso.AddPair(TJSONPair.Create('charset'  , 'iso-8859-1'));
         js.AddPair(TJSONPair.Create('headers'  , jso));
         result:=js.ToJSON;
      finally
          js.Free;
      end;
   end;
begin
  fIdHTTP := TIdHTTP.Create(nil);
  with fIdHTTP do
  begin
    Request.Clear;
    Request.CustomHeaders.AddValue('api-key',API_KEY_BLUE);
    Request.ContentType := 'application/json';
    Request.Accept := 'application/json';
    Request.CharSet := 'iso-8859-1';
    HTTPOptions := [];
    Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
    HandleRedirects := true;
    hdlSocket:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    with hdlSocket do
    begin
      SSLOptions.Method := sslvSSLv23;
      SSLOptions.Mode := sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 2;
    end;
    IOHandler := hdlSocket;
  end;

  RequestUTF8 := TStringStream.Create(GetJsonMail,TEncoding.UTF8);
  try
    fIdHTTP.Post('https://api.sendinblue.com/v3/email', RequestUTF8);
  finally
    RequestUTF8.Free;
    fIdHTTP.Free;
  end;
end;

Solution

  • HTTP response code 404 means you are posting to a URL that does not exist. Look at the URLs being used by the curl and TIdHTTP calls. They are different URLs. The curl code is posting to this URL:

    https://api.sendinblue.com/v3/smtp/email

    But your TIdHTTP code is posting to this URL instead:

    https://api.sendinblue.com/v3/email

    See the difference?

    Your TIdHTTP code is also not setting up all of the same HTTP headers as the curl code. In particular, the 'Postman-Token' and 'Cookie' headers are missing.

    Try this:

    procedure Test_Email();
    var
      fIdHTTP : TIdHTTP;
      hdlSocket : TIdSSLIOHandlerSocketOpenSSL;
      RequestUTF8 : TStringStream;
    
      function GetJsonMail: String;
      var
        js, jso : TJSONObject;
        ja : TJSONArray;
      begin
        js := TJSONObject.Create;
        try
          jso := TJSONObject.Create;
          try
            jso.AddPair('name', 'Gestan');
            jso.AddPair('email', 'gestancsadfasd@outlook.com');
            js.AddPair('sender', jso);
          except
            jso.Free;
            raise;
          end;
          ja := TJSONArray.Create;
          try
            jso := TJSONObject.Create;
            try
              jso.AddPair('email', 'cprmlasdaao@gmail.com');
              jso.AddPair('name', 'Luiz');
              ja.AddElement(jso);
            except
              jso.Free;
              raise;
            end;
            js.AddPair('to', ja);
          except
            ja.Free;
            raise;
          end;
          js.AddPair('subject', 'Teste email');
          js.AddPair('htmlContent', '<b>Teste email</b>');
          jso := TJSONObject.Create;
          try
            jso.AddPair('X-Mailin-custom', 'custom_header_1:custom_value_1|custom_header_2:custom_value_2|custom_header_3:custom_value_3');
            jso.AddPair('charset', 'iso-8859-1');
            js.AddPair('headers', jso);
          except
            jso.Free;
            raise;
          end;
          Result := js.ToJSON;
        finally
          js.Free;
        end;
      end;
    
    begin
      fIdHTTP := TIdHTTP.Create(nil);
      try
        fIdHTTP.Request.CustomHeaders.AddValue('api-key', API_KEY_BLUE);
        fIdHTTP.Request.CustomHeaders.AddValue('Postman-Token', '...');
        fIdHTTP.Request.CustomHeaders.AddValue('Cookie', '__cfduid=...');
        fIdHTTP.Request.ContentType := 'application/json';
        fIdHTTP.Request.Accept := 'application/json';
        fIdHTTP.Request.CacheControl := 'no-cache';
        fIdHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
        fIdHTTP.HandleRedirects := True;
        fIdHTTP.HTTPOptions := [];
    
        hdlSocket := TIdSSLIOHandlerSocketOpenSSL.Create(fIdHTTP);
        hdlSocket.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
        hdlSocket.SSLOptions.Mode := sslmUnassigned;
        hdlSocket.SSLOptions.VerifyMode := [];
        hdlSocket.SSLOptions.VerifyDepth := 2;
        fIdHTTP.IOHandler := hdlSocket;
    
        RequestUTF8 := TStringStream.Create(GetJsonMail, TEncoding.UTF8);
        try
          fIdHTTP.Post('https://api.sendinblue.com/v3/smtp/email', RequestUTF8);
        finally
          RequestUTF8.Free;
        end;
      finally
        fIdHTTP.Free;
      end;
    end;