TSMTPCli Last Updated: 01/27/2007 |
Frequently Asked Questions for TSMTPCli:
- What is it?
- Adding headers
- Attach a file
- Authentication
- Commands
- Component not ready
- Does SMTPCli support E-mail priority?
- How to send e-mail directly to the recipient's SMTP server?
- Inline image
- Message size
- Multiple recipitients
- OnSessionConnected and OnSessionClosed
- Priority
- RcptName sends only one address
- Relaying what is that
- Reply Codes
- Reply to
- Request read receipt setting
- Sending multiple emails
- Several address
- verify email addresses
- Wait for Conenction
- Why do I get '550 Relaying is prohibited' when using the MailSnd demo?
What is it?
Jan Tomasek 03.10.1998 |
class implements the SMTP (Simple Mail Transfer Protocol)described in rfc821. Suports file attachement using MIME format (MultipurposeInternet Mail Extensions), rcf1521.
|
Adding headers
Wilfried Mestdagh wilfried@mestdagh.biz 22/12/2002 |
If you want to add something in the headers then you assign code to the OnProcessHeader of TSmtpCli ane put following code: procedure TMain.SmtpCliProcessHeader(Sender: TObject; HdrLines: TStrings); begin HdrLines.Add('Errors-to: whatever'); end; |
Attach a file
Francois Piette francois.piette@overbyte.be 21.09.1998 |
The SMTP component has a TStrings property to hold all file names and paths. Just fill this property with all the filenames you want to attach to the message. The SMTP component will automatically format the text and mail attachment(s) conforming to RFC-1521 (MIME), then send it.
|
Authentication
Bruno Laffont - Listes laffont2@sekoya.net 10/03/2001 |
It won't work if you use the USER and PASS command with the SMTP server.
For a good authentication, you need to : - check the server support this Service Extension (checking AUTH command is available sending EHLO instead of HELO command to server) - send the AUTH command with the authentication mechanism name in parameter - send the user name (login) encoded in base64 - send the password encoded in base64 -> then if it's ok, the user is authenticated and ready to send data... More details : - Sending EHLO command tells to server to send back the list of extend commands supported. - The list can be trapped in the TriggerResponse event (one command by line). - If one of the line begin by "250-AUTH=" followed by "themechanismname" -> ie: "250-AUTH=themechanismname", then secured authentication is supported by the server and "themechanismname" is the mechanism name to use (for this server) with the AUTH command to tell the server to be in waiting mode for secured authentication. Generally the mechanism is called "LOGIN". - Then you send AUTH command to server with the mechanism in parameter (ie: "AUTH LOGIN"). The mechanism name cannot be empty. A good response is sent back with "334". - The server now waits the login name encoded in base64, send it directly without command, like "myloginencodedinb64" A good response is sent back with "334". - Then send the password encoded in base64, without command like "mypasswordencodedinb64" A good response is sent back with "235". Then, if all is good you can now send data, as usually. |
Commands
dZ dz@caribe.net 03/29/2001 |
To send an message via Smtp in "one shot" you must send the following
commands (in order):
Other commands are available. Check RFC for more info: |
Component not ready
Francois PIETTE francois.piette@overbyte.be 14/01/2006 |
> Smtp1.Host := smtpserver;
> Smtp1.port := '25'; > Smtp1.FromName := uname; > Smtp1.HdrFrom := emailaddr; > Smtp1.HdrTo := mailto.text; > Smtp1.HdrCc := mailcc.text; > Smtp1.HdrSubject := mailsubject.text; > Smtp1.EmailFiles := Memo1.Lines; > Smtp1.Connect; > Smtp1.Data; > Smtp1.quit; > > now the problem is when i go to send the email . > i get Smtp componet not ready. errors. This is a VFAQ (very frequently asked question). You are trying to use a non blocking component as a blocking one. When you call Smtp1.Connect, you ask the component to connect. It will connect in the background and give control back to you while connection take place in the background. You'll get an event when the connection is done (or failed). You should program "event driven". See mailSnd sample and look what is behind the "All in once" button. You must program the same way. If you really need blocking (that is synchronous) operation, then use TSyncSmtpCli instead of TSmtpCli. It expose ConnectSync and other synchronous methods. |
Does SMTPCli support E-mail priority?
Dimitri Bijenhof DBijenhof@bnb.com.bo 13/02/2002 |
> I want to know if SMTPCli support e-mail priority (high, low and > normal) ? This priority has nothing to do with the SMTP protocol itself. It is simply a flag (header line) placed in the message itself by the sender's mail client, for example: From: me@here.com To: you@there.com Date: 13/02/2002 Priority: Urgent The recipient's mail client should sif through the RCF-822 message headers for this header and take any action necessary for "Urgent" messages (E.G. process them immediately). Unfortunately, there does not seem to be an official standard header format for "Urgent" messages (that is, I can't seem to find anything in any RFC), and different programs use different methods. Outlook seems to play it safe and places 3 different headers in the message: X-Priority: 1 Priority: Urgent Importance: high Just to make it clear that this is an urgent message. |
How to send e-mail directly to the recipient's SMTP server?
DZ-Jay dz@caribe.net 20/01/2002 |
> I just would like to know if it would be possible to create an email > program which would not depend on an SMTP server to relay the messages but > would send them directly to the recipientīs SMTP. > Of course! All you need to do is find out the recipient's SMTP server. You can do this by checking the MX record of a DNS lookup to the @domain.com part of the address. Then you just connect to that SMTP server and send the email as usual. |
Inline image
DZ-Jay dz@caribe.net 27/11/2005 |
I try send email format html and attach jpg, this attach found ok, but no see image in html
To attach an image and display it inline, you must reference it via its MIME Content-ID from the image tags. For example, when you attach the image, you create a Content-ID header for that attachment, and use this ID to replace the image src attribute in the HTML source: <img src="cid: The SMTP Component does not do this automatically, but I believe that there's a demo (MailHtml) that shows how to do this. |
Message size
Various 21/07/2001 |
> I would like to be able to get an accurate size of a message before sending,
> and then be able to provide progress as it is sending. The problem I am > having is the Base64 encoding I believe. Whenever there is an attachment, > the data sent is greater than the actual sizes of the > Files + MailMessage + Headers Answer 1: A small test on an attachment that I did, shows that the original data has a length of 60 and the encoded Base64 data has a length of 80. Said another way, the encoding process expands the data by 1/3 and the decoding process shrinks the data by 1/4. Answer 2: A couple of small points to add to this, depending on how accurate you need to be: Each three bytes of raw data encodes to 4 bytes of base64. If the total length of your raw data is not an exact multiple of three, you need to round the calculation up. Thus 12 raw bytes equals 16 coded bytes; 13, 14, or 15 raw bytes all equate to 20 coded bytes. If you use a line-based protocol to transmit the data (NNTP, Pop3 or whatever), then each line includes an additional CRLF pair. So you'd need to add (2 * linecount) to the byte-count as calculated above. |
Multiple recipitients
Jan Tomasek 03.10.1998 |
Use TSMTPClient.RCPTName property, it is a string list, you can add there as many address you need.
If you dont want to allow to yours recipients to see addressies of other all, set to TSMTPClient.HdrTo property something like my_loved@users.whole.world. Examples: 1. Code which will assign list of recipients to RCPTName property. Var ListOfRecipients : TStringList; Begin ListOfRecipients := TStringList.Create; LoadAdressBook(ListOfRecipients); { your function for adressbook loading } SMTPClient.RCPTName:=ListOfRecipients; { Francois has correctly handled this don't worry about memory leaks. Look at TSMTPClient.SetRCPTName source} ... 2. Code which will assign list of recipients to HdrTo property. Not required. Only if you wish put this information into message header, it allows all your recipients to see the full list of recipients. Var ListOfRecipients : TStringList; I : Integer; S, T : String; Begin ListOfRecipients := TStringList.Create; LoadAdressBook(ListOfRecipients); { your function for adressbook loading } S := ListOfRecipients.Strings[0]; SMTPClient.HdrTo := ''; For I:=1 To ListOfRecipients.Count-1 Do Begin If Length(S)>=75 Then Begin If SMTPClient.HdrTo='' Then T:='' Else T:=', '#13#10; SMTPClient.HdrTo := SMTPClient.HdrTo+T+S; S:=ListOfRecipients.Strings[I]; End Else S:=S+', '+ListOfRecipients.Strings[I]; End; If SMTPClient.HdrTo='' Then T:='' Else T:=', '#13#10; SMTPClient.HdrTo := SMTPClient.HdrTo+T+S; ... Line in message is limited to 1000 chars including <CRLF>. It's main reason why is list separated into limited lines. Warning: in rcf is written "The maximum total number of recipients that must be buffered is 100 recipients". But many mail servers should accept more than 100. I test with Smail-3.2 (#2 1996-Nov-26) - server works without any problem with list of 312 recipients. |
OnSessionConnected and OnSessionClosed
Arno Garrels garrels@duodata.de 14/01/2006 |
How to use the events OnSessionConnected and OnSessionClosed of the TSmtpCli component?
These events differ from the session events of TWSocket, since TSmtpCli 'intercepts' events of the underlaying TWSocket component. OnSessionConnected is only fired if the banner of the SMTP server has been received. In case of OnSessionConnected of the underlaying TWSocket is triggered with an error, the event is not passed on to the OnSessionConnected event of TSmtpCli, but OnRequestDone is fired with the same error code. On the other side, event OnSessionClosed of TWSocket is always passed on to the OnSessionClosed event of TSmtpCli and in addition OnRequestDone is fired as well, so OnSessionClosed behaves the same as in TWSocket. In other words, the session events are for information purposes only, for example displaying a status icon to tell the user whether a connection is active or inactive. In your application you should control TSmtpCli and program flow from within the OnRequestDone event handler, nearly anything can be done there. |
Priority
DZ dz@mail.caribe.net 21/12/2002 |
I am using ICS SMTP/POP components to send emails from my app. How can I set the priority to "High" in an email I am sending
The "priority" is just an extra header added by some mail clients. It is also important to note that each mail client may have its own way of setting "priority", since there is no standard way. What some mail clients do (such as Outlook and Eudora) is to add one of each of the "priority" headers used by the most common mail clients, just to be safe. For example, these are some headers sent by Eudora: ------ Importance: Normal X-Priority: 3 X-MSMail-Priority: Normal ------ As other client-specific headers, a mail client will use the ones it understands and ignore the rest. |
RcptName sends only one address
Steve Williams stevewilliams@kromestudios.com 21/04/2003 |
> To test the program I was using multiple copies of my own email address, but would get only one copy of the email. Then I tested the program by using three different emails and it worked correctly, because all three of my sons received the email. Does this mean you can not have duplicate email addresses in RcptName
Duplicate addresses are eliminated by the SMTP server. This is not any fault of the SMTP component, but standard behaviour in most SMTP servers. Essentially, you are telling me that Rcpt() has to be used in this way, FromName(), Rctp(), Data(), and that is the reason it didn't work in the program. Mail() combines the MailFrom(), RcptTo() and Data() methods and returns smtpMail in the RequestDone event. Just like Open() combines the Connect() and Helo() methods. The Mail() method uses the same code that the RcptTo() method does, so I see no reason why Mail() would only send to one recipient. Remember that all address added to RcptName must be of the format 'abc@xyz.com'. No pretty names are allowed in the RcptName list, just the plain email address. Some SMTP servers enforce the use of HELO or EHLO, some don't. It is safer to always send it and have the SMTP server ignore it than to never send it and possibly have the SMTP server refuse your mail because you forgot to say HELO. If you do not provide a value for the SignOn property, then your local host name is used in the HELO or EHLO command. This is usually ok. |
Relaying what is that
DZ-Jay dz@caribe.net 21/07/2001 |
Relaying (by itself) to an SMTP server usually means just sending a message from one network to another (both networks being outside of the server's network). For example:
There is ISP "A" There is ISP "B" There is user Foo connected to ISP "C" Foo wants to send email to his friend Fred in "A", so he sends his email using the SMTP server from "C" (his own ISP). This is standard "Mail Delivery". Server C delivers the mail to Server A, which in turn delivers it to Fred's mailbox. Lets say that Foo wants to spam all the users of "A" but does not want to be caught, so he connects to C like always, but when he is going to send email, instead of sending through Server C (the smtp server in his ISP), he sends them through Server B. This means that Server B will have to accept connections from C to deliver to A. As you can see Server B will be just a stupid proxy for the delivery. This is bad because Server B will be very busy delivering all this email that is not from users of B and is not to users of B, so its like taking an unnecessary load for some spammer! If Server A wants to complain about the spam, they will blame Server B because it all came from there.... they don't know it came from Server A. This is what normally is called "Relaying". It is called like that because Relaying means "To pass around" (or something like that). You know those running races in the Olympics where people have to run and pass a stick among themselves? well that's called Relay Race --> because you do not deliver the stick, you do not receive the stick for yourself, you just receive it to pass it to someone else. Most ISP's turn off "Relaying" in their smtp servers to avoid spam. The Smtp makes sure your IP belongs to their network before accepting messages that go to an outside server. You can, however, send email from outside to the inside. |
Reply Codes
DZ-Jay dz@caribe.net 16/09/2001 |
SMTP Reply Codes in Numeric Order:
SMTP COmmand-Reply Sequence: 'S' = Success 'E' = Error 'I' = Intermediate (only applies to DATA command)
|
Reply to
Jan Tomasek 03.10.1998 |
Look at the OnProcessHeader event. This passes a TStrings object to your application. This TStrings object contains all the headers before the component sends them to the SMTP server. You can add, modify or delete headers from this list. To add a Reply-To field, just use the Add method of the TStrings object, such as:
procedure TForm1.SMTPCli1ProcessHeader(Sender: TObject; HdrLines: TStrings); begin HdrLines.Add('Reply-To: <tinyduck@bigpond.com>'); end; |
Request read receipt setting
DZ-Jay dz@caribe.net 23/07/2003 |
Prompt me please how to send e-mail in a format HTML in ICS component and how to establish a priority " Request Read Receipt " (how in Outlook Express).
To request a return receipt you have to add a few headers to your message. Since there is no specific standard on which headers to use, and different mail clients use different headers, what most modern clients do is to try to cover all bases by attempting to send all common return receipt headers. After much search, I have found the following headers: Disposition-Notification-To: hdrFrom Return-Receipt-Requested: hdrFrom Return-Receipt-To: hdrFrom Read-Receipt-To: hdrFrom Registered-Mail-Reply-Requested-By: hdrFrom X-Confirm-Reading-To: hdrFrom Where 'hdrFrom' is the e-mail address of the sender (to whom the return receipt will be returned.) My suggestion is to add all these headers to your message when a return receipt is being requested, unless you are sure that the recipient is using a specific mail client and know which header that client recognizes. |
Sending multiple emails
DZ-Jay <dz@caribe.net 29/06/2003 |
How do I send multiple emails
There are 2 things you can do to send multiple e-mails, and it all depends on what you actually want to do: 1. If you want to send e-mails concurrently, then I suggest instantiating multiple SmtpCli components. But of course, if you are planning to send a lot of messages, this will not be a good idea. 2. If you want to send one after the other, then instead of using a loop, you can use your OnRequestDone state machine to get the next record from the DB, set the SmtpCli component properties, and send a new message after the Quit method is called on each message. You can alternatively do this after the Data method, instead of the Quit method and therefore reuse your current connection to the SMTP server. There is actually one more thing you could do, and its a hybrid of these 2 techniques: 3. You can instantiate a new SmtpCli object for every record returned by the DB until a preset maximum count of objects is reached. After the maximum amount of objects have been instantiated, you can have each one continue to send one message after the other just like I mentioned in #2 above. This way you can send many messages concurrently. This is usually what many mass mailers do. |
Several address
DZ-Jay dz@caribe.net 10/03/2001 |
Just so you understand: There is no "technical" difference between a BCC or a CC or a TO address. They are all recipients of the message. The Mail Server DOES NOT make any distinction between them, they are all given to the server by the same command ("RCPT TO:"). The only difference between all of them is their position in the "headers" of the message:
The "main" recipient appears in the "TO" line The CC's appear in the "CC" line The BCC's do not appear at all. Another important thing to understand is that the "headers" of a message are nothing special -- they are actually part of the "body" itself. The distinction between header and body is made by your mail program when it receives the message -- NOT by the server. So when you are "making" a message in your application to send by email, you gather all recipients (TO, CC, BCC) and give them to the mail server. Then you add them to the appropiate header in your message (or in the case of BCC, you don't add them at all). This is not a function of the mail server, and this is not a function of ICS, this is a function of the developer that is making the application. >And I have noticed in the past that some Smtp servers don't process the >addresses in BCC. All addresses are processed by every mail server (of course, if it is possible, and if they were actually given as recipients), the thing is that your mail program won't add the BCC address to the message header -- so it is "hidden" from anyone reading the message. >Well; I only want to send a mail to several addresses, and that these >adresses don't appear on "To" line. Do you want to send to ONE address, and BCC copies to someone else? or do you want to hide ALL recipients (like some spammers do)? >I have understand that I should put any string in the HdrTo property. >But this doesn't work. >A message is sent to "HdrTo", not to the first item of the RcptName list. The ICS SMTPCli example is very simple, so it does not do any "advanced" things like BCC. It takes all address from ToEdit.text and puts them in the headers. But this is *NOT* ICS, this is an *EXAMPLE* that Francois offers on how to send email. It is up to you -- the developer -- to modify this function to do what you want: - Send the ToEdit.text addresses to the Server - Do not add them to the Headers. |
verify email addresses
DZ-Jay dz@caribe.net 14/01/2006 |
how can i verify a list of email addresses?
It depends on what do you mean by "verify". If you want to check syntax, that's one thing; if you want to validate if they actually exist, that is another. There is no fool proof way to verify the existence of an e-mail address and validate that it is real -- other than sending the e-mail and asking the person to reply. That said, there are various techniques that you can use which will depend on the amount of accuracy you require of the validation. a. Attempt to use the 'VRFY' command on the SMPT server. This is not very reliable, as most ISPs disable this command because it could be abused by spammers, so you might get an "invalid command" or "not supported" response. Accuracy: VERY HIGH (when available) b. Contact the SMTP server of the recipient's ISP or mail service directly and attempt delivery. The way it works is this: You do a DNSLookup on the recipient's domain name, in particular you request the MX record, which will contain the mail host that services that account. You then start an SMTP session with that mail host and attempt delivery by issuing the 'RCPT TO:' command (first try the VRFY command, who knows! it sure doesn't hurt.) The server will then tell you if delivery is allowed to that address. Since most SMTP servers do not allow relaying to external SMTP servers (unless you are a subscriber to their service and are currently connected with one of their network IP addresses), this usually means that if the address is local or not. But this is not really accurate -- the server won't tell you if the address is real or not -- it will only tell you if it will "allow" delivery to it. For example, if the server responds with "550 user unknown" -- ta-DA!!! you now can assume that the address is invalid. But if the server replies with an OK response, it doesn't automatically means it is valid, just that the server will *try* to deliver it. For most applications this is good enough. Accuracy: OK NOTE: Up until recently, this was a very useful technique, but most ISPs nowadays do not allow delivery from "unknown" SMTP servers. They usually keep a whitelist of SMTP servers from other major and minor ISPs. They verify the IP of the connecting SMTP server against this list. Dial-up IP addressess are especially disallowed by virtually everybody. As you can see, it gets harder and harder to actually validate an e-mail address. The problem is that the easier it is to validate an e-mail the better it is for spammers to gather huge lists of very valuable verified e-mail addresses, and nobody wants that. |
Wait for Conenction
DZ-Jay dz@caribe.net 22/09/2001 |
> It seems that SMTPClient.Open is an aysnchronous process and control carries
> on to the next statement. How can I wait for the OPEN request to eiother > fail or succeed before carrying on That's the beauty of it.... you don't "wait" and block your application while expecting a response. What you do instead is this: Whenever a request is received from the server after you send a command -- either good or bad -- the onRequestDone event will get fired. The most common thing to do in that event is to make a sort of "state machine": depending on the current state of your smtp transaction (i.e. which command was sent last), you execute the next command. Of course, since this event gets trigger when the server responds with errors too, you must check for errors. Here's a (very) simplistic way.... its up to you to make it more robust and error-checky: PROCEDURE TForm1.SmtpClientRequestDone(Sender : TObject; RqType : TSmtpRequest; Error : Word); BEGIN IF Error <> 0 THEN BEGIN // handle errors here // Exit; END {Check if the response we got is from the Open command} {if it is, then send the Mail Command} IF RqType = SmtpOpen THEN BEGIN SmtpClient.Mail; Exit; END; {Check if the response we got is from the Mail command} {if it is, then send the Quit command} IF RqType = SmtpMail THEN BEGIN SmtpClient.Quit; Exit; END; // etc... END |
Why do I get '550 Relaying is prohibited' when using the MailSnd demo?
DZ-Jay dz@caribe.net 20/01/2002 |
> I tried the demo program, MailSnd. > > I only can send e-mail to my colleague. > When I tried to send e-mail to the internet > e-mail address, xyz@hotmail.com, I got > an error: > > 550 Relaying is prohibited When you used MailSnd demo, the "SMTP Host" field should contain the SMTP server in your network or ISP, otherwise most external SMTP servers will not accept email going to an outside address if you do not have an IP local to their network. |