User Tools

Site Tools


sending_20an_20html_20email_20with_20optional_20attachments

Sending an HTML email with optional attachments

by Richard Russell, April 2014, corrected August 2015

In the article Sending an email with attachments the procedure PROCsendmailattach() automatically sends an email using the SOCKLIB library. Listed below is a procedure which performs the same function except that you can send the body of the email as HTML instead of (or preferably as well as) plain text. The procedure might be called as follows:

        INSTALL @lib$+"SOCKLIB"
 
        SMTP$    = "smtp.gmail.com"
        From$    = "sender@somewhere"
        To$      = "recipient@elsewhere"
        Subject$ = "Test of sending attachments"
        ReplyTo$ = "reallyme@myaddress"
        Plain$   = "This is a test of sending an HTML email."
        HTML$    = "<html><head></head><body>" + \
        \          "This is a test of sending an <b><i>HTML</i></b> email." + \
        \          "</body></html>"
        Attach$ =  """C:\Program Files\BBC BASIC for Windows\readme.txt"""
 
        PROCsendmailhtmlattach(SMTP$,From$,To$,"","",Subject$,ReplyTo$,Plain$,HTML$,Attach$)

The calling program should first check that the attached file(s) actually exist, because if not PROCattach() will abort with an error and not terminate the SMTP transaction; this could leave the server 'in limbo'. Note that if an attached file path contains spaces or punctuation characters you must enclose it in quotes.

You should not assume that the receiving email client can necessarily render HTML, therefore ideally you should always include a plain-text message body as well as an HTML message body.

