Topic:Implementing mail using CARAVAN. ------------------------------------- Intro: First a few things about internet mail. Mail is mostly sent over the internet using SMTP protocol. As you can see from the format of the internet mail address "user@domain.com", every email address is linked to a domain and there is a unique userid for every mail user. Most of the time you can connect to the http or ftp servers using ftp.domain.com or www.domain.com to access these services. But mail works differently and there is a more reliable way to find the mail host using the DNS system. DNS information for a domain contains the mail host name in what is called the MX record. When you access the MX record you will get the names of the SMTP servers that handle the domain's mail. Usually there is more than one such SMTP server and the MX record has a number which indicates the order of preference -- the lower this number the more preferable it is to send the mail to this host. When you send a mail you do the following. 1. Lookup the DNS for the domain's MX record. 2. Make a list of mail hosts for this domain. 3. Send the mail using SMTP protocol to the most preferred mail host - trying the next if any problem. To receive a mail you should: Install an SMTP server and register it on the DNS. In your domain's MX record enter the fully qualified hostname of your SMTP server. Your ISP should be able to help you with this. Now when ever you send the mail from a smtp client it will connect to your SMTP server and post the mail. Caravan can both receive and send mail for a domain. To send mail it is sufficient to know the domain name and the DNS address/es . DNS lookup is built into caravan for this purpose. These can be set in the settings menu of caravan. Additionally most SMTPs do a reverse lookup to check if you are the domain that you claim to be (atleast this is what I guess). So registering your IP address on the DNS is probably important. If you want caravan to receive mail you should register the host on the internet with something like mail.domain.com or anything with a valid IP address. Then change your domains MX record so the it contains this hostname. So much for setting up caravan to receive and send mail. But some things are still left. Caravan is just an engine, it needs to be driven by some code. Sending mail: It is very simple to send mail from Caravan. Caravan uses a object of type mail to send and receive mail. You can create a mail object like this: mail mymail; Some properties of this object have to be set: to: the recipient address cc: cc recipient address. subject: subject of mail text: text of mail attachment : attachments if any. Some properties are set automatically. from: sender's address Since a user is identified when he/she is logged in, this information is filled in by caravan. Conversely if the script is run in public domain (without login) mail cannot be sent. An example for sending mail: mail mymail mymail(to)="kdv_@yahoo.com" mymail(cc)="kdv@response4u.com" mymail(subject)="This is a test for sending mail" mymail(text)="hello\nblah .. blah\n" mymail(attachment)=myfile(file) The mail object is automatically queued ==== more about this after this. An actual example from response4u: if mx(type)="addnewuser" mx(to)=users(email) mx(subject)="Your registration accepted :" mx(subject(01))+=users(agency) mx(subject(01))+="(email:" mx(subject(01))+=users(email) mx(subject(01))+=")." mx(text)="Your request for registration for the digital ad acceptance service has been accepted\r\n. Your login is:" mx(text(01))+=users(login); mx(text(01))+=". Please login with your login and password:\"password\"." mx(text(01))+="\r\n" sql(cords)=users(cords) mx(text(01))+="Your have been assigned the following co-ordinators:\r\n" loop ccl (sql(cords(00))) if sql(cords(ccl(count)))<>"0" users(recordno)=sql(cords(ccl(count))) if users(recordno)=sql(cords(ccl(count))) mx(text(01))+="\r\n" mx(text(01))+=users(agency); mx(text(01))+="-" mx(text(01))+=users(city) mx(text(01))+=": Tel:" mx(text(01))+=users(phone); mx(text(01))+=", email:" mx(text(01))+=users(email); mx(cc)=users(email) endif endif repeat ccl 16 mx(text(01))+="\r\n\r\n" mx(text(01))+="This is a computer generated message: Please do not reply to this email\r\nThank you.\r\n..... registration@response4u.com" elseif; // .... endif Queueing. Q. why caravan has queues and eventhandlers in the first place? Every caravan object is destroyed in the garbage collection phase after the execution is completed except for mail and form objects. Mail objects which have not been sent successfully are automatically queued into the smtp queue which is handled by a user defined eventhandler. Form objects are posted to their destination server in a separate thread -- if there is lot of form generation or if more reliabilty is desired, forms can be put into any user defined queue and will be handled sequentially by the designated eventhandler. One can also explicitly post the mail by: mymail(post);//In this case it will not go into queue if post was successfull. The following code is used as the eventhandler for sending SMTP mail at response4u. example : mailer.html eventhandler(smtp) ;// declares this code as eventhandler for handing "smtp" queue mail mx=_event(item);// gets the topmost item in queue mx(post);// post it, output con; // output to cosole mx(error);// error info if any _event(deleteItem);// deletes this item from queue. // but the mail object mx will append to queue again // if post was not successfull! Programming caravan for receiving mail: Now our server is listening on port 25 for any incoming mail. Still it does not know whether to accept any particular mail and if accepted what to do with it. SMTP protocol needs TWO hooks for receiving mail and these are written using caravan script. The names of these files are fixed. 1. mailuser.html Tells Caravan if it is ok to accept mail for a particular user or not. This is done by setting the property accept mail(accept)="ok"; if you have just this all mail will be accepted or you can have your on logic for this. sample code from response4u:(mailuser.html) (on responsee4u mail is accepted if the user exists) append c:\adint\doc\mail.txt;// appends to this file for logging purpose time t "Got mail for user ";mail(recipient);" at ";t(dd);"-";t(mm);"-";t(yy);" ";t(hour);":";t(minute);// logs the time etc var mailto={mail(recipient)}X{"`*`\@`*`"}:{userid,domain};// a caravan parser at work // splits email address to userid and domain if mailto; // mailto is created if the email was in format user x; // instance of user x(userid)=mailto(userid); // set userid if x(uid); // check if it return valid numeric id if x(uid)<>"0"; // there is non zero id for this user mail(accept)="ok"; // ok to accept "-- Accepted"; // logs this as accepted endif endif endif "\r\n"; // add a linefeed to our log 2. mailaction.html An object of type mail is passed to this script. This is the received mail with all the attendant properties set. You may do what you wish with it. additional properties of recieved mail: recipient: (list of all all recipients of this mail) received: smtp headers which contains the text appended by the routing smtps The recipient property has as many values as there are recipients for this mail. Logic for mailaction.html: Loop through all the recipients and parse each name to get the userid and domain. If it is for our domain, insert the contents of this mail including the text, attachments, header, current time etc into separate fields of our mail table. Additional information like userid is also useful so that an sql query can be used get the users mail, when implementing a web based mail client. Such a facility is implemented on response4u. To avoid confusion I am not attaching this code here because other concepts of caravan language needs to be explained before one can understand this code.