Programmer to ProgrammerTM | |||||
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||
The ASPToday
Article March 21, 2001 |
Previous
article - March 20, 2001 |
Next
article - March 22, 2001 | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||
ABSTRACT |
| ||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||
Article Discussion | Rate this article | Related Links | Index Entries | ||||||||
ARTICLE |
There are several articles covering how to send emails from an ASP web server, but not how to receive and process mails. The fact is that the IIS SMTP service is capable of receiving emails, including attachments, and your ASP pages can process them. It's a wonderful way of receiving information from remote systems and persons in an asynchronous way.
This article includes a sample application that's a modified version of my previous article's, Create a common user updateable news publishing system with IE HTML Editing, sample. It's been improved to receive news for publishing by email and automatically process them. A Windows Host script that runs on the server scheduler regularly calls an email-processing page.
Microsoft's IIS server package includes an SMTP service to send and receive emails. This service should not be confused with a regular email server most companies use, and it's primary suited for automatic emails from/to the website. Since it's part of the IIS package it's usually installed even on shared servers. If in doubt, check with your hosting provider.
Using the SMTP service to send emails is common, and there are several articles on how to do it, including here on ASPToday. But the service can also receive emails sent to an address formatted like this: user@www.domain.top_domain (use your full web site address, not just the domain).
If you check on your server directory tree, there is a mailroot folder on the same level as the wwwroot and ftproot. Inside the mailroot folder there are other subfolders. These are used to store email messages and each one has its use:
When new messages are created, they are saved to the pickup folder to await delivery. Incoming messages are all stored on the Drop folder. There are no individual mailboxes for each user (there are, in fact, no users). The CDONTS API, that is used to work with the service, makes the separation.
ASPToday has other articles about this service, including two on how to configure it. Check them for extra information or if you are having trouble using the service, http://www.asptoday.com/content/articles/20000306.asp?WROXEMPTOKEN=1161130Zh4iBkFYw7zlBupiCnE may be a good start.
To read messages we must create a session for a given user, identified by its email address.The session will filter the messages in the Drop folder, allowing access only to the given email address messages. There are no security issues involved and any page, included anonymous users, can run this code.
set session = server.CreateObject("CDONTS.Session") session.logonsmtp "Friendly Username", "email address"
When opening a session we supply a friendly name and an email address, both of which will be used if you send an email during the session. Browsing the mail messages on the inbox folder is as easy as opening and looping a collection:
Select one of the two accessible folders: Inbox or Outbox :
' Goto Default Inbox Folder
set inbox = session.GetDefaultFolder(CdoDefaultFolderInbox)
Get and loop the folder messages collection (the example will output the messages subject and sent date):
' Get messages collection set messages = inbox.messages ' Loop messages and compare subjects with the defined word for each message in messages ' get messages body text and sent date subject = message.subject maildate = message.timesent Response.Write maildate & ": " & subject & "<br>" next
All that's left is to close the session and discard object references:
' Close current session session.logoff() ' Clean Objects Used set message = nothing set messages = nothing set inbox = nothing set session = nothing
Pic. 2 show the object model for CDONTS. For the complete reference check the article links.
Each email message, incoming or outgoing, can have any number of file attachments, like in any email program because after all this is a SMTP service and SMTP is the internet email protocol. Each message has an attachments collection with its attachments, which can be saved to disk. In this section I'm only covering the processing of received attachments.
' Get messages collection set messages = inbox.messages ' Loop messages for each message in messages ' get and loop message attachments attachments = message.attachments for each attach in attachments ' Write attachment name to browser, save file to disk C: root and delete it on the message response.write attach.name & "<br>" attach.writetofile "C:\" & attach.name attach.delete next next
There is no way to retrieve the file data and insert it in a variable, in order to process or save it to a database. The only option is to save it to disk (eventually with an unique name instead of the original name, to avoid overwriting if two messages share the same attachment name) and read the disk file.
Philippe Collignon's article File Uploading with ASP and VBScript includes some example functions that work with binary data in VBScript. These functions can be very useful if you decide to manipulate binary attachments from VBScript.
This article's sample application is a modified version of my former article, Create a common user updateable news publishing system with IE HTML Editing, sample. This article will help you to understand the sample, but it's not necessary. However since the ASPToday archive is now fee based, I'll reproduce the sample description from the former article:
The example application is a press-release publisher allowing a common user with a browser to post new press releases with formatted texts and a picture. The application has two interfaces, one for editing, accessed through the default.asp page and a public interface accessed through the newlist.asp page.
Editing users may insert new press releases, edit the existing ones, and delete them to a recycle-bin. Public users see a list of active press releases and can click on the date to open them. Each press release will feature a date, title (unformatted), image (optional) and formatted body text."
The new version can receive news for publishing from an email, as well as from the already existing web form.
The old database had a single table to contain articles. To process emails we will add a new table, to store article senders information. Only emails matching this table data will be processed:
The GetEmails.asp page is charged with the email-processing task. Every time this page is called it will loop all senders and process existing emails. Each sender has its name ID, an email address on your SMTP server (name@yoursiteaddress) and a subject keyword. The processing page will check emails intended to each email addresses on this list and verify if the subject field contains the given keyword. Only emails that meet both criteria will be processed. Pic. 5 shows the subject keyword being the same for all senders, but they could be different. Keywords may also be multi-word strings.
The page will give some feedback to the calling http client that is useful for debugging. In a production environment the page will be called from a scheduler and the HTML response discarded.
The following code implements the email processing and should be easy to understand:
' Query list of possible senders. Loop list Set objRecordSet = objDataCon.Execute("SELECT senders",email, id, subject FROM senders", lRecordsFound) If not objrecordset.eof Then objrecordset.movefirst while not objrecordset.eof response.write "<p><b>" & objrecordset("email") & "</b></p>" ' Open session for email set session = server.CreateObject("CDONTS.Session") session.logonsmtp "News", cstr(objrecordset("email")) ' Goto Default Inbox Folder set inbox = session.GetDefaultFolder(CdoDefaultFolderInbox) ' Get messages collection set messages = inbox.messages ' Loop messages and compare subjects with the defined word for each message in messages if instr(ucase(message.subject), ucase(objrecordset("subject"))) then ' get messages body text and sent date text = message.htmltext maildate = message.timesent ' Double commasquote characters to avoid delimiter problems text = replace(text, "'", "''") text = replace(text, """", """") ' Save news do database savenews maildate, text, cstr(ucase(objrecordset("id"))) ' Delete Message message.delete Response.Write maildate & "<br>" & replace(text, vbcrlf, "<br>") & "<hr>" end if next ' Close current session session.logoff() ' Move to next sender objrecordset.movenext wend end if
Emails are deleted on the SMTP server after processing to avoid duplication and to reclaim disk space. Note that message bodies are retrieved in HTML format since the CDO API keeps both text and html properties synchronized, regardless of the initial mail format. And since the news application is intended to publish HTML, it's this format that's retrieved.
After a message has been retrieved and identified as a target message, its fields are accessed as text or html that can be saved to a database using an INSERT statement. The processing page uses this function, defined in the news.inc include file, to achieve this:
The parameters are already made SQL Ready on the GetEmails.asp page by doubling any commaquotes present.
Sub SaveNews(newsdate, subject, textin) Dim objDataCon Dim objRecordSet Dim lRecordsFound set objDataCon = server.createobject("ADODB.Connection") set objRecordSet = server.createobject("ADODB.recordset") objDataCon.ConnectionTimeout = 15 objDataCon.CommandTimeout = 30 objDataCon.Open ConnectString, DBUsername(), DBPassword() Set objRecordSet = objDataCon.Execute("INSERT INTO messages (ndate, title, message, online) VALUES (" & & _ dateformat(newsdate) & ", '" & subject & "', '" & textin & "', -1) ", lRecordsFound) objDataCon.Close set objrecordset = nothing set objDataCon = nothing End Sub
The online flag is set to TRUE on the INCLUDEINSERT SQL statement, so that messages are online as soon as they are saved
After the GetEmails.asp page has accessed the email it will add the message to the messages table in the correct format. Then it will display this when you run the default.asp page in the list of news items. The picture below shows this, after a message titled News was added.
When this item is clicked on, we can see the email has been transformed into a news message, the title is the news title, the message is the news body and the date of the mail is the date of the news message.
The Windows Scripting Host is a windows component that allows the running of scripts on server or desktop computer. Originally included as an IIS component it became standard on most recent windows editions ( W98 and W2000). Intended to replace batch files as the operating system scripting language, it can run both VBScript and JavaScript files. If you install the engines you can also run many more languages.
On the sample there is a LoadPage.vbs script that when ran calls the GetEmails.asp page, using the HTTP client of the Microsoft XML Parser:
on error resume next Dim http, url ' Set URL here url = "http://www.serveraddress.com/mailnews/getemails.asp" ' Try tu use the mosty recent version of the parser. ' If fails then create an older and less reliable version set http = wscript.createobject("MSXML2.serverXMLHTTP") if error.number <> 0 then _ set http = wscript.createobject("microsoft.XMLHTTP") http.open "GET", cstr(url), false http.send set http = nothing
Microsoft advises that on the Knowledge Base you should not use the http client included on versions prior to 3.0 on a server ( Microsoft.XMLHTTP). Personally I've never had problems with it in this environment since there is no concurrent access (it's the scheduler that calls the script, not the IIS server). Since you cannot always control what the server has installed, I decided to support both. The script checks for the secure version first and if it fails it instantiates the older version. The remaining code is similar and will work with any of the objects. Don't forget to change the URL variable to reflect your server.
To regularly call this script I use the built-in NT/2000 scheduler, using the command line. Windows 2000 includes in the control panel a visual applet to schedule tasks, unlike NT. Some versions of Internet Explorer also add a visual scheduler. The command line method works with both.
Open a command prompt ( CMD.EXE) and write:
Don't forget the to encase the path with quotations marks and to include the full path. The scheduled script will run every day at 5:00 in the morning. If you need to run it more often then you should schedule several tasks, one for each required time.
If you don't have access to the server scheduler you can run it on any computer with internet access, since the script calls the getemails.asp page using http. I've used this setup successfully using a separate machine to call the server.
Another option is to write your own NT/W2000 service to call the processing page. This is the most flexible and robust approach, but is also the most difficult to implement. If you're comfortable with writing services you can create your own scheduler, or even better a task repeater that repeats a task at a given time. A repeater is better suited to this kind of task since the purpose is to repeat the task over time. However, the writing of a service is out of this article scope.
This approach is also limited to users who have full control over the server as it's very unlikely that shared server hosts will allow their clients to install services on their machines.
The sample application demonstrates one of the possible uses for server email processing. There are several other possibilities, some of which I present here:
We could allow picture submission as attachments. The sample application doesn't support the inclusion of pictures on submitted news, something that the base news application supports when loading through the browser. It could be changed so that if an attachment is present it is stored to the file database.
The sample application is intended as a ready-to-run sample so you can easily evaluate the idea and check if it's for you. However, in a real world production environment there are some shortcomings that must be addressed:
In order to help migration to other databases there are some functions on the news.inc file that wraps most changes when using different databases. By changing the ConnectString(), DBUsername(), DBPassword(), FileConnectString(), FileOLEDBConnecString() and DateFormat() functions once, all of the database access pages will use the new database and its formats.
There are some other possible uses for these email-processing capabilities:
Included with this article there is a sample application, composed of the following files:
To use the sample, create a folder anywhere below the IIS root folder and copy all files to it (all files should be in the same folder). No adjusting or ODBC DSN is needed. Then open news.mdb, using Ms-Access and change the sender's table data to match the users (name, email address and subject keywords) for your server.
Note: Access databases were used to allow out-of-the-box usage, without any setup. Convert to a database server (SQL Server, Oracle, etc) for production use. The HTML editor page (from the former article) is not compatible with Netscape (any version), and IE versions previous to 4. All Access files are for Ms-Access 2000 and are not readable by previous versions, including Access 97.
Q266452
- HOWTO: Send an Attachment in ASP Using CDONTS and the Posting
Acceptor
Q186204
- HOWTO: Use CDONTS to Collect and Mail Information From a User
Q247958
- How to Change the Path Used by the SMTP Service for the NTOP
Q193685
- Sending E-mail from a Command Prompt Using the IIS SMTP Service
Q233293
- HOWTO: Set SMTP Header Properties Using CDONTS
Q221495
- How to Create Scheduled Email Messages Using WSH and CDONTS
Article
on MSDN Library
Article:
Using Advanced CDONTS Techniques
Article:
Microsoft Internet Developers
CDONTS
Object Model
|
| |||||||
|
| |||||||||||||||
|
ASPToday is brought to you by
Wrox Press (http://www.wrox.com/). Please see our terms
and conditions and privacy
policy. ASPToday is optimised for Microsoft Internet Explorer 5 browsers. Please report any website problems to webmaster@asptoday.com. Copyright © 2001 Wrox Press. All Rights Reserved. |