Spaces and carriage returns are being added to HTML email - vbscript

We have a server generated HTML file (myFile.html) that we embed in emails that get sent to our clients. We've been using this method for years with minimal issues. We use Windows Server 2012 with smtp server via II6. Recently the HTML is getting skewed in the email. When checking the source file, all looks well. Directly opening the HTML file for viewing in a browser works as you'd expect. Here is the code we're using to read the file into memory to prepare for emailing:
Set objFile = objFSO.OpenTextFile(strFilePath)
Do While objFile.AtEndOFStream <>True
line = objFile.ReadLine
If Instr(1, line, "<table") > 0 And strHeaderWritten = "N" Then
strHeaderWritten = "Y"
strFileContent=strFileContent & strHeader
End If
strFileContent=strFileContent & line
Loop
set objFile = Nothing
And then we add the content to the email and send:
strBody = strFileContent
Set objMail = CreateObject("CDO.Message")
Set objMail.Configuration = cdoConfig
objMail.From = strFrom
objMail.ReplyTo = strReplyTo
objMail.To = strTo
objMail.Subject = strSubject
objMail.HTMLBody = strBody
objMail.Fields("urn:schemas:httpmail:importance").Value = strImportance
objMail.Send
And here are examples of what it spits out in the email. There are no errors in the source:
Has anyone else had this happen to them?
Been toiling over this for hours looking for an explanation. Thank so much for reading!
I tried using the ADO Stream method for the email, but it is still coming out the same:
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 2 'adTypeText
objStream.CharSet = Application("CharacterSet")
objStream.Open
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS
line = objStream.ReadText(-2)
If Instr(1, line, "<table") > 0 And strHeaderWritten = "N" Then
strHeaderWritten = "Y"
strFileContent=strFileContent & strHeader
End If
If Instr(1, line, "< table") > 0 Then
strFileContent=strFileContent & "<h3>Broken HTML</h3>"
End If
strFileContent=strFileContent & line
Loop
objStream.Close
Set objStream = Nothing
As you can see, I also added a check for one of the persistent errors I'm seeing where there has been a space inserted between < and table. Checking the output this way did not capture the issue as in checking the text for the added space. So it must be happening after it's been written or I need to use a regex for the test. I'll try that next. I'm still seeing it in multiple email clients. Here's an example post test of ADO Stream:

This seems to be a common problem in CDO. I've found a few references online to the problem that spaces are randomly inserted into the HTMLbody.
One answer was to make the HTML body not one long string, because CDO will then insert random spaces, but to include whitespace yourself, so that CDO doesn't have to.
You could try adding VbCrLf or just plain spaces in the text you're sending.
A second suggestion made more sense to me; this can be an encoding problem. That also explains why adding your own whitespace could be a workaround.
Anyway; CDO allows for setting the encoding of the CDO.Message object before sending.
Try objMail.BodyPart.ContentTransferEncoding = "quoted-printable" to see if that solves it.

The issue is windows use of both line break and carrage return. I recommend loading the body of the text and replacing all instances of vbcrlf with just vblf and you will find you wont have the double spacing anymore.
e.g.
body = replace(body, vbcrlf, vblf)

Related

Errors Loading a Network File into a Stream in Classic ASP

