libSMTP

Bringing the internet highway into your project? Building FTP, HTTP, email, chat or other client solutions?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Emily-Elizabeth
Posts: 101
Joined: Mon Jan 03, 2022 7:10 pm

libSMTP

Post by Emily-Elizabeth » Sun Feb 13, 2022 6:11 pm

This is an event-driven SMTP library. This is just the first rough draft, no error handling, etc, but would like to get feedback. There are three public commands that you call SMTPConnect, SMTPSend, and SMTPDisconnect.
SMTPConnect has three callbacks SMTPConnected, SMTPRequestAuthenticationMethod(), and SMTPLoggedIn.
SMTPSend has four callbacks SMTPRequestSender(), SMTPRequestRecipient(), SMTPRequestDataLine() and SMTPMessageSent
SMTPDisconnect has one callback SMTPDisconnected

So a typical workflow would be something like:
SMTPConnect
- SMTPConnected
- SMTPRequestAuthenticationMethod()
- SMTPLoggedIn

In the SMTPLoggedIn callback you would call:
SMTPSend
- SMTPRequestSender()
- SMTPRequestRecipient()
- SMTPRequestDataLine()
- SMTPMessageSent [you can call SMTPSend again from here to send another message, or SMTPDisconnect]

SMTPDisconnect
- SMTPDisconnected

Code: Select all

--- public commands
// SMTPConnect
// SMTPSend
// SMTPDisconnect


--- callbacks
// SMTPConnected
// SMTPRequestAuthenticationMethod()
// SMTPLoggedIn
// SMTPRequestSender()
// SMTPRequestRecipient()
// SMTPRequestDataLine()
// SMTPMessageSent
// SMTPDisconnected


--- contants used for socket timeouts
constant kTwoMinutes   = 120000
constant kThreeMinutes = 180000
constant kFiveMinutes  = 300000
constant kTenMinutes   = 600000


local sCallback
local sSMTPReply
local sCurrentCommand


on SMTPConnect serverAddress, serverPort, useSSL, callback
   local sender
   put serverAddress & ":" & serverPort & "|libSMTP" into sender
   put EMPTY into sSMTPReply[sender]
   put EMPTY into sCurrentCommand[sender]
   put callback into sCallback[sender]
   if (useSSL) then
      open secure socket to sender with message "libSMTPRead"
   else
      open socket to sender with message "libSMTPRead"
   end if
end SMTPConnect


on SMTPDisconnect sender
   libSMTPWrite sender, "QUIT", kFiveMinutes   
end SMTPDisconnect


on SMTPSend sender
   dispatch function "SMTPRequestSender" to sCallback[sender] with sender
   libSMTPWrite sender, "MAIL FROM:<" & the result & ">", kFiveMinutes   
end SMTPSend


on libSMTPRead sender
   read from socket sender until CRLF with message "libSMTPGotData"
end libSMTPRead


on libSMTPGotData sender, data
   put data after sSMTPReply[sender]
   if (char 4 of data = "-") then  // multi-line reply
      read from socket sender until CRLF with message "libSMTPGotData"
   else
      switch (char 1 to 3 of sSMTPReply[sender])
         case 220  // <domain> service ready
            dispatch "SMTPConnected" to sCallback[sender] with sender, sSMTPReply[sender]
            libSMTPWrite sender, "EHLO" && hostAddress(sender), kFiveMinutes
            break
         case 221  //
            close socket sender
            dispatch "SMTPDisconnected" to sCallback[sender] with sender
            break
         case 235  // password successful
            dispatch "SMTPLoggedIn" to sCallback[sender] with sender
            break
         case 250  // requested mail action okay, completed
            if (sCurrentCommand[sender] = "EHLO") then
               local authMethods
               put libSMTPFindAuthMethods(sSMTPReply[sender]) into authMethods
               dispatch function "SMTPRequestAuthenticationMethod" to sCallback[sender] with sender, authMethods
               libSMTPWrite sender, "AUTH" && the result, kFiveMinutes
            else if (sCurrentCommand[sender] = "MAIL") then
               libSMTPGetNextRecipient sender
            else if (sCurrentCommand[sender] = "RCPT") then
               libSMTPGetNextRecipient sender
            else if (sCurrentCommand[sender] = ".") then
               dispatch "SMTPMessageSent" to sCallback[sender] with sender
            end if
            break
         case 251
            if (sCurrentCommand[sender] = "RCPT") then
               dispatch "SMTPInvalidRecipient" to sCallback[sender] with sender
               libSMTPGetNextRecipient sender
            end if
            break
         case 354  // start mail input; end with <CRLF>.<CRLF>
            if (sCurrentCommand[sender] = "DATA") then
               libSMTPGetNextDataLine sender
            end if
            break
         default
            put sSMTPReply[sender]
            close socket (line 1 of the openSockets)
      end switch
   end if
