#!/bin/sh # MetaCard 2.4 stack # The following is not ASCII text, # so now would be a good time to q out of more exec mc $0 "$@" "altEmailHarness3on stripAndShip put "" into fld "server" put "" into fld "username" put "" into fld "password" put "" into fld "from" put "" into fld "senderName" put "" into fld "to" put "" into fld "cc" put "" into fld "bcc" put "" into fld "replyToEmail" put "" into fld "subject" put "" into fld "messageText" put "" into fld "altLog" hilite btn "Use Authentication" end stripAndShip on doIt end doIt }Test harness for libSmtp253  UTahoma UTahoma WTahomaUTahoma UTahoma Wtahoma WTahomaWTahoma U Courier New Wtahoma Utahoma WTahomaUTahoma UTahoma Utahoma cREVGeneralscriptChecksumdas@]D% debugObjects bookmarks handlerListstripAndShip doIt tempScript prevHandler stripAndShipscriptSelectionchar 410 to 409script

on stripAndShip

put "" into fld "server"

put "" into fld "username"

put "" into fld "password"

put "" into fld "from"

put "" into fld "senderName"

put "" into fld "to"

put "" into fld "cc"

put "" into fld "bcc"

put "" into fld "replyToEmail"

put "" into fld "subject"

put "" into fld "messageText"

put "" into fld "altLog"

hilite btn "Use Authentication"

end stripAndShip

on doIt

end doIt