I have a Classic ASP website that currently loads PDF files from a local directory and writes them to the Response. I create a stream and use LoadFromFile to pull the data. This has worked well for years, but we now want to delete the local files and pull from a network "\" drive, where all of our .NET sites pull the files from.
We do this in our .NET sites with no problem, but I cannot figure out how to open a network file from Classic ASP and load it into a stream. Nothing I have tried seems to recognize the "\server\directory\file" as a valid path.
So, just to be as clear as possible, this is what we do:
Pull a DocID from the QueryString.
Pass the DocID as a parameter to a SQL proc to pull the path to the file (In the current ASP page it pulls a local path, in .NET it pulls a network path. In our new ASP page it will now pull a network path).
We create a stream and load the file into it (this is the part that does not work in Classic ASP if the path is "\" instead of "D:\").
We change the Response.ContentType to "application/pdf".
We Response.BinaryWrite and Flush the Response.
The result is the page displays the PDF with no indication of the file name or location.
Adding partial code:
' sets the Cache-Control HTTP header to prevent proxy caching
Response.CacheControl = "Private"
Response.Expires = 0
Response.Buffer = True
Response.Clear
sDocID = Request.QueryString("DocID")
sSQL = "exec Get_DocData '" & sDocID & "'"
Set rsDoc = Server.CreateObject("ADODB.RecordSet")
rsDoc.Open sSQL, conn, 3, 1
'
' sPath = \\server\directory\filename.ext
' sFileName = filename.ext
'
sPath = rsDoc.Fields("DocPath").Value
sFileName = rDoc.Fields("DocDescription").Value
rsDoc.Close
Set rsDoc = Nothing
'sPath = Replace(sPath,"\\<svr>\<dir>","Z:")
If sPath <> "" Then
Set oStream = Server.CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1 ' adTypeBinary
oStream.LoadFromFile sPath
Response.ContentType = "application/pdf"
Response.AddHeader "Content-Disposition", "inline; filename=""" & sFileName & """"
Response.Charset = "UTF-8"
Do while not oStream.EOS
Response.BinaryWrite oStream.read(3670016)
Response.Flush
Loop
oStream.Close
Set oStream = Nothing
Else
Response.ContentType = "text/html"
'Response.Write("Invalid Document ID.")
End If
Response.End
Well, I knew I would feel stupid when I figured this out. As Lankymart commented, the LoadFromFile() does support UNC formatted paths, which lead me to suspect the issue was permission-based and not code-based.
Although our ApplicationPool was running under a general account which had permission to the network drives, the site was not. I simply brought up the site in IIS7, clicked on Basic Settings and used the "Connect as..." button to run the site under the same general account. That corrected my issue. Palm-slapping my head.

VBscript for sending mail using SMTP for .mht file attachment

I am using Gmail SMTP server to send out a .mht file. once send out, i am getting a lot of attachemnts and the .mht file were loading in the email body (from yahoo mail). Instead in outlook, i am getting it as a mail attachements.
VB script used for this :
Set objMessage = CreateObject("CDO.Message")
objMessage.HTMLBody = "<h1>Matrikon AM</h1>"
objMessage.Subject = "Test 1 -Blank"
objMessage.From = "xxxxx#gmail.com"
objMessage.To = "xxxxx#yahoo.com"
objMessage.TextBody = "From b.vbs"
objMessage.AddAttachment "c:\xxxxxxx\A1.mht"
objMessage.Send
I had some quick search online that "ContentMediaType" have to be define somewhere since the file extension is .mht.
Need help on this as i could not find a way to define the content-type.
My issue were exactly like mentioned in "https://stackoverflow.com/questions/15976836/modifying-the-content-type-of-an-attachment-in-a-cdo-message-object"
thanks.
This is from Help.
urn:schemas:mailheader: Namespace
The urn:schemas:mailheader: namespace defines fields that contain Internet standard message header values. Each field value (with a few exceptions) is stored as US-ASCII characters and is identical to the ASCII string found in the message stream. Non US-ASCII characters are encoded according to the RFC 1522 specification. No conversion is performed when the property value is set or updated. An application that sets the raw message header property must RFC 1522-encode non US-ASCII characters or the header value will be corrupted.
String constants are provided in the C++ header file cdosysstr.h and type library (cdoMailHeader module) for each field name. You can use these constants when referring to the fields to avoid typos and extra typing.
Example
The following example demonstrates use of the fields in the urn:schemas:mailheader: namespace. First, RFC 822 headers are added for a message. Next, body parts are added and the MIME headers set manually.
This code is for illustrative purposes only.
Copy Code
Dim iMsg as New CDO.Message
Dim Flds as ADODB.Fields
With iMsg
.To = """Someone"" <example#example.com>"
.From = """Me"" <example#example.com>"
.Subject = "Here is a sample message"
' Now set some custom mail headers using the raw fields collection
Set Flds = .Fields
With Flds
.Item("urn:schemas:mailheader:X-Mailer") = "Microsoft CDO for Windows 2000"
' I add a custom header here
.Item("urn:schemas:mailheader:Myheader")= "some value"
.Update
.Resync
End With ' Flds
End With ' iMsg
' Create a multipart/alternative (HTML) message below
Dim iBp as CDO.IBodyPart
Dim iBp2 as CDO.IBodyPart
Set iBp = iMsg ' get IBodyPart on Message object
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-type") = "multipart/alternative"
Flds.Update
Set iBp2 = iBp.AddBodyPart
Set Flds = iBp2.Fields
Flds("urn:schemas:mailheader:content-type") = "text/plain"
Flds("urn:schemas:mailheader:content-transfer-encoding") = "quoted-printable"
Flds.Update
Dim Stm as ADODB.Stream
Set Stm = iBp2.GetDecodedContentStream
Stm.WriteText "This is a test", stWriteLine
Stm.Flush
Set iBp2 = iBp.AddBodyPart
Set Flds = iBp2.Fields
Flds("urn:schemas:mailheader:content-type") = "text/html"
Flds("urn:schemas:mailheader:content-transfer-encoding") = "quoted-printable"
Flds.Update
Set Stm = iBp2.GetDecodedContentStream
Stm.WriteText "This is a <i>test</i>", stWriteLine
Stm.Flush
iMsg.Send

How to add default signature and new tables in a new outlook mail by testcomplete

I am trying to send new outlook mail by testcomplete using vb scripting language .In that new mail i want to add new tables and keep default signature at bottom of mail by testcomplete. i am getting VB script run time error when i am using this code..please check the code and suggest me the correct methods i have to use to add new tables and signature
Function SendMail()
Dim objOutLook, NamespaceMAPI,objNewMail, fso, SendReceiveControls
Dim strTo,strCc ,strBcc ,strSubject, AccountName,strAttachmentPath
strSubject="test"
strTo=yyy#yy.com
strCc=XXX#XX.com
strBcc =zzz#zzz.com
strAttachmentPath="c:\text.txt"
Set objOutLook = CreateObject("Outlook.Application")
Set NamespaceMAPI = objOutLook.GetNamespace("MAPI")
Set objNewMail = objOutLook.CreateItem(olMailItem)
objOutLook.DisplayAlerts =True
objNewMail.TO = strTo
objNewMail.CC = strCc
objNewMail.BCC=strBcc
objNewMail.Subject = strSubject
objNewMail.Body = strMsg
If strAttachmentPath <> "" Then
Set fso =CreateObject("Scripting.FileSystemObject")
If fso.FileExists(strAttachmentPath) Then
objNewMail.Attachments.Add(strAttachmentPath)
objNewMail.GetDefaultsignature() 'script run time error occured here
objNewMail.addtable(4,3)
objNewMail.display
Else
msgbox "Attachment File Does not exists"
End If
End If
objOutLook.Quit
''''''' Releasing objects '''''''
Set objOutLook =Nothing
Set objNewMail = Nothing
Set fso = Nothing
End Function
please help me.. thanks in advannce....
See if this or this helps. They are alternative methods to yours.
I prefer to use the 2nd option, the CDO method, you just need to take atention to the fact that usually this email goes to the spam inbox, you need to manually add it to your secure contacts

Sending email from webpage using Outlook

I have a webpage that has a button that sends a letter on the page to an email recipent. Currently we are use Lotus Notes and with VB script, we are able to create an object of Lotus Notes and one of the properties for this object is PutInFolder. After the user clicks on the email button, the script will send the email and also put save the email in a certain folder on the user's computer. Our company is now switching over to Outlook 2007 and I'm looking to do the same thing with an Outlook object instead. Our development is local intranet only, and there are only a few users that will have access to this. Anyway, my problem is I cannot seem to find the same functionality with an Outlook Application.
I do have the send of the email currently working using this logic. Does anyone have any ideas on how to save the email in the user's outlook folder? I tried looking for a list of properties that I can call but I cannot find anything searching. Maybe I don't have the right terminalogy in the searches.
Thank you.
sub send_mailvb(sendto, sendcc, sendbcc, subject_text, body_text, attachment1, attachment2, attachment3)
'Open mail, adress, attach report
dim objOutlk 'Outlook
dim objMail 'Email item
dim strMsg
const olMailItem = 0
'Create a new message
set objOutlk = createobject("Outlook.Application")
set objMail = objOutlk.createitem(olMailItem)
' Setup send to
objMail.To = sendto
' Setup send cc
If sendcc <> "" Then
objMail.cc = sendcc
End If
' Setup send bcc
If sendbcc <> "" Then
objMail.bcc = sendbcc
End If
'Set up Subject Line
objMail.subject = subject_text
'Add the body
strMsg = body_text & vbcrlf
'Add an attachments
If attachment1 <> "" Then
objMail.attachments.add(attachment1)
End If
If attachment2 <> "" Then
objMail.attachments.add(attachment2)
End If
If attachment3 <> "" Then
objMail.attachments.add(attachment3)
End If
objMail.body = strMsg
objMail.display 'Use this to display before sending, otherwise call objMail.Send to send without reviewing
'Clean up
set objMail = nothing
set objOutlk = nothing
End Sub
For future reference... I found the solution I was looking for. It wasn't too bad of a mess. Here's the modified source to replicate the Send and save email to a specific folder incase someone else comes looking. Thanks to Tester101 for the website I was looking for. Again this is vbscript imbedded in the HTML page.
sub send_mailvb(sendto, sendcc, sendbcc, subject_text, body_text, attachment1, attachment2, attachment3)
'Open mail, adress, attach report
dim objOutlk 'Outlook
dim objMail 'Email item
dim strMsg
dim myInbox
const olMailItem = 0
'Create a new message
set objOutlk = createobject("Outlook.Application")
Set objNameSpace = objOutlk.Session
set objMail = objOutlk.createitem(olMailItem)
Set myNameSpace = objOutlk.GetNamespace("MAPI")
Set myExplorer = objOutlk.ActiveExplorer
' 6 at least on my machine pointed to the Inbox (should be the same as constant olFolderInbox). Within the Inbox I have a folder called Test
Set myExplorer.CurrentFolder = myNameSpace.GetDefaultFolder(6).Folders("Test")
Set myFolder = myExplorer.CurrentFolder
' Setup send to
objMail.To = sendto
' Setup send cc
If sendcc "" Then
objMail.cc = sendcc
End If
' Setup send bcc
If sendbcc "" Then
objMail.bcc = sendbcc
End If
'Set up Subject Line
objMail.subject = subject_text
'Add the body
strMsg = body_text & vbcrlf
'Add an attachments
If attachment1 "" Then
objMail.attachments.add(attachment1)
End If
If attachment2 "" Then
objMail.attachments.add(attachment2)
End If
If attachment3 "" Then
objMail.attachments.add(attachment3)
End If
objMail.body = strMsg
// objMail.display 'Use this to display before sending, otherwise call objMail.Send to send without reviewing
objMail.Save
objMail.Move(myFolder)
objMail.Send
'Clean up
set objMail = nothing
set objOutlk = nothing
End Sub
I found this article. It might be something tha could help.
http://www.outlookcode.com/codedetail_print.aspx?id=1041
If not this site has great resources for working with outlook.
It looks like the MailItem object has a Save method, as well as a SaveAs method. So you should be able to do something like this.
objMail.SaveAs "C:\Test.msg", 3
The 3 is to save the message in olMSG format see OlSaveAsType Enumeration.
I have a solution. We've decided to bcc the person sending the email and then use an outlook rule to move the email to the specified outlook folder. Thanks to everyone that replied.

Display JPEG using Response.BinaryWrite

I'm displaying an image like this:
<img src='counter.asp'>
counter.asp is doing a hit-counter do determine how often the image was displayed (I'll replace it with a modrewrite URL).
The problem: in the counter.asp script I need to send the actual .jpg image to the browser. How could this be done? I suppose I need to load the image through FSO, and then send it using Response.BinaryWrite - any ideas?
To read and output binary you can simply use the ADODB.Stream object.
See the ADODB.Stream MSDN Library:
http://msdn.microsoft.com/en-us/library/ms675032(VS.85).aspx
Here's an example I found from Experts Exchange as well:
Function ReadBinaryFile(strFileName)
on error resume next
Set oStream = Server.CreateObject("ADODB.Stream")
if Err.Number <> 0 then
ReadBinaryFile=Err.Description
Err.Clear
exit function
end if
oStream.Type = 1
oStream.Open
oStream.LoadFromFile strFileName
if Err.Number<>0 then
ReadBinaryFile=Err.Description
Err.Clear
exit function
end if
ReadBinaryFile=oStream.Read
oStream.Close
set oStream = nothing
if Err.Number<>0 then ReadBinaryFile=Err.Description
End Function
you can just redirect your counter.asp to the image you want..
<%
response.redirect("/virtual/path/to/yourimage.jpg")
%>
FSO cannot load a binary file, only text. You will need to use a 3th party component.

Resources