end libSMTPGotData


on libSMTPWrite sender, data, timeout
   put EMPTY into sSMTPReply[sender]
   put word 1 of data into sCurrentCommand[sender]
   set the socketTimeoutInterval to timeout
   write data & CRLF to socket sender with message "libSMTPRead"
end libSMTPWrite


on libSMTPWriteDataLine sender, data, timeout
   set the socketTimeoutInterval to timeout
   if (data = ".") then
      write ".." & CRLF to socket sender with message "libSMTPGetNextDataLine"
   else
      write data & CRLF to socket sender with message "libSMTPGetNextDataLine"
   end if
end libSMTPWriteDataLine


on libSMTPGetNextDataLine sender
   dispatch function "SMTPRequestDataLine" to sCallback[sender] with sender
   if (the result is FALSE) then
      libSMTPWrite sender, ".", kTenMinutes
   else
      libSMTPWriteDataLine sender, the result, kThreeMinutes
   end if
end libSMTPGetNextDataLine


on libSMTPGetNextRecipient sender
   dispatch function "SMTPRequestRecipient" to sCallback[sender] with sender
   if (the result is FALSE) then
      libSMTPWrite sender, "DATA", kTwoMinutes
   else
      libSMTPWrite sender, "RCPT TO:<" & the result & ">", kFiveMinutes
   end if
end libSMTPGetNextRecipient
   
   
   function libSMTPFindAuthMethods data
   local results
   repeat for each line tLine in data
      if (word 1 of tLine = "250-AUTH") then
         put word 2 to -1 of tLine into results
      else if (word 2 of tLine = "AUTH") then
         put word 3 to -1 of tLine into results
      end if
   end repeat
   return results
end libSMTPFindAuthMethods

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: libSMTP

Post by mwieder » Sat Feb 26, 2022 2:36 am

Nice. Looks like a good start.
I'm surprised "callback" isn't a reserved word, but there you go.

cmhjon
Posts: 175
Joined: Tue Aug 04, 2015 11:55 am

Re: libSMTP

Post by cmhjon » Fri Feb 17, 2023 7:24 pm

Is there a way to pass HMTL commands such as bolding certain words in the email that is generated and sent?

Best regards,
Jon

Emily-Elizabeth
Posts: 101
Joined: Mon Jan 03, 2022 7:10 pm

Re: libSMTP

Post by Emily-Elizabeth » Sat Feb 18, 2023 5:19 am

That would be done in your MIME message that you'd create before sending it through SMTP.

cmhjon
Posts: 175
Joined: Tue Aug 04, 2015 11:55 am

Re: libSMTP

Post by cmhjon » Sat Feb 18, 2023 1:13 pm

Hi Emily-Elizabeth,

Thank you for the reply. How does one create a MIME message in LC?

Best regards,
Jon :-)

Emily-Elizabeth
Posts: 101
Joined: Mon Jan 03, 2022 7:10 pm

Re: libSMTP

Post by Emily-Elizabeth » Sat Feb 18, 2023 4:53 pm

MIME is just plain text, but needs to be in a specific format. For more information take a look at this wikipedia article https://en.wikipedia.org/wiki/MIME and if you're really bored, the six RFCs for MIME are linked at the beginning of the article.

cmhjon
Posts: 175
Joined: Tue Aug 04, 2015 11:55 am

Re: libSMTP

Post by cmhjon » Mon Feb 20, 2023 2:11 pm

Hi Emily-Elizabeth,

I tried digesting that link and what little sense I could make of it, I tried putting "MIME-Version: 1.0" into he first line of the body of the email to be sent but all I get is an email with that text just added as part of the body. Any subsequent HTML codes don't do anything.

Do you have any LC code examples on what I would need to do to get this to work?

Best regards,
Jon

Emily-Elizabeth
Posts: 101
Joined: Mon Jan 03, 2022 7:10 pm

Re: libSMTP

Post by Emily-Elizabeth » Mon Feb 20, 2023 5:29 pm

I would have to look in to it, but currently working on a project, so it'd have to wait.

cmhjon
Posts: 175
Joined: Tue Aug 04, 2015 11:55 am

Re: libSMTP

Post by cmhjon » Mon Feb 20, 2023 7:05 pm

Hi Emily-Elizabeth,

I would be most grateful for any help you could provide as your time allows.

Best regards,
Jon :-)

Post Reply

Return to “Internet”