Forum OpenACS Development: Re: html in emails.
This evening I have been trying to get my openacs-4-6 to send email password reminders as html and was meeting with mysterious problems.
Having dissected the file line by line it became obvious that the problem was an unwanted newline between the subject line and the "Content-Type:" declaration.
So with tremendous courage I embarked on a search of ns_sendmail.tcl - emboldened by Tilman's patches that I applied yesterday! - And guess what I found.......
There is an extra '\n' included before the body which confuses MS Outlook.
So if anyone wants to send html emails from the ACS and doesn't mind hacking ns_sendmail..................
Modified version posted below - includes Tilman's patches.
Mime header and html body need to go into email-password-2.tcl
Regards
Richard
Having dissected the file line by line it became obvious that the problem was an unwanted newline between the subject line and the "Content-Type:" declaration.
So with tremendous courage I embarked on a search of ns_sendmail.tcl - emboldened by Tilman's patches that I applied yesterday! - And guess what I found.......
There is an extra '\n' included before the body which confuses MS Outlook.
So if anyone wants to send html emails from the ACS and doesn't mind hacking ns_sendmail..................
Modified version posted below - includes Tilman's patches.
Mime header and html body need to go into email-password-2.tcl
proc _ns_sendmail {smtp smtpport timeout tolist bcclist \ from subject body extraheaders} { ## Put the tolist in the headers set rfcto [join $tolist ", "] ## Build headers set msg "To: $rfcto\nFrom: $from\nSubject: $subject\nDate: [ns_httptime [ns_time]]" ## Insert extra headers, if any (not for BCC) if ![string match "" $extraheaders] { set size [ns_set size $extraheaders] for {set i 0} {$i < $size} {incr i} { append msg "\n[ns_set key $extraheaders $i]: [ns_set value $extraheaders $i]" } } ## Blank line between headers and body append msg "$body\n" ## Terminate body with a solitary period foreach line [split $msg "\n"] { if [string match . $line] { append data . } append data $line append data "\r\n" } append data . ## Open the connection set sock [ns_sockopen $smtp $smtpport] set rfp [lindex $sock 0] set wfp [lindex $sock 1] ## Strip "from" email address regexp {.*<(.*)>} $from ig from ## Perform the SMTP conversation if { [catch { _ns_smtp_recv $rfp 220 $timeout _ns_smtp_send $wfp "HELO [ns_info hostname]" $timeout _ns_smtp_recv $rfp 250 $timeout _ns_smtp_send $wfp "MAIL FROM:<$from>" $timeout _ns_smtp_recv $rfp 250 $timeout ## Loop through To list via multiple RCPT TO lines foreach toto $tolist { _ns_smtp_send $wfp "RCPT TO:<$toto>" $timeout _ns_smtp_recv $rfp 250 $timeout } ## Loop through BCC list via multiple RCPT TO lines ## A BCC should never, ever appear in the header. Ever. Not even. foreach bccto $bcclist { _ns_smtp_send $wfp "RCPT TO:<$bccto>" $timeout _ns_smtp_recv $rfp 250 $timeout } ## Loop through To and BCC list via multiple RCPT TO lines ## A BCC should never, ever appear in the header. Ever. Not even. foreach toto [concat $tolist $bcclist] { # Transform "Fritz #fritz@foo.com>" into "fritz@foo.com". regexp {.*<(.*)>} $toto ig toto _ns_smtp_send $wfp "RCPT TO:<$toto>" $timeout _ns_smtp_recv $rfp 250 $timeout } _ns_smtp_send $wfp DATA $timeout _ns_smtp_recv $rfp 354 $timeout _ns_smtp_send $wfp $data $timeout _ns_smtp_recv $rfp 250 $timeout _ns_smtp_send $wfp QUIT $timeout _ns_smtp_recv $rfp 221 $timeout } errMsg ] } { ## Error, close and report close $rfp close $wfp return -code error $errMsg } ## Close the connection close $rfp close $wfp }
Regards
Richard
The simple modification above broke the basic default emails for confirming registrations to I added this simple check to ns_sendmail and it seems to be working fine. I have only just started working with tcl so my repertoire of instructions is not good. Perhaps the tcl experts could let me know if this is an efficient way to construct it.
I was not sure if I had to explicitly tell the interpreter that newline contains null so I thought I had better for safety's sake.
Regards
Richard
if {[string index $body 0] != "\n"} { set newline "\n" } else { set newline "" } append msg $newline "$body\n"
I was not sure if I had to explicitly tell the interpreter that newline contains null so I thought I had better for safety's sake.
Regards
Richard