Here is PROCsendmailhtmlattach(); like PROCsendmail() it cannot be used if authentication is required so in practice that probably means that your ISP's SMTP server must be used:

        DEF PROCsendmailhtmlattach(smtp$,from$,rcpt$,cc$,bcc$,subject$,replyto$,plain$,html$,attach$)
        LOCAL D%, S%, skt%, comma%, reply$, file$
        DIM D% LOCAL 31, S% LOCAL 15
 
        SYS "GetLocalTime", S%
        SYS "GetDateFormat", 0, 0, S%, "ddd, dd MMM yyyy ", D%, 18
        SYS "GetTimeFormat", 0, 0, S%, "HH:mm:ss +0000", D%+17, 15
        D%?31 = 13
 
        PROC_initsockets
        skt% = FN_tcpconnect(smtp$,"mail")
        IF skt% <= 0 skt% = FN_tcpconnect(smtp$,"25")
        IF skt% <= 0 ERROR 100, "Failed to connect to mail server"
        IF FN_readlinesocket(skt%, 1000, reply$)
        WHILE FN_readlinesocket(skt%, 10, reply$) > 0 : ENDWHILE
 
        PROCsend(skt%,"HELO "+FN_gethostname)
        PROCmail(skt%,"MAIL FROM: ",from$)
        IF rcpt$<>"" PROClist(skt%,rcpt$)
        IF cc$<>"" PROClist(skt%,cc$)
        IF bcc$<>"" PROClist(skt%,bcc$)
        PROCsend(skt%, "DATA")
 
        IF FN_writelinesocket(skt%, "Date: "+$D%)
        IF FN_writelinesocket(skt%, "From: "+from$)
        IF FN_writelinesocket(skt%, "To: "+rcpt$)
        IF cc$<>"" IF FN_writelinesocket(skt%, "Cc: "+cc$)
        IF subject$<>"" IF FN_writelinesocket(skt%, "Subject: "+subject$)
        IF replyto$<>"" IF FN_writelinesocket(skt%, "Reply-To: "+replyto$)
        IF FN_writelinesocket(skt%, "MIME-Version: 1.0")
        IF attach$<>"" THEN
          IF FN_writelinesocket(skt%, "Content-Type: multipart/mixed; boundary=""BB4Wsep""")
          IF FN_writelinesocket(skt%, "")
          IF FN_writelinesocket(skt%, "--BB4Wsep")
        ENDIF
        IF plain$<>"" IF html$<>"" THEN
          IF FN_writelinesocket(skt%, "Content-Type: multipart/alternative; boundary=""BB4Wsep2""")
          IF FN_writelinesocket(skt%, "")
          IF FN_writelinesocket(skt%, "--BB4Wsep2")
        ENDIF
        IF plain$<>"" THEN
          IF FN_writelinesocket(skt%, "Content-Type: text/plain")
          IF FN_writelinesocket(skt%, "Content-Transfer-Encoding: 7bit")
          IF FN_writelinesocket(skt%, "")
          IF FN_writelinesocket(skt%, plain$)
        ENDIF
        IF plain$<>"" IF html$<>"" THEN
          IF FN_writelinesocket(skt%, "--BB4Wsep2")
        ENDIF
        IF html$<>"" THEN
          IF FN_writelinesocket(skt%, "Content-Type: text/html")
          IF FN_writelinesocket(skt%, "Content-Transfer-Encoding: 7bit")
          IF FN_writelinesocket(skt%, "")
          IF FN_writelinesocket(skt%, html$)
        ENDIF
        IF plain$<>"" IF html$<>"" THEN
          IF FN_writelinesocket(skt%, "--BB4Wsep2--")
        ENDIF
        IF attach$<>"" THEN
          REPEAT
            WHILE ASCattach$=32 attach$ = MID$(attach$,2) : ENDWHILE
            IF ASCattach$=34 THEN
              file$ = EVAL(attach$)
              comma% = INSTR(attach$, ",", LENfile$)
            ELSE
              comma% = INSTR(attach$, ",")
              IF comma% file$ = LEFT$(attach$, comma%-1) ELSE file$ = attach$
            ENDIF
            PROCattach(skt%, file$)
            attach$ = MID$(attach$, comma%+1)
          UNTIL comma%=0
          IF FN_writelinesocket(skt%, "--BB4Wsep--")
        ENDIF
        IF FN_writelinesocket(skt%, ".")
 
        PROCsend(skt%,"QUIT")
 
        PROC_exitsockets
        ENDPROC
 
        DEF PROClist(skt%,list$)
        LOCAL comma%
        REPEAT
          WHILE ASClist$=32 list$=MID$(list$,2):ENDWHILE
          comma% = INSTR(list$,",")
          IF comma% THEN
            PROCmail(skt%,"RCPT TO: ",LEFT$(list$,comma%-1))
            list$ = MID$(list$,comma%+1)
          ELSE
            PROCmail(skt%,"RCPT TO: ",list$)
          ENDIF
        UNTIL comma% = 0
        ENDPROC
 
        DEF PROCmail(skt%,cmd$,mail$)
        LOCAL I%,J%
        I% = INSTR(mail$,"<")
        J% = INSTR(mail$,">",I%)
        IF I% IF J% THEN
          PROCsend(skt%, cmd$+MID$(mail$,I%,J%-I%+1))
        ELSE
          PROCsend(skt%, cmd$+"<"+mail$+">")
        ENDIF
        ENDPROC
 
        DEF PROCsend(skt%,cmd$)
        LOCAL reply$
        IF FN_writelinesocket(skt%,cmd$) < 0 THEN
          ERROR 100, "Send failed"
        ENDIF
        IF FN_readlinesocket(skt%, 200, reply$)
        WHILE FN_readlinesocket(skt%, 10, reply$) > 0 : ENDWHILE
        ENDPROC
 
        DEF PROCattach(skt%,file$)
        LOCAL D%, F%, I%, L%, N%, A$, B$
        B$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        F% = OPENIN(file$)
        IF F%=0 ERROR 100, "Failed to open attached file " + file$
        REPEAT
          D% = INSTR(file$, "\")
          IF D%=0 D% = INSTR(file$, "/")
          IF D% file$ = MID$(file$, D%+1)
        UNTIL D%=0
        IF FN_writelinesocket(skt%, "")
        IF FN_writelinesocket(skt%, "--BB4Wsep")
        IF FN_writelinesocket(skt%, "Content-Type: application/octet-stream")
        IF FN_writelinesocket(skt%, "Content-Disposition: attachment; filename="+file$)
        IF FN_writelinesocket(skt%, "Content-Transfer-Encoding: base64")
        IF FN_writelinesocket(skt%, "")
        L% = EXT#F%
        WHILE NOT EOF#F%
          N% = L% - PTR#F%
          D% = BGET#F% << 16 OR BGET#F% << 8 OR BGET#F%
          FOR I% = 1 TO 4 : A$ += MID$(B$,(D% >>> 18)+1,1) : D% = D% << 6 AND &FFFFFF : NEXT
          IF N%=1 RIGHT$(A$,2) = "==" ELSE IF N%=2 RIGHT$(A$) = "="
          IF LENA$>=72 IF FN_writelinesocket(skt%,A$)=0 A$ = ""
        ENDWHILE
        IF A$<>"" IF FN_writelinesocket(skt%, A$)
        CLOSE #F%
        ENDPROC
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
sending_20an_20html_20email_20with_20optional_20attachments.txt · Last modified: 2024/01/05 00:21 by 127.0.0.1