cREVGeometryCachestackID1058 @ cREVGeneral bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0scriptcREVGeometryCacheIDs"11309631585141015113096874857410411130968748575104211309631585151016113114310636210511130967972136103811309679721371039113114173855910501130967967577103511309721820281048113096796757810361130963165343101711309631653441018113096409207010271130964092071102811309631105611011113096311056210121131143142757105211309630689591006113096319967610211130970834442104311309678384411030113096783844210311130963066320100411309631020801009113096787181610331131143142769105311309631020811010113096309660010071130963096601100811309679345941034113097172746710461130963209702102411309632034871022cREVGeometrycachetotal34order       Label Field "[d cREVTable currentviewServer* cREVGeneral revUniqueID 1130963066320 Server*  Label Field "yd cREVTable currentviewUsername cREVGeneral revUniqueID 1130963096600 Username  Label Field "d cREVTable currentviewPassword cREVGeneral revUniqueID 1130963102080 Password  Label Field U1 cREVTable currentviewTo* cREVGeneral revUniqueID 1130963110561 To*  Label Field "d cREVTable currentviewSubject cREVGeneral revUniqueID 1130963158514 Subject  Label Field " d cREVTable currentview Message Text cREVGeneral revUniqueID 1130963165343 Message Text Send EmailEpvon mouseUp --> INIT VARS put fld "server" into tServer put fld "username" into tUsername put fld "password" into tPassword put fld "from" into tFrom put fld "senderName" into tSenderName put fld "to" into tTo put fld "cc" into tCC put fld "bcc" into tBCC put fld "replyToEmail" into tReplyToEmail put fld "subject" into tSubject put fld "messageText" into tMsg if the hilite of btn "use Authentication" is true then put "AUTO" into tAuthentication else put "" into tAuthentication end if put 25 into tPort get altSendEmail(tServer,tUsername,tPassword,tAuthentication,tPort,tFrom,tSenderName,tTo,tCC,tBCC,tReplyToEmail,tSubject,tMsg) if it is "false" then answer information "Send Failed" end mouseUp --> BEGIN altSendMail SCRIPTS --> COPY ALL FUNCTIONS AND HANDLERS BELOW ------------------------------------------ function altSendEmail pServer,pUsername,pPassword,pAuthentication,pPort,pFrom,pSenderName,pTo,pCC,pBCC,pReplyToEmail,pSubject,pMsg --> SENDS PLAIN TEXT EMAIL WHERE: --> pServer IS DOMAIN OR IPADDRESS OF SMTP SERVER (ex. mail.ibm.com) --> pUsername IS THE USERNAME FOR THE USER ON THAT SERVER --> pPassword IS THE PASSWORD FOR THE USER ON THAT SERVER --> pAuthentication IS THE AUTHENTICATION TYPE: AUTO,PLAIN,LOGIN or "" FOR NO AUTHENTICATION --> pPort IS THE PORT NUMBER (USUALLY 25) --> pFrom IS THE EMAIL ADDRESS OF THE USER SENDING THE EMAIL *NOTE* FOR MOST SMTP SERVERS IT MUST BE A VALID EMAIL ADDRESS! --> pSenderName IS THE NAME OF THE USER SENDING THE EMAIL --> pTo IS A LINEFEED DELIMITED LIST OF 'TO' RECIPIENTS --> pCC IS A LINEFEED DELIMITED LIST OF 'CC' RECIPIENTS --> pBCC IS A LINEFEED DELIMITED LIST OF 'BCC' RECIPIENTS --> pReplyToEmail IS THE EMAIL ADDRESS WHICH ALL REPLIES ARE SENT TO --> pSubject IS THE SUBJECT OF THE EMAIL --> pMsg IS THE TEXT OF THE MESSAGE TO BE SENT if "libSmtp253" is not among the lines of the stacksInUse then start using stack "libSmtp253" end if if pPort is "" then put 25 into pPort altLog "" --> BUILD HEADERS AND RECIPIENT LIST put "" into tHeader put "from: " & line 1 of pSenderName && "<" & line 1 of pFrom & ">" & cr after tHeader put "subject: " & line 1 of pSubject & cr after tHeader put "sender: " & line 1 of pSenderName & cr after tHeader put "reply-to: " & line 1 of pReplyToEmail & cr after tHeader --> THIS CONSTRUCTS THE LIST OF EMAIL RECIPIENTS --> EVERYONE WILL SEE USERS IN LISTED IN tHeader --> tRecipientList IS LIST OF EVERYONE SENT AN EMAIL put "" into tRecipientList repeat for each line L in pTo if "@" is not in L then next repeat put "to: " & L & cr after tHeader put L & cr after tRecipientList end repeat repeat for each line M in pCC if "@" is not in M then next repeat put "cc: " & M & cr after tHeader put M & cr after tRecipientList end repeat repeat for each line N in pBCC if "@" is not in N then next repeat put N & cr after tRecipientList end repeat delete last char of tRecipientList --> OPEN CONNECTION TO SMTP SERVER get smtpOpen(pServer,pPort,pAuthentication,pUsername,pPassword) altLog "Opening:" & it if it is false then get smtpClose() altLog "Error Connecting to Server:" & it altLog smtpGetTranscript() return "false" end if put tHeader &cr& pMsg into tBody --> SEND EMAIL get smtpSend(pFrom,tRecipientList,tBody) altLog "Sending:" & it if it is "false" then put "false" into tReturn get smtpClose() altLog "Closing:" & it if it is "false" then put "false" into tReturn altLog smtpGetTranscript() stop using stack "libSmtp253" return tReturn end altSendEmail on altLog pMsg if there is not a fld "altLog" then exit altLog if pMsg is "" then put "" into fld "altLog" else put pMsg & cr after fld "altlog" set the vscroll of fld "altlog" to 10000000 end if end altLog 1zR cREVGeneral scriptChecksumCB OzWY7T breakPoints handlerListmouseUp altSendEmail altLogscriptSelectionchar 2013 to 2012 revUniqueID 1130963199676 bookmarks tempScript prevHandlermouseUpscript

on mouseUp

--> INIT VARS

put fld "server" into tServer

put fld "username" into tUsername

put fld "password" into tPassword

put fld "from" into tFrom

put fld "senderName" into tSenderName

put fld "to" into tTo

put fld "cc" into tCC

put fld "bcc" into tBCC

put fld "replyToEmail" into tReplyToEmail

put fld "subject" into tSubject

put fld "messageText" into tMsg

if the hilite of btn "use Authentication" is true then

put "AUTO" into tAuthentication

else

put "" into tAuthentication

end if

put 25 into tPort

get altSendEmail(tServer,tUsername,tPassword,tAuthentication,tPort,tFrom,tSenderName,tTo,tCC,tBCC,tReplyToEmail,tSubject,tMsg)

if it is "false" then answer information "Send Failed"

end mouseUp

--> BEGIN altSendMail SCRIPTS

--> COPY ALL FUNCTIONS AND HANDLERS BELOW

------------------------------------------

function altSendEmail pServer,pUsername,pPassword,pAuthentication,pPort,pFrom,pSenderName,pTo,pCC,pBCC,pReplyToEmail,pSubject,pMsg

--> SENDS PLAIN TEXT EMAIL WHERE:

--> pServer IS DOMAIN OR IPADDRESS OF SMTP SERVER (ex. mail.ibm.com)

--> pUsername IS THE USERNAME FOR THE USER ON THAT SERVER

--> pPassword IS THE PASSWORD FOR THE USER ON THAT SERVER

--> pAuthentication IS THE AUTHENTICATION TYPE: AUTO,PLAIN,LOGIN or "" FOR NO AUTHENTICATION

--> pPort IS THE PORT NUMBER (USUALLY 25)

--> pFrom IS THE EMAIL ADDRESS OF THE USER SENDING THE EMAIL *NOTE* FOR MOST SMTP SERVERS IT MUST BE A VALID EMAIL ADDRESS!

--> pSenderName IS THE NAME OF THE USER SENDING THE EMAIL

--> pTo IS A LINEFEED DELIMITED LIST OF 'TO' RECIPIENTS

--> pCC IS A LINEFEED DELIMITED LIST OF 'CC' RECIPIENTS

--> pBCC IS A LINEFEED DELIMITED LIST OF 'BCC' RECIPIENTS

--> pReplyToEmail IS THE EMAIL ADDRESS WHICH ALL REPLIES ARE SENT TO

--> pSubject IS THE SUBJECT OF THE EMAIL

--> pMsg IS THE TEXT OF THE MESSAGE TO BE SENT

if "libSmtp253" is not among the lines of the stacksInUse then

start using stack "libSmtp253"

end if

if pPort is "" then put 25 into pPort

altLog ""

--> BUILD HEADERS AND RECIPIENT LIST

put "" into tHeader

put "from: " & line 1 of pSenderName && "<" & line 1 of pFrom & ">" & cr after tHeader

put "subject: " & line 1 of pSubject & cr after tHeader

put "sender: " & line 1 of pSenderName & cr after tHeader

put "reply-to: " & line 1 of pReplyToEmail & cr after tHeader

--> THIS CONSTRUCTS THE LIST OF EMAIL RECIPIENTS

--> EVERYONE WILL SEE USERS IN LISTED IN tHeader

--> tRecipientList IS LIST OF EVERYONE SENT AN EMAIL

put "" into tRecipientList

repeat for each line L in pTo

if "@" is not in L then next repeat

put "to: " & L & cr after tHeader

put L & cr after tRecipientList

end repeat

repeat for each line M in pCC

if "@" is not in M then next repeat

put "cc: " & M & cr after tHeader

put M & cr after tRecipientList

end repeat

repeat for each line N in pBCC

if "@" is not in N then next repeat

put N & cr after tRecipientList

end repeat

delete last char of tRecipientList

--> OPEN CONNECTION TO SMTP SERVER

get smtpOpen(pServer,pPort,pAuthentication,pUsername,pPassword)

altLog "Opening:" & it

if it is false then

get smtpClose()

altLog "Error Connecting to Server:" & it

altLog smtpGetTranscript()

return "false"

end if

put tHeader &cr& pMsg into tBody

--> SEND EMAIL

get smtpSend(pFrom,tRecipientList,tBody)

altLog "Sending:" & it

if it is "false" then put "false" into tReturn

get smtpClose()

altLog "Closing:" & it

if it is "false" then put "false" into tReturn

altLog smtpGetTranscript()

stop using stack "libSmtp253"

return tReturn

end altSendEmail

on altLog pMsg

if there is not a fld "altLog" then exit altLog

if pMsg is "" then

put "" into fld "altLog"

else

put pMsg & cr after fld "altlog"

set the vscroll of fld "altlog" to 10000000

end if

end altLog

 Label Field "d cREVTable currentviewLog cREVGeneral revUniqueID 1130963209702 Log fro "d cREVTable currentview From Email* cREVGeneral revUniqueID 1130964092070 From Email* fro "d cREVTable currentview Sender's Name cREVGeneral revUniqueID 1130967838441 Sender's Name  Label Field 7 cREVTable currentviewAccount Settings cREVGeneral revUniqueID 1130967871816 Account Settings  Label Field  cREVTable currentviewEmail Settings cREVGeneral revUniqueID 1130967934594 Email Settings  CCd UH1 cREVTable currentviewCC cREVGeneral revUniqueID 1130967967577 CC BCCs Uz1 cREVTable currentviewBCC cREVGeneral revUniqueID 1130967972136 BCC  Label Field "d cREVTable currentviewReply To Email cREVGeneral revUniqueID 1130968748574 Reply To Email  description  7on linkClicked pLink revGoURL pLink end linkClicked 32 cREVGeneral revUniqueID 1130970834442 altEmailHarness  .by Chipp Walters using Sean Shao's libSmtp253 - What does this do?   5Makes sending an email from your stack super simple. This is a simple test stack for Sean Shao's fine SMTP library used for sending emails directly from Revolution. This stack works with the included library stack libSmtp253.   tIncluded in this stack is a simple altSendMail function, which is a basic wrapper around Sean's libSmtp253 library. # # .2 ` j SSean's library stacks are great, and they offer so many options...in fact, too many options! You can send HTML as well as Plain text, connect to various servers with different authentication schemes, and more! The reason I wrote this stack is to build a very simple test harness which allow you to send PLAIN text email directly from Rev. How to use it?  mYou'll need to have an existing SMTP server you want to use and fill out the Account Settings appropriately. M M ] zThen fill out your Email Settings and press the Send Email button. Below in the Log field you will see what is happening.   ! 0 :? iTo incorporate into your stack, just copy the altSendEmail and altLog functions from the Send Email button into your own button, and copy the substack libSmtp253 into your main stack. If you want to log and check activity, create a fld "altLog" on the same card where you are calling altSendEmail and all communication with the server will be displayed there. . . : ? E Y b5  G  (  (@ fAll the documentation for the parameters of altSendEmail function are in the script. Hope this helps! , , 8- 4Muchos Kudos to Sean Shao and the great libSmtp253!  3 Chipp Walters  Altuit, inc   DirectionsEpXon mouseUp get the htmlText of fld "description" answer information it end mouseUp 0 R cREVGeneral revUniqueID 1130971727467  Label Field  B cREVTable currentview(* denotes fld which must have valid data cREVGeneral revUniqueID 1130972182028 )* denotes fld which must have valid data serveri`[ cREVGeneral revUniqueID 1130963068959   usernamei`y cREVGeneral revUniqueID 1130963096601   passwordi` cREVGeneral revUniqueID 1130963102081  fromi` cREVTable currentviewchipp@chipp.com cREVGeneral revUniqueID 1130964092071   senderNamei` cREVTable currentview cREVGeneral revUniqueID 1130967838442  To)`0 cREVGeneral revUniqueID 1130963110562  `@s.  CC)`H0 cREVGeneral revUniqueID 1130967967578   `@sI. bcc)`z0 cREVGeneral revUniqueID 1130967972137  `@s{.  replytoemaili` cREVTable currentviewtest222 cREVGeneral revUniqueID 1130968748575  subjecti` cREVGeneral revUniqueID 1130963158515   messageText)` h cREVGeneral revUniqueID 1130963165344  `@s f altLog)`> cREVGeneral revUniqueID 1130963203487  `@s<Use Authentication`E cREVGeneral revUniqueID 1131141738559 togglePaletteModeA*}on mouseUp if the mode of this stack is 1 then palette this stack else toplevel this stack end if end mouseUp @ cREVGeneralscriptChecksum 1St78x bookmarks revUniqueID 1131143106362 handlerListmouseUpscriptSelection char 11 to 10 prevHandlermouseUp tempScriptscript

on mouseUp

if the mode of this stack is 1 then

palette this stack

else

toplevel this stack

end if

end mouseUp

vers on mouseUp if the shiftKey is down then ask "New Version:" with me if it is empty then exit mouseUp put it into me set the altVers of img "altPlug.png" to it end if end mouseUp ($ cREVGeneralscriptChecksumKA2|S#ֺD٨m` bookmarks revUniqueID 1131143142757 handlerListmouseUp prevHandlermouseUp tempScriptscriptSelectionchar 176 to 175scriptl

on mouseUp

if the shiftKey is down then

ask "New Version:" with me

if it is empty then exit mouseUp

put it into me

set the altVers of img "altPlug.png" to it

end if

end mouseUp

v0.10 altPlug.png D altOpenVisibletruealtVersv0.10altPlugFileNamealtEmailHarness.rev altOnClickMedoIt altUpdateURL;http://www.gadgetplugins.com/altplugins/altEmailHarness.txtPlugin BuilderʉPNG  IHDR szzgAMA aIDATXϫE?ճLsлP,J*o|~O*Q"xyؾо̀X Al3(nms`^|K} fP~rc퓍IO9I!=&"Fu1dx(fpvQDr޿.;AԲ,۔4kƗ2feJ72663Q}a8w^`_xd p\#qu`u`mĭ0OMKQVPܭb~ aú<-.dMcsܴѻ0_<߫A{Rz.O^_AP$Uu4&b3JQY2зx,7 poj'ե_`T9EœP^<) OU,UL0033ؚ^Pd\yG|wym $+ !C,f8!diʌ;*Ea^)ʆ*E U%Cvi~W 1Ҷi!>kc:2t4 i4 h V>p3MU@㇆KIhM4MhcRόa]*C Ģ21@T1 :C0B 6 $Y@Ƌ)xAm02B-4Q7P74FS&Pׁn 4),mo@VIENDB` cREVGeneralscriptChecksumُ B~ revUniqueID 1131143142769 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script

 libSmtp253<:## FILE INFORMATION # File Name .....: libSmtp # Version .......: v2.5.3 # Build Date ....: 2005-10-17 ## AUTHOUR INFORMATION # Written By ....: Shao Sean # Email .........: support@shaosean.tk # Website .......: www.shaosean.tk ## NOTE TO DEVELOPERS # Any of the handlers/functions that start with a "z" are considered to be private # and are called from within the public handlers. ## PUBLIC DOMAIN DISCLAIMER # This software was developed by Shao Sean and is available for use by the public # without need of a license. ## DISCLAIMER # THE SOFTWARE AND RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT WARRANTY OR INDEMNITY OF ANY KIND # INCLUDING ANY WARRANTIES OF USE, PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR # PURPOSE OR FOR ANY PURPOSE WHATSOEVER. # # USER BEARS ALL RISK RELATING TO USE, QUALITY AND PERFORMANCE OF THE SOFTWARE. ## HANDLER LISTING # # smtpOpen(serverAddress, serverPort, authType, authUser, authPassword [, callbackMessage]) # smtpSend(mailFrom, {recipientList}, emailMessage [, callbackMessage]) # smtpClose( [callbackMessage] ) # smtpGetServerGreeting() # smtpGetInvalidRecipients() # smtpGetLastError() # smtpGetTranscript() --- contants used for socket timeouts constant kTwoMinutes = 120000 constant kThreeMinutes = 180000 constant kFiveMinutes = 300000 constant kTenMinutes = 600000 --- constants used for error messages (these probably should be moved into a customPropertySet for different language support) constant kErrSmtpAddressIsEmpty = "err: SMTP address is empty." constant kErrNoSupportedAuthMethod = "err: Server does not support authentication methods we support." constant kErrAuthFailed = "err: Authentication failed." #constant kErrAuthMethodNotSupported = "err: Authentication method tried not supported by SMTP server." constant kErrAuthInvalidUser = "err: Authentication username is not valid." constant kErrAuthInvalidPass = "err: Authentication password is not valid." constant kErrMailFromIsEmpty = "err: 'MAIL FROM' is empty." constant kErrRcptToListIsEmtpy = "err: 'RCPT TO' is empty." constant kErrMessageIsEmpty = "err: Message is empty (no headers and no bodies means no message to send)." constant kErrorSocketClosed = "err: The remote server has closed the connection." constant kErrSocketTimedOut = "err: The connection to the remote server has timed out." constant k421 = "(421) Service not available, closing connection." constant k450 = "(450) Requested action not completed, mailbox unavailable." constant k451 = "(451) Requested action aborted, error processing request." constant k452 = "(452) Requested action not completed, insufficient system storage." constant k500 = "(500) Command not recognized." constant k501 = "(501) Command parameter syntax error." constant k502 = "(502) Command not implemented." constant k503 = "(503) Command out of sequence." constant k504 = "(504) Command parameter not implemented." constant k535 = "(535) Authentication method failed." constant k550 = "(550) Requested action not completed, mailbox unavailable." constant k551 = "(551) User not local." constant k552 = "(552) Requested action aborted, exceeded storage allocation." constant k553 = "(553) Requested action not completed, mailbox name is not valid." constant k554 = "(554) Transaction failed." local sSmtpSocketPointer -- socket pointer, used for communication to the server local sSmtpSocketContinue -- boolean, allows the script to continue local sSmtpSocketSuccess -- boolean, the last command was successfully or not local sSmtpError -- string, human readable error message (based on error code returned from the server) local sSmtpSocketReply -- string, storage for the incoming server reply local sSmtpServerGreeting -- string, the greeting returned from the server upon connection local sInvalidRecipients -- string, return-delimited list of email addresses that were deemed invalid local sSmtpTranscript -- log of communication with the server ##### PUBLIC HANDLERS ##### function smtpGetLastError -- returns the last error the library encountered return sSmtpError end smtpGetLastError function smtpGetInvalidRecipients -- returns a list (LF delimited) of all the recipients who were refused by the server return sInvalidRecipients end smtpGetInvalidRecipients function smtpGetServerGreeting -- returns the initial connection message from the server return sSmtpServerGreeting end smtpGetServerGreeting function smtpGetTranscript -- returns a log of the smtp session (basically a log dump) return sSmtpTranscript end smtpGetTranscript function smtpOpen pServer, pPort, pAuthType, pAuthUser, pAuthPass local tCallbackMessage local tCallbackTarget --- check parameters if (pServer is empty) then put kErrSmtpAddressIsEmpty into sSmtpError return FALSE end if if (pPort is a number) AND (pPort > 1) then put pServer & ":" & pPort & "|libSmtp" into sSmtpSocketPointer else put pServer & ":25|libSmtp" into sSmtpSocketPointer if (paramCount() = 6) AND (param(6) is not empty) then put param(6) into tCallbackMessage put the long id of the target into tCallbackTarget end if --- cleanup zSmtpResetVariables "all" zSmtpLog "--- Open socket to" && sSmtpSocketPointer open socket to sSmtpSocketPointer with message "zSmtpRead" wait until sSmtpSocketContinue is TRUE with messages if (sSmtpSocketSuccess is FALSE) then return FALSE --- store the server's greeting, sometimes it has important information in it put sSmtpSocketReply into sSmtpServerGreeting --- say hello if (zSmtpWrite("EHLO" && hostAddress(sSmtpSocketPointer), kFiveMinutes) is TRUE) then -- server supports enhanced hello if (pAuthType is not empty) then -- try using authentication if (zSmtpAuthentication(pAuthType, pAuthUser, pAuthPass, sSmtpSocketReply) is FALSE) then -- error doing authentication return FALSE end if end if else -- server does not support enhanced hello, so let's use standard hello if (zSmtpWrite("HELO" && hostAddress(sSmtpSocketPointer), kFiveMinutes) is FALSE) then -- server doesn't like us close socket sSmtpSocketPointer return FALSE end if end if --- callback message if (tCallbackMessage is not empty) AND (tCallbackTarget is not empty) then send tCallbackMessage to tCallbackTarget in 0 seconds end if return TRUE end smtpOpen function smtpSend pMailFrom, pRcptToList, pMessage local tCallbackMessage local tCallbackTarget local tRcptToLine local tMessageLine local tMessageCharsSent --- check parameters if (pMailFrom is empty) then put kErrMailFromIsEmpty into sSmtpError return FALSE end if if (pRcptToList is empty) then put kErrRcptToListIsEmtpy into sSmtpError return FALSE end if if (pMessage is empty) then put kErrMessageIsEmpty into sSmtpError return FALSE end if if (paramCount() = 4) AND (param(4) is not empty) then put param(4) into tCallbackMessage put the long id of the target into tCallbackTarget end if put EMPTY into sInvalidRecipients --- send the message if (zSmtpWrite("MAIL FROM:<" & pMailFrom & ">", kFiveMinutes) is FALSE) then return FALSE repeat for each line tRcptToLine in pRcptToList if (tRcptToLine is empty) then next repeat if (zSmtpWrite("RCPT TO:<" & tRcptToLine & ">", kFiveMinutes) is FALSE) then put tRcptToLine & LF after sInvalidRecipients end if end repeat if (zSmtpWrite("DATA", kTwoMinutes) is FALSE) then return FALSE put 0 into tMessageCharsSent repeat for each line tMessageLine in pMessage if (tMessageLine = ".") then add 1 to tMessageCharsSent if (zSmtpWrite("..", kThreeMinutes, FALSE) is FALSE) then return FALSE end if else add (the number of chars of tMessageLine) to tMessageCharsSent if (zSmtpWrite(tMessageLine, kThreeMinutes, FALSE) is FALSE) then return FALSE end if end if end repeat if (zSmtpWrite(".", kTenMinutes) is FALSE) then return FALSE zSmtpLog "--- " && tMessageCharsSent && "chars sent." --- callback message if (tCallbackMessage is not empty) AND (tCallbackTarget is not empty) then send tCallbackMessage to tCallbackTarget in 0 seconds end if return TRUE end smtpSend function smtpClose local tCallbackMessage local tCallbackTarget --- check parameters if (paramCount() = 1) AND (param(1) is not empty) then put param(1) into tCallbackMessage put the long id of the target into tCallbackTarget end if --- say goodbye get zSmtpWrite("QUIT", kFiveMinutes) --- cleanup zSmtpResetVariables if (sSmtpSocketPointer is among the lines of the openSockets) then close socket sSmtpSocketPointer end if --- callback message if (tCallbackMessage is not empty) AND (tCallbackTarget is not empty) then send tCallbackMessage to tCallbackTarget in 0 seconds end if return TRUE end smtpClose ##### PRIVATE HANDLERS BELOW ##### on zSmtpResetVariables put FALSE into sSmtpSocketContinue put FALSE into sSmtpSocketSuccess put EMPTY into sSmtpSocketReply put EMPTY into sSmtpError if (paramCount() = 1) then put EMPTY into sSmtpServerGreeting put EMPTY into sInvalidRecipients put EMPTY into sSmtpTranscript end if end zSmtpResetVariables on zSmtpLog put param(1) & LF after sSmtpTranscript end zSmtpLog function zSmtpAuthentication pAuthType, pAuthUser, pAuthPass, pServerReply local tAuthMethod --- check parameters if (pAuthType is "AUTO") then if (pServerReply contains "PLAIN") then put "PLAIN" into tAuthMethod else if (pServerReply contains "LOGIN") then put "LOGIN" into tAuthMethod else return EMPTY else if (pAuthType is not among the items of "PLAIN,LOGIN") then put kErrNoSupportedAuthMethod into sSmtpError return FALSE else put pAuthType into tAuthMethod --- do the authentication switch (tAuthMethod) case "PLAIN" if (zSmtpWrite("AUTH PLAIN", kFiveMinutes) is TRUE) then if (zSmtpWrite(base64encode(numToChar(0) & pAuthUser & numToChar(0) & pAuthPass), kFiveMinutes) is FALSE) then put kErrAuthFailed into sSmtpError return FALSE end if else if (zSmtpWrite("AUTH PLAIN" && base64encode(numToChar(0) & pAuthUser & numToChar(0) & pAuthPass & numToChar(0)), kFiveMinutes) is FALSE) then put kErrAuthFailed into sSmtpError return FALSE end if end if break case "LOGIN" if (zSmtpWrite("AUTH LOGIN", kFiveMinutes) is FALSE) then put kErrAuthFailed into sSmtpError return FALSE end if if (zSmtpWrite(base64encode(pAuthUser), kFiveMinutes) is FALSE) then put kErrAuthInvalidUser into sSmtpError return FALSE end if if (zSmtpWrite(base64encode(pAuthPass), kFiveMinutes) is FALSE) then put kErrAuthInvalidPass into sSmtpError return FALSE end if break end switch return TRUE end zSmtpAuthentication on zSmtpRead pSocketPointer read from socket pSocketPointer until CRLF with message "zSmtpGotData" end zSmtpRead function zSmtpWrite pData, pTimeoutInterval zSmtpResetVariables zSmtpLog ">>> " && pData set the socketTimeoutInterval to pTimeoutInterval if (paramCount() = 2) then write pData & CRLF to socket sSmtpSocketPointer with message "zSmtpRead" else write pData & CRLF to socket sSmtpSocketPointer with message "zSmtpWriteData" wait until sSmtpSocketContinue is TRUE with messages return sSmtpSocketSuccess end zSmtpWrite on zSmtpWriteData put TRUE into sSmtpSocketSuccess put TRUE into sSmtpSocketContinue end zSmtpWriteData on zSmtpGotData pSocketPointer, pData zSmtpLog "<<< " && pData put pData after sSmtpSocketReply if (char 4 of pData is "-") then -- multi-line reply read from socket pSocketPointer until CRLF with message "zSmtpGotData" else -- single-line reply or end of multi-line reply #zSmtpLog "<<<" && (char 1 to -2 of sSmtpSocketReply) switch (char 1 to 3 of sSmtpSocketReply) case "211" -- [rfc 2821] system status, or system help reply case "214" -- [rfc 2821] help message case "220" -- [rfc 2821] service ready case "221" -- [rfc 2821] service closing transmission channel case "235" -- [smtp authentication] password successful case "250" -- [rfc 2821] requested mail action okay, completed case "251" -- [rfc 2821] user not local; will forward to case "252" -- [rfc 2821] cannot VRFY user, but will accept message and attempt delivery case "334" -- [smtp authentication] username successful case "354" -- [rfc 2821] start mail input; end with . put TRUE into sSmtpSocketSuccess break case "421" -- [RFC2821] service not available, closing transmission channel case "450" -- [RFC2821] requested mail action not taken; mailbox unavailable (e.g., mailbox busy) case "451" -- [RFC2821] requested action aborted: local error in processing case "452" -- [RFC2821] requested action not taken: insufficient system storage case "500" -- [RFC2821] syntax error, command unrecognized case "501" -- [RFC2821] syntax error in parameters or arguments, also used by smtp authentication (bad username) case "502" -- [RFC2821] command not implemented, also used by smtp authentication (authentication method not recognized) case "503" -- [RFC2821] bad sequence of commands case "504" -- [RFC2821] command parameter not implemented, also used by smtp authentication (authentication method not recognized) case "535" -- used by authenticated smtp (authentication failed) case "550" -- [RFC2821] requested action not taken: mailbox unavailable, also used by smtp authentication (username or password incorrect) case "551" -- [RFC2821] user not local; please try case "552" -- [RFC2821] requested mail action aborted: exceeded storage allocation case "553" -- [RFC2821] requested action not taked: mailbox name not allowed case "554" -- [RFC2821] transaction failed do ("put k" & char 1 to 3 of sSmtpSocketReply && "into sSmtpError") break default put "Unknown error." into sSmtpError break end switch put TRUE into sSmtpSocketContinue end if end zSmtpGotData on socketError pSocketPointer, pErrorMessage if (pSocketPointer is among the lines of the openSockets) then close socket pSocketPointer put pErrorMessage into sSmtpError put FALSE into sSmtpSocketSuccess put TRUE into sSmtpSocketContinue end socketError on socketTimeout pSocketPointer if (pSocketPointer is among the lines of the openSockets) then close socket pSocketPointer put kErrSocketTimedOut into sSmtpError put FALSE into sSmtpSocketSuccess put TRUE into sSmtpSocketContinue end socketTimeout on socketClose pSocketPointer if (pSocketPointer is among the lines of the openSockets) then close socket pSocketPointer put kErrorSocketClosed into sSmtpError put FALSE into sSmtpSocketSuccess put TRUE into sSmtpSocketContinue end socketClose dlibSmtp 2.5.3 Ums sans serif ULucida Grande UCourier UCourier ULucida Grande WLucida Grande WCourier WCourier WLucida Grande UCourier ULucida Grande cREVGeneral @d Field)@@ h cREVGeneral revUniqueID 1126568933773  {libSMTP is a library for Runtime Revolution 2.0.3 or greater that allows you to send emails from within your own programs. You need to put the library in your message path either by putting it in the front or back scripts or by using it as a library: start using stack "libSmtp253"  SOnce the library is in use, you will need to open a connection to the SMTP server: F smtpOpen( address, port, authType, authUser, authPass [, callback] ) 7 7 CNow that the connection is open, you can send your email messages: ? smtpSend( mailFrom, {rcptToList}, emailMessage [, callback] ) 3 3 HOnce you have finished sending all your messages, close the connection:  smtpClose( [callback] )  There are a few other commands that you can use to help track down any errors or problems that you may be having using the library in your program: C smtpGetServerGreeting() - what the server said when you connected 5 5 = smtpGetLastError() - contains a string about the last error 7 7 ? smtpGetTranscript() - returns a log of the whole smtp session 7 7 When sending emails to many recipients, some email addresses may be invalid in which case you can get the list of the invalid addresses:  smtpGetInvalidRecipients()  $----------------------------------- EsmtpOpen( address, port, authType, authUser, authPass [, callback] ) D address  ? address of the smtp server (smtp.example.org OR 123.45.67.89) port  6 is the port the smtp server listens on (default= 25) $ pass empty to use the default port authType   authentication method to use ? "AUTO" to have the library automatically detect (recommended) "PLAIN" "LOGIN" % pass empty for unauthenticated smtp authUse  % username to use with authentication authPass  # password associated with the user callback  I optional handler to be called when connected successfully to the server ,Will return FALSE on error, TRUE on success      Examples: 41. get smtpOpen("smtp.example.org", "", "", "", "")  0 m opens a connection to "smtp.example.org" on the default port with no authentication and no callback message e e N2. if (smtpOpen("smtp.example.org", "", "AUTO", "user", "pass") is TRUE) then  J opens a connection to "smtp.example.org" on the default port letting the library detect authenticationt to use (AUTO) with the username "user" and password "pass" Y YJ G3. get smtpOpen("smtp.example.org", "26", "", "", "", "smtpConnected")  C p opens a connection to "smtp.example.org" on custom port 26 with no authentication, but with a callback message _ _ $----------------------------------- >smtpSend( mailFrom, {rcptToList}, emailMessage [, callback] )       " . 2 : mailFrom  / email address of the person sending the email rcptToList  A LINEFEED-delimited list of email addresses to send the email to emailMessage  , a properly formatted message to be emailed callback  I optional handler to be called when the email has successfully been sent ,Will return FALSE on error, TRUE on success      After being called successfully, you may want to call smtpGetInvalidRecipients() to see if there were any recipients who did not get the email. 6 6 P? Examples: E1. get smtpSend("shaosean@example.org", "bob@example.org", tMessage)  A k send the email from "shaosean@example.org" to "bob@example.org" with the message in the variable tMessage Y Y $----------------------------------- smtpClose( [callback] )     callback  O optional handler to be called when the smtp connection is closed successfully ,Will return FALSE on error, TRUE on success      $----------------------------------- smtpGetServerGreeting()   Sometimes an SMTP server will display important information upon connection to the server, so this command will allow you access to the information. Some servers display legal information and/or terms of conduct, so you may want to display this to your end user. d d $----------------------------------- smtpGetInvalidRecipients()  Not all email addresses are correct - outdated, typo, etc - so after sending the email message check to see if this is empty or not. If not, there are probably some people who didn't get the email message. This is a LINEFEED-delimited list. f f $----------------------------------- smtpGetLastError()  If you get a FALSE return from one of the commands (open, send, close) you can check to see what the error was, and optionally display it to the end user. This is a human-readable string. b bZ $----------------------------------- smtpGetTranscript()  Sometimes the last error message isn't enough information or it might even be wrong, so you can use this to get a complete log of the SMTP session to see where things went wrong. e eN $----------------------------------- AThanks go out to a lot of people especially the following geeks: aRobert Brenstein - smtp transcript code and feature; bug fix for the "invalid recipient" feature  O BMark Wieder - supplying a server to test smtp authentication with   6 Klaus Major - you know why ;-)    #Matt Denton - you know why too ^_^    CKurt Kaufman - supplying a server to test smtp authentication with   6 4Ian Summerfield - error handling for socket opening  # jmalte, bvg, Mark and the rest of the guys at the ChatRev server for getting me to even write the docs =P~        Y Mike (mmessieh)  David Kwinter  Mark Powell  Ian Gordon  Jerry Daniels  Bernard Devlin  `@f