Board index » delphi » Ultra-reliable direct mail sending- some info on Indy SendCmd/GetResponse requested

Ultra-reliable direct mail sending- some info on Indy SendCmd/GetResponse requested

Hello Indy Users and Team,

 I'm currently writing an application to deliver e-mails as quickly
 and reliably as possible (directly to the end-user SMTP server). I
 want immediate feedback if there is any problem with the domain or
 the user name within the domain. Here's a basic overview of what I'm
 trying to do:

   Parse the e-mail name to get the domain (easy).

   Perform an MX look-up to find all servers for this domain (easy).

   Connect to each MX server and issue "RCPT TO:" to determine if this
   server will accept the recipient (using TIdTCPClient). Immediately
   disconnect and move to next step (small problem here).

   Send the mail to server which accepted the recipient previously (if
   any) (easy).

This routine could also be used to do advanced verification of e-mail
addresses.

My problem is using the SendCmd and GetResponse methods of
TIdTCPClient, I'm not sure if the server is accepting my RCPT TO:
command. I tried SendCmd(.., [250]) = wsOK, but I get an $11C response
(284- that's not a documented SMTP return code), not wsOK. Could
someone help help me with the finer points of SendCmd and GetResponse?
Will SendCmd(..., [250]) and GetResponse(..., [220]) raise an
exception if I do not get a 250/220 response message from the command,
or do they simply continue?

I've appended my code as an MX look-up reference and to show you what
and how I'm trying to achieve this. If I can get this to work
satisfactorily I will be writing a multi-threaded Indy MX e-mail
verifier (if the Indy team is interested in this as a demo).

Thanks!

--
Best regards,
 Keith                          mailto:keithb_removethis_@_removeth...@eta.co.za

....
var
  IdDNSResolver1: TIdDNSResolver;
  IdTCPVerifyName: TIdTCPClient;
  mp1, mp2: TidText;
  IdMSG  : TIdMessage;
  IdSMTP : TIdSMTP;
  tsMXServers : TStringList;
  szAddress, szDomain,
  szErrMsg,
  lPos, i, j : Integer;
  bCanContinue, bFoundAServer : Boolean;
  lServerIndex : Integer;
....
begin
 ....
// Get MX servers for this address...
if bCanContinue then
begin
  IdDNSResolver1.Host := gszDNSServer;
  IdDNSResolver1.ReceiveTimeout := 20000;
  IdDNSResolver1.ClearVars;
  IdDNSResolver1.RequestedRecords := [cMX]; // Mail Exchange
  try
    IdDNSResolver1.ResolveDomain(szDomain);
    tsMXServers.Clear;
    if (IdDNSResolver1.DNSAnList.Count > 0) then
      for j := 0 to IdDNSResolver1.DNSAnList.Count - 1 do
        if (IdDNSResolver1.DNSAnList[j].AType = cMX) then
          tsMXServers.Add(IdDNSResolver1.DNSAnList[j].RData.MX.Exchange);
    bCanContinue := (tsMXServers.Count > 0);
    if (tsMXServers.Count = 0) then szErrMsg := 'No MX servers were found ' +
                                                'for domain "' + szDomain + '"';
  except on E: Exception do
    begin
      szErrMsg := 'Unable to resolve domain: ' + E.Message;
      bCanContinue := False;
    end;
  end;
end;

// Try to determine which server will accept mail from us for this person...
// We will try until we run out of servers or find one which will
// accept a message for this recipient...
if bCanContinue then
begin
  bFoundAServer := False;
  for j := 0 to Pred(tsMXServers.Count) do
    if not bFoundAServer then
    begin
      szInfo := 'Threaded MX send: Trying server "' + tsMXServers[j] +
                '" for user "'+ szAddress + '"';
      Synchronize(ShowStatus);

      IdTCPVerifyName.Host := tsMXServers[j];
      IdTCPVerifyName.Port := 25; // SMTP
      try
        try
          IdTCPVerifyName.Connect;
          // Receive: 220 BBN-UNIX.ARPA Simple Mail Transfer Service Ready
          IdTCPVerifyName.GetResponse([220]);
          //if (IdTCPVerifyName.GetResponse([220]) = wsOK) then
          //begin
            // HELO <SP> <domain> <CRLF>
            IdTCPVerifyName.SendCmd('HELO yourdomain.com', 250);
            IdTCPVerifyName.SendCmd('MAIL FROM:<Q...@yourdomain.com>', 250);
            // Returns $11C = 284
            IdTCPVerifyName.SendCmd('RCPT to:<' + szAddress + '>', 250)
            // If we get here, success!
            bFoundAServer:= True; lServerIndex := j;
            szInfo := 'Threaded MX send: Server "' + tsMXServers[j] +
                  '" accepted user "'+ szAddress + '"!';
            Synchronize(ShowStatus);
            // Disconnect, ignoring any errors...
            IdTCPVerifyName.SendCmd('QUIT', 221);
            IdTCPVerifyName.Disconnect;
            Break;
        except on E: Exception do
          begin
            szInfo := 'ERROR: Can''t connect to server "' + tsMXServers[j] +
                    '" for user "'+ szAddress + '" Error:' + E.Message;
            Synchronize(ShowStatus);
            bCanContinue := False;
            szErrMsg := 'Unable to connect with MX server "' + tsMXServers[j] +
                                         '": Error: "' + E.Message + '"';
          end;
        end;
      finally
        if IdTCPVerifyName.Connected then IdTCPVerifyName.Disconnect;
      end;
    end;
end;

// Send the message...
if bCanContinue and bFoundAServer then
begin
  try
  .....

 

Re:Ultra-reliable direct mail sending- some info on Indy SendCmd/GetResponse requested


keithblo@nospam!@#@_woollyware.com (Keith Blows) wrote in
<Xns903574409DE3Dkeithblotrack...@207.105.83.65>:

Quote
>   Send the mail to server which accepted the recipient previously (if
>   any) (easy).

Id like to see this developed into a descendant of TIdSMTP, such as
TIdSMTPRelay and contributed to the Indy 8.1 core if you dont mind.

Quote
>TIdTCPClient, I'm not sure if the server is accepting my RCPT TO:
>command. I tried SendCmd(.., [250]) = wsOK, but I get an $11C response

No. wsOk is only for POP3. All servers respond with 3 digit numbers, except
POP3. I have no idea why they made POP3 non standard. Normally you ignore the  
result of SendCmd.

If you use TIdSMTP you chould not need to use SendCmd, simply let it do the
work for you while you augment it with MX lookups, etc.

Quote
>(284- that's not a documented SMTP return code), not wsOK. Could
>someone help help me with the finer points of SendCmd and GetResponse?
>Will SendCmd(..., [250]) and GetResponse(..., [220]) raise an
>exception if I do not get a 250/220 response message from the command,
>or do they simply continue?

They will raise an exception if a response is returned other than what you
pass in the arrays.

Quote
>satisfactorily I will be writing a multi-threaded Indy MX e-mail
>verifier (if the Indy team is interested in this as a demo).

Yes, very interested, but more as a component, with a demo. :)

--
Chad Z. Hower (Kudzu) - Church Hill, TN - Team Indy
      "Programming is an art form that fights back"
Forget the Y2K problem, Lets fix the W2K problem.
http://www.pbe.com/Kudzu/ - Free Delphi/CBuilder components and articles

Re:Ultra-reliable direct mail sending- some info on Indy SendCmd/GetResponse requested


chad...@pbe.com (Kudzu - Team Indy) wrote in
<9036E9A75chadngpbe...@207.105.83.62>:

Quote
>keithblo@nospam!@#@_woollyware.com (Keith Blows) wrote in
><Xns903574409DE3Dkeithblotrack...@207.105.83.65>:
>>   Send the mail to server which accepted the recipient previously (if
>>   any) (easy).

>Id like to see this developed into a descendant of TIdSMTP, such as
>TIdSMTPRelay and contributed to the Indy 8.1 core if you dont mind.

>>TIdTCPClient, I'm not sure if the server is accepting my RCPT TO:
>>command. I tried SendCmd(.., [250]) = wsOK, but I get an $11C response

>No. wsOk is only for POP3. All servers respond with 3 digit numbers,
>except POP3. I have no idea why they made POP3 non standard. Normally
>you ignore the  result of SendCmd.

>If you use TIdSMTP you chould not need to use SendCmd, simply let it do
>the work for you while you augment it with MX lookups, etc.

>>(284- that's not a documented SMTP return code), not wsOK. Could
>>someone help help me with the finer points of SendCmd and GetResponse?
>>Will SendCmd(..., [250]) and GetResponse(..., [220]) raise an
>>exception if I do not get a 250/220 response message from the command,
>>or do they simply continue?

>They will raise an exception if a response is returned other than what
>you pass in the arrays.

Thanks for the help. I looked at Ernst Gerlach's code and with that I has a
good idea of the command usage, just wasn't sure about the exception.

Quote
>>satisfactorily I will be writing a multi-threaded Indy MX e-mail
>>verifier (if the Indy team is interested in this as a demo).

>Yes, very interested, but more as a component, with a demo. :)

OK. I think we need two components: TIdSMTPRelay and TIdAddressVerify? These
would probably make a lot of people's lives a lot easier. No promises right
now (I'm still learning the Indy infrastructure), but I think I can squeeze
it in sometime in late Feb.

I think TIdSMTPRelay may use TIdAddressVerify to firstly verify the address
and find the suitable host, what do you think?

Regards

Keith Blows

Re:Ultra-reliable direct mail sending- some info on Indy SendCmd/GetResponse requested


Quote
Keith Blows wrote:

> I think TIdSMTPRelay may use TIdAddressVerify to firstly verify the address
> and find the suitable host, what do you think?

I think it's a great idea!  Just yesterday I was thinking of how on earth I'd
tackle the same issues.  That's my 2 cents.
-G

Other Threads