User Friendly Webmail Client

POP3 Email Client with Attachments
By Robert Jones

This tutorial is quite simple if you are familiar with many of the basic practices of ColdFusion. It outlines exactly how to create a webbased email client for all of your clients currently hosted by your company. It is basically an expansion on Pablo Varando's Email client, which is all well and good for those of us that are web-savvy and dont care about alert boxes, but in my experiance clients that aren't very familiar with the internet tend to freak out and think something is wrong with their computers when they see and alert box, which tends to be a hassle when you provide customer support and they are calling you every five seconds because of a simple harmless alert.

Therefore I set out to provide an extreamly user friendly email sending and reciveing client. The files associated with thie tutorial are as follows:

application.cfm - A simple session management application
index.cfm - this is our login page, you could realistically name this one login.cfm, but remember we are going for user friendlyness
inbox.cfm - This one should be obvious, delete.cfm and send.cfm are set as cfincludes here
details.cfm - viewing messages and providing a way to reply/forward/delete the messages
compose.cfm - create new messages, reply to messages, and also forward messages
delete.cfm - delete messages from the POP3 server
send.cfm - send messages
upload.cfm - this is used for attaching messages to outgoing emails.
LinkFinder.cfm - a simple custom tag that parses urls in received messages and makes them active http://www.cfcomet.com/utilities/CF_LinkFinder_v1-1.zip


File: application.cfm
this file isn't to hard to figure out, it's simply to manage active sessions you can set the timespan to be how ever long you feel neccisary

<cfapplication name="name" sessionmanagement="yes" sessiontimeout="#CreateTimeSpan(0,0,10,0)#">

^Top


File: index.cfm
This is our login screen, it gives the user the opportunity to remember their user ID so that they don't have to enter it everytime they come to check their email, because people like that sort of thing ;-P

Note: I only use this system for those of my clients that are hosted on MY system and thus all have the same POP3 server, but it is easily adaptable for those of you who wish to use it for anyone.

<!--- If the user has logged out, we clear the session variables --->
<cfif IsDefined('logout')>
  <cfscript>
    StructClear(Session);
  </cfscript>
<!--- if the cookie was set and the user wants to sign in as someone else, we clear the cookie --->
<cfelseif IsDefined('newuser')>
  <cfcookie name="username" expires="now">
  <cfscript>
    StructClear(Cookie);
  </cfscript>
</cfif>

<!--- If the user is still active we simply redirect them right to their Inbox --->
<cfif IsDefined('session.username') and IsDefined('session.userpass')>
  <cflocation url="inbox.cfm" addtoken="yes">
</cfif>


<!--- Our login form --->
<form method="post" action="inbox.cfm?login=try">
<table border="0" width="80%" cellspacing="0" cellpadding="0" align="center">

<!--- If we have a session timeout or an invalid username/password, display an error message here --->
<cfif IsDefined('error')>
  <tr>
     <td colspan="2" align="center">
       <span style="color: red">* Invalid Username or Password</span>
    </td>
  </tr>
</cfif>

   <tr>
     <td align="right" width="50%">
       <font face="Arial" size="2">Username:&nbsp;</font>
     </td>
     <td align="left" width="50%">
<!--- If the user has chosen to remember their username we insert it as a hidden feild and display it in bold letters --->
       <cfif IsDefined('cookie.username')>
         <cfoutput>
           <input type="hidden" name="userNAME" value="#cookie.username#">
           <font face="Arial" size="2"><b>#cookie.username#</b></font>
         </cfoutput>
<!--- If they haven't set thier cookies, we display a text input --->
       <cfelse>
         <input type="text" name="userNAME" size="30" >
       </cfif>
     </td>
   </tr>

<!--- We do not want to remember the users password in the cookie, so this is just a plain ole' password field --->
   <tr>
     <td align="right" width="50%">
       <font face="Arial" size="2">Password:&nbsp;</font>
     </td>
     <td align="left" width="50%">
       <input type="password" name="userPASS" size="30">
     </td>
   </tr>

   <tr>
     <td colspan="2" align="center">
<!--- If the cookies haven't been set yet, we ask the user if the WANT them set via a checkbox --->
        <cfif NOT IsDefined('cookie.username')>
          <input type="checkbox" name="remember" value="indeed"><font face="Arial" size="2"> Remember ID on this Computer?</font>
<!---
If the cookies ARE set we ask them if the are the user that is set by the cookie, if not they can log out, if so we pass the value of "remember" along in a hidden field
--->

        <cfelse>
          <cfoutput>
            <input type="hidden" name="remember" value="indeed">
            <font face="Arial" size="2">Not #cookie.username#? <a href="index.cfm?newuser=true">Login as a different user</a></font>
          </cfoutput>
        </cfif>
     </td>
   </tr>

   <tr>
     <td colspan="2" align="center">
       <input type="submit" value="Log In">
     </td>
   </tr>

