Sjef Bosman
asked on
Extension to MIME emails in Lotusscript needed
I want to create a multipart MIME message, with the following sections:
- plain section
- plain text
- html section
- html code
- image-1
- image-n
I want the images as inline images, i.e. with code like <img src="cid:image_123">
I found the following class, created by Jake Howlett:
http://www.codestore.net/store.nsf/unid/BLOG-20091022-0419/
I'd like to have it adapted with a call to add an inline image. For that purpose I now have the code below, which doesn't work.
Please help me to improve the code so that I can create html mails with inline internal images.
Thanks!!
- plain section
- plain text
- html section
- html code
- image-1
- image-n
I want the images as inline images, i.e. with code like <img src="cid:image_123">
I found the following class, created by Jake Howlett:
http://www.codestore.net/store.nsf/unid/BLOG-20091022-0419/
I'd like to have it adapted with a call to add an inline image. For that purpose I now have the code below, which doesn't work.
Please help me to improve the code so that I can create html mails with inline internal images.
Thanks!!
Const ERR_EMAIL_MODIFICATION_NOT_ALLOWED = "You can not make changes to an email once it has been sent."
Const ERR_EMAIL_NO_CONTENT = "Email has no body."
Class Email
Private session As NotesSession
Private doc As NotesDocument
Private body As NotesMIMEEntity
Private mh As NotesMIMEHeader
Private mc As NotesMIMEEntity
Private stream As NotesStream
Private isTextSet As Boolean
Private isHTMLSet As Boolean
Private isStyleSet As Boolean
Private isRebuildNeeded As Boolean
Private isMailBuilt As Boolean
Private rtitem As NotesRichTextItem
Private str_TextPart As String
Private str_HTMLPart As String
Private str_DefaultStyles As String
Private str_Styles As String
Private FromName(0 To 2) As String
Private images() As String
Private nimages As Integer
Sub New()
Set Me.session = New NotesSession()
Set Me.doc = Me.session.Currentdatabase.CreateDocument
Me.doc.Form = "Memo"
Me.FromName(0) = "Sender's Name"
Me.FromName(1) = "foo@bar.net"
Me.FromName(2) = "DOMAIN"
Me.str_DefaultStyles = "body{margin:10px;font-family:verdana,arial,helvetica,sans-serif;}"
Me.isTextSet = False
Me.isHTMLSet = False
Me.isRebuildNeeded = True
Me.isMailBuilt = False
End Sub
%REM
Property Set Subject
Description: Comments for Property Set
%END REM
Property Set Subject As String
Me.doc.subject = subject
End Property
%REM
Sub setTextPart
Description: Comments for Sub
%END REM
Property Set Plain
Me.str_TextPart = Plain
Me.isTextSet = True
Me.isRebuildNeeded = True
End Property
Property Get Plain
Plain = Me.str_TextPart
End Property
%REM
Sub setHTMLPart
Description: Comments for Sub
%END REM
Property Set HTML
Me.str_HTMLPart = HTML
Me.isHTMLSet = True
Me.isRebuildNeeded = True
End Property
Sub EmbedImage(file As String)
Dim ContentType As String
Dim streamFile As NotesStream
Dim filename As String
Redim Preserve images(nimages)
images(nimages)= file
nimages= nimages+1
filename= Strrightback(file, "\")
If Instr(file, "/") Then filename= Strrightback(file, "/")
Me.HTML= Me.HTML + |<img src="cid:image_| & nimages & |">|
End Sub
Private Sub AttachImage(file As String)
Dim ContentType As String
Dim streamFile As NotesStream
Dim filename As String
Dim n As Integer
filename= Strrightback(file, "\")
If Instr(file, "/") Then filename= Strrightback(file, "/")
Select Case Lcase(Strright(filename, ".") )
Case "gif"
ContentType = "image/gif"
Case "jpeg", "jpg"
ContentType = "image/jpeg"
Case Else
ContentType = "application/octet-stream"
End Select
Set Me.mc= Me.body.createChildEntity()
Set Me.mh = Me.mc.CreateHeader("Content-Disposition")
Call Me.mh.SetHeaderVal({inline; filename="} & filename & {"} )
'only required if we're embedding something we need to reference later on
Set Me.mh = Me.mc.CreateHeader("Content-ID")
n= n + 1
Call Me.mh.SetHeaderVal( |<image_| & n & |>| )
Set streamFile = session.CreateStream
If streamFile.Open(file) Then
Call Me.mc.SetContentFromBytes(streamFile, ContentType & {; name="} & filename & {"}, ENC_IDENTITY_BINARY)
Call streamFile.Close
End If
End Sub
Property Get HTML
HTML = Me.str_HTMLPart
End Property
%REM
Sub Styles
Description: Comments for Sub
%END REM
Property Set Styles As String
Me.str_Styles = Styles
Me.isStyleSet = True
Me.isRebuildNeeded = True
End Property
%REM
Sub CSS
Description: Shortcut sub to Styles
%END REM
Property Set CSS As String
Me.Styles = CSS
End Property
%REM
Sub setFromAddress
Description: Comments for Sub
%END REM
Property Set Sender As Variant
Me.FromName(0) = Sender(0)
Me.FromName(1) = Sender(1)
Me.FromName(2) = Sender(2)
Me.isRebuildNeeded = True
End Property
%REM
Property Set replyTo
Description: Comments for Property Set
%END REM
Property Set ReplyTo As String
Me.Doc.ReplyTo = ReplyTo
Me.isRebuildNeeded = True
End Property
%REM
Property Set CopyTo
Description: Comments for Property Set
%END REM
Property Set CopyTo As String
Me.Doc.CopyTo = CopyTo
Me.isRebuildNeeded = True
End Property
%REM
Property Set BlindCopyTo
Description: Comments for Property Set
%END REM
Property Set BlindCopyTo As String
Me.Doc.BlindCopyTo = BlindCopyTo
Me.isRebuildNeeded = True
End Property
%REM
Sub Rebuild
Description: Comments for Sub
%END REM
Sub Rebuild
If Me.doc.HasItem("Body") Then
Call Me.doc.RemoveItem("Body")
'Is this needed to allow rebuilding between sends?
'Set Me.body = Me.Doc.GetMIMEEntity( "Body" )
'If Me.body Is Nothing Then
' MsgBox "can't find mime entity"
'End If
'Call Me.body.Remove()
End If
If Me.isHTMLSet Then 'Send mulipart/alternative
'Create the MIME headers
Me.session.convertMIME = False
'This is the line that errors if you try and rebuild the message between sends!
'Error = "Object varaible not set"
Set Me.body = Me.doc.CreateMIMEEntity("Body")
Set Me.mh = Me.body.CreateHeader({MIME-Version})
Call Me.mh.SetHeaderVal("1.0")
Set Me.mh = Me.body.CreateHeader("Content-Type")
Call Me.mh.SetHeaderValAndParams( {multipart/mixed;boundary="=NextPart_="}) ' was multipart/alternative
'Send the text part first
If Me.isTextSet Then
Set Me.mc = Me.body.createChildEntity()
Set Me.stream = Me.session.createStream()
Call Me.stream.WriteText(Me.str_TextPart)
Call Me.mc.setContentFromText(Me.stream, {text/plain}, ENC_NONE)
End If
'Now send the HTML part. Order is important!
Set Me.mc = Me.body.createChildEntity()
' Set Me.mh = Me.mc2.CreateHeader("Content-Type")
' Call Me.mh.SetHeaderValAndParams( {multipart/related;boundary="=NextPart_rich="}) ' was multipart/alternative
Set Me.stream = Me.session.createStream()
' Set Me.mc2 = Me.body.createChildEntity()
Call stream.WriteText("<html>", EOL_CR)
Call stream.WriteText("<head>", EOL_CR)
Call stream.WriteText("<style>", EOL_CR)
Call stream.WriteText(Me.str_DefaultStyles, EOL_CR)
If Me.isStyleSet Then
Call stream.WriteText(Me.str_Styles, EOL_CR)
End If
Call stream.WriteText("</style>", EOL_CR)
Call stream.WriteText("</head>", EOL_CR)
Call stream.WriteText("<body>", EOL_CR)
Call stream.WriteText(Replace(Me.str_HTMLPart, ">", ">"+Chr(10)))
Call stream.WriteText("</body>", EOL_CR)
Call stream.WriteText("</html>", EOL_CR)
Call Me.mc.setContentFromText(Me.stream, {text/html;charset="iso-8859-1"}, ENC_NONE)
Forall image In images
Call AttachImage(image)
End Forall
Call Me.doc.Closemimeentities(True)
Me.session.convertMIME = True
Elseif Me.isTextSet Then 'Just Text will do!
Set Me.rtitem = New NotesRichTextItem(Me.doc, "Body")
Me.rtitem.Appendtext(Me.Str_TextPart)
Else 'No content!
Error 1000, ERR_EMAIL_NO_CONTENT
End If
Me.doc.Principal= Me.FromName(0) +" <"+Me.FromName(1)+"@"+Me.FromName(2)+">"
Me.doc.InetFrom = Me.FromName(0) +" <"+Me.FromName(1)+">"
Me.isMailBuilt = True
Me.isRebuildNeeded = False
End Sub
%REM
Sub Send
Description: Comments for Sub
%END REM
Sub Send(sendTo As String)
If Me.isMailBuilt And Me.isRebuildNeeded Then
Error 1000, ERR_EMAIL_MODIFICATION_NOT_ALLOWED
Elseif Not Me.isMailBuilt Then
Call Me.Rebuild()
End If
Me.Doc.SendTo = SendTo
Call Me.Doc.Send(False)
End Sub
End Class
Sub Initialize
Dim mail As New Email()
mail.Subject = "A multipart email generated " & Now
mail.Sender= Split("Your name;yourname@yourdomain.com;ACME", ";")
mail.Plain = "This is plain text"
mail.HTML = "<p>This is <i>fancy</i> text</p>"
mail.EmbedImage "c:\Windows\Cloud.gif"
mail.HTML = mail.HTML + "<p>Woops. Forgot this</p>"
mail.CSS = "p{margin:2em}"
' mail.CopyTo= "someoneelse@somedomain.com"
mail.Send("testaddress@destination.com")
End Sub
ASKER
Nope. It's like a newsletter, distributed via MIME mail. The plain text should just read:
If you see this text, please go to www.abcd.net/info to get the same document in PDF format
If you see this text, please go to www.abcd.net/info to get the same document in PDF format
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes, that already explains better what I'm looking for. Ideally, what I'm after are the calls in LotusScript to prepare the multi-part stuff, with children and grandchildren and so. See the codestore-link above, I also posted there, maybe Jake has the time to look into it.
What happens when you run your code?
Where does it fail?
Where does it fail?
Which mail client are you using for testing?
ASKER
Code doesn't fail, but code produces a mail I don't want :-)) Try to dump the code in an agent and send yourself a mail. Set your own mail addresses and select an existing image file on the disk.
There are some other modifications to the code, at the start of the Rebuild method: the multipart/mixed, which causes all sections to be added to the content, which I do not want. What I need to know is how exactly should CreateChildEntity be called and how often to allow a) the plain-text section, b) the rich-text section with c) the embedded in-line internal image.
Oh, and I'm testing in R7.0.3 (but that shouldn't be very important).
There are some other modifications to the code, at the start of the Rebuild method: the multipart/mixed, which causes all sections to be added to the content, which I do not want. What I need to know is how exactly should CreateChildEntity be called and how often to allow a) the plain-text section, b) the rich-text section with c) the embedded in-line internal image.
Oh, and I'm testing in R7.0.3 (but that shouldn't be very important).
ASKER
Oh, mail client... I send mails to my Gmail address. I still have problems with Gmail, Notes looks better but isn't correct either. If I get the structure I want to have, I will test it in Thunderbird (and maybe Outlook Express).
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks, I'll study the code but I doubt it'll tell me much more.
What I really need to know is the exact calls to execute to generate a mail with images, embedded in a mail with a text and a rich-text part. Did nobody ever do that yet in Notes??
What I really need to know is the exact calls to execute to generate a mail with images, embedded in a mail with a text and a rich-text part. Did nobody ever do that yet in Notes??
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
LOL !!
he he, I'm glad you liked it...
I do not think it is your code, I have tested it from my local PC and got the attach results, which looks fine to me. Where are you running this code from, is it an agent, button or action. If agent, is it scheduled or on click event . Another question from Web or Client
gmail-result.GIF
gmail-result.GIF
ASKER
> which looks fine to me
Yes exactly, it 'looks' fine but it it's not what I want!
I want "This is plain text" to be invisible, in a separate section of the multi-part mail. There should be no attachment visible. For the rest you are right, it seems to work.
What I want to produce:
- a section with plain text, which only shows up in applications not supporting multi-part MIME mails
- another section with rich text plus one or more embedded images; the images should show up in-line (which essentially works)
- for the time being, no attachments
All multi-part MIME mail agents in LotusScript that I found create a mail with attachments, and in that case the mail can be one section only. I suppose I need to add more children, but I can't do that alone... ;-)
Yes exactly, it 'looks' fine but it it's not what I want!
I want "This is plain text" to be invisible, in a separate section of the multi-part mail. There should be no attachment visible. For the rest you are right, it seems to work.
What I want to produce:
- a section with plain text, which only shows up in applications not supporting multi-part MIME mails
- another section with rich text plus one or more embedded images; the images should show up in-line (which essentially works)
- for the time being, no attachments
All multi-part MIME mail agents in LotusScript that I found create a mail with attachments, and in that case the mail can be one section only. I suppose I need to add more children, but I can't do that alone... ;-)
ASKER
I must have cracked it, a long time ago, but I'd have to examine multiple databases to find how I exactly did it. If someone needs it, better post a new question.
Thanks guys!
Thanks guys!
Why does it have to be plain text? Can you just format html so that it looks like plain text?