</table>
</form>

^Top


File: inbox.cfm
This is the meat and potatoes of our application, without this page, we wouldn't be able to Recieve, send OR delete Messages, so its a tad bit important.
The formatting and layout of this page can be EASILY changed to fit you needs, but you probably already knew that right?

<!---
Some if/else statements to start us off here
First we find out if the user filled out the login form,
or if they were simply redirected because their session
was still valid.
--->

<cfif IsDefined('login')>
<!---
If the user did use the login form,
we check to make sure the user entered data,
if so, we set the form variables up as session variables for easy use
--->

<cfif IsDefined('form.userNAME') and #form.userPASS# is not "">
  <cfset session.username=#form.userNAME#>
  <cfset session.userpass=#form.userPASS#>
<!---
If they want us to remember there login info We'll set a cookie
otherwise we will set a cookie with the same name to expire now
that way there will deffinently be no cookies set on the users machine
--->

    <cfif IsDefined('form.remember')>
      <cfcookie name="username" value="#form.userNAME#" expires="never">
    <cfelse>
      <cfcookie name="username" expires="now">
    </cfif>
<!---
If the user didn't use the login form OR they didn't enter valid information
Redirect them to the index screen with error set to true
--->

  <cfelse>

    <cflocation url="index.cfm?error=true" addtoken="yes">
  </cfif>
</cfif>

<!---
Here is where the sending and deleting includes come in
We check to see if an action is defined at all,
then we find out what that function is and include the appropriete file for that action
--->

<cfif isDefined('action')>
  <cfif action is "send">
    <cfinclude template="send.cfm">
  <cfelseif action is "delete">
    <cfinclude template="delete.cfm">
  </cfif>
</cfif>

<!---
This is where we retrieve the messages from the POP3 server
We've surrounded the CFPOP tag with a CFTRY statement
This is another way to check to be sure that the user entered valid data
if there are any errors thrown back at us we redirect the user to the login screen
this is what they are used to anyway right?
--->

<cftry>
  <cfpop action="getheaderonly" name="qGetMessages" server="mail.yoursever.com" timeout="90" username="#session.username#" password="#session.userpass#">
<cfcatch type="Any">
  <cflocation url="index.cfm?error=true">
  <cfabort>
</cfcatch>
</cftry>

<!---
This is just a header,
I like to have an image here at the top,
you can of course put whatever you want here
--->

<table width=
"100%" border="0">
  <tr>
    <td align="left">
      <img src="images/logo.gif">
    </td>
    <td align="right">
      <font size="2" face="Arial">
      <cfoutput>
       #session.username#<br>
      <a href="index.cfm?logout=true">Log Out</a>
      </font>
      </cfoutput>
    </td>
  </tr>
</table>

<table width="100%" border="0" cellpadding="3" cellspacing="0">
  <tr bgcolor="#000000">
    <td width="44%">
      <font size="2" face="Arial" color="white">
      <b>Inbox</b>
      </font>
    </td>
    <td width="54%" align="center">
      <font size="2" face="Arial" color="red"><b>
<!---
This is our conformation cell,
if the user sent or deleted something,
this is where we tell them
Its just one of those user friendly kinda things
--->

         <cfif
IsDefined('sent')>
           --MESSAGE SENT--
        <cfelseif IsDefined('delete')>
           --MESSAGE DELETED--
        </cfif>
      </b></font>
    </td>
    <td width="1%" colspan="2" align="right">
      <a href="inbox.cfm">Refresh</a>
    </td>
    <td width="1%" align="right">
      <font color="#FFFFFF">&nbsp;||&nbsp;</font><a href="compose.cfm">Compose</a>
    </td>
  </tr>
</table>


<!---
This is our column headers,
They are displayed regaurdless of weather or not there are messages
so there is really nothing all that special about them
--->

<table width="100%" border="0" cellpadding="2" cellspacing="1">
  <tr bgcolor="#efefef">
    <td width="14%" colspan="2">
      <font size="2" face="Arial">
        <b>DATE</b>
      </font>
    </td>
    <td width="20%">


All ColdFusion Tutorials By Author: Robert Jones
  • User Friendly Webmail Client
    This is an expansion of Pablo Varando's Email client, I heard a few folks say that they had problems viewing the attachments in the way that Pablo's tutorial outlined it, so I came up with a new way.
    Author: Robert Jones
    Views: 19,973
    Posted Date: Thursday, June 19, 2003