Composing Email using LotusScript, inconsistencies

I'm losing my mind. Have a Notes application from which I want to send an email to selected documents within a view. I have a view that has an Action button ("Email Script 1") with LotusScript code on "Click" property. I want to manipulate the sender name to come from a shared mailbox so I set the Principal. This works fine, EXCEPT that when received, it is poorly formatted with some arbitrary hard returns in body of msg.

Sub Click(Source As Button)
	On Error Resume Next
	Dim session As New NotesSession
	Dim workspace As New NotesUIWorkspace
	Dim db As NotesDatabase
	Dim view As NotesView
	Dim doc As NotesDocument
	Dim coll As NotesDocumentCollection
	Dim mailDoc As NotesDocument
	Dim emailField As NotesItem
	Dim principal As String
	Dim subject As String
	Dim body As String
	Dim startTime As Variant
	Dim endTime As Variant
	Dim waitTime As Long
' Set the principal and email content
principal = "Custom Research Study <studyemail@email.com>"
subject = "Email Script 1"
body = "Good afternoon," & Chr(10) & _
"Researchers at the University of HCL in New York, New York are interested in hearing your views on our study topic in your State." & Chr(10) & _
"As a potentially eligible candidate in your State, you are invited to complete a brief survey on our research topic. Because the laws were recently changed in your State, this research will help us to gain an understanding of its impact, risk & factors among eligible candidates like you in your State." & Chr(10) & _
"Please use the link below to access the survey, and answer our generic questions to the best of your ability. All survey participants will be receive a $10 reward." & Chr(10) & _
"Your participation is completely voluntary. You can choose to be in the study or not. If you'd like to participate or have any questions about the study, or have trouble entering our survey, please email or contact me at emailusername@email.com. You may also contact the research team if you no longer wish to receive recruitment e-mails or mailings." & Chr(10) & _
Chr(10) & _
"Thank you in advance for your participation." & Chr(10) & _
"Researcher FirstName LastName, PhD" & Chr(10) & Chr(10) & _
"Please use the following link to take our survey: https://www.hcltechsw.com/domino"

' Get the current database
Set db = session.CurrentDatabase

' Get the current view
Set view = db.GetView("Batch_2")

' Get the selected documents in the view
Dim uiView As NotesUIView
Set uiView = workspace.CurrentView
Set coll = uiView.Documents

' Loop through the selected documents
Set doc = coll.GetFirstDocument
While Not doc Is Nothing
    ' Get the email address from the "Email" field in Notes record
	Set emailField = doc.GetFirstItem("Email")
	
    ' Get the text value of the field
	Dim email As String
	email = emailField.Text
	
    ' Create a new mail document
	Set mailDoc = New NotesDocument(db)
	mailDoc.Form = "Memo"
	
    ' Set the sender, recipient, subject, and body
	mailDoc.Principal = principal
	mailDoc.SendTo = email
	mailDoc.Subject = subject
	
    ' Create a rich text item for the body and set the content
	Dim bodyItem As New NotesRichTextItem(mailDoc, "Body")
	bodyItem.AppendText(body)
	
    ' Send the email
	Call mailDoc.Send(False)
	
    ' Pause for 5 seconds
	startTime = Now
	waitTime = 5 ' seconds
	endTime = startTime + (waitTime / 86400) ' convert seconds to days (1 day = 86400 seconds)
	
	Do While Now < endTime
        ' Wait
	Loop
	
    ' Clean up
	Set doc = coll.GetNextDocument(doc)
	Set mailDoc = Nothing
	Set emailField = Nothing
Wend

Msgbox "Emails sent successfully!"

End Sub

I created a 2nd Action button ("Email Script 2") that specifies explicitly where the hard returns should be, and this works great in properly formatting the msg when received, EXCEPT the sender name shows me as the sender, instead of the necessary Principal & From fields set in the code to come from shared mailbox.

Sub Click(Source As Button)
	On Error Resume Next
	Dim session As New NotesSession
	Dim workspace As New NotesUIWorkspace
	Dim db As NotesDatabase
	Dim view As NotesView
	Dim doc As NotesDocument
	Dim coll As NotesDocumentCollection
	Dim mailDoc As NotesDocument
	Dim emailField As NotesItem
	Dim principal As String
	Dim senderName As String
	Dim subject As String
	Dim body As String
	Dim startTime As Variant
	Dim endTime As Variant
	Dim waitTime As Long
' Set the principal, sender name, and email content
principal = "Custom Research Study <studyemail@email.com>"
senderName = "Custom Research Study <studyemail@email.com>"
subject = "Email Script 2"
body = "<html><body><p>Good afternoon,</p>" & _
"<p>Researchers at the University of HCL in New York, New York are interested in hearing your views on our study topic in your State.</p>" & _
"<p>As a potentially eligible candidate in your State, you are invited to complete a brief survey on our research topic. Because the laws were recently changed in your State, this research will help us to gain an understanding of its impact, risk & factors among eligible candidates like you in your State.</p>" & _
"<p>Please use the link below to access the survey, and answer our generic questions to the best of your ability. All survey participants will be receive a $10 reward.</p>" & _
"<p>Your participation is completely voluntary. You can choose to be in the study or not. If you'd like to participate or have any questions about the study, or have trouble entering our survey, please email or contact me at emailusername@email.com. You may also contact the research team if you no longer wish to receive recruitment e-mails or mailings.</p>" & _
"<p>Thank you in advance for your participation.</p>" & _
"<p>Researcher FirstName LastName, PhD </p>" & _
"<p>Please use the following link to take our survey: <a href=""<https://www.hcltechsw.com/domino>"">https://www.hcltechsw.com/domino</a></p>" & _
"</body></html>"

' Get the current database
Set db = session.CurrentDatabase

' Get the current view
Set view = db.GetView("Batch_2")

' Get the selected documents in the view
Dim uiView As NotesUIView
Set uiView = workspace.CurrentView
Set coll = uiView.Documents

' Loop through the selected documents
Set doc = coll.GetFirstDocument
While Not doc Is Nothing
    ' Get the email address from the "Email" field from Notes record
	Set emailField = doc.GetFirstItem("Email")
	
    ' Get the text value of the field
	Dim email As String
	email = emailField.Text
	
    ' Create a new mail document
	Set mailDoc = New NotesDocument(db)
	mailDoc.Form = "Memo"
	
    ' Set the sender, recipient, and subject
	mailDoc.Principal = principal
	mailDoc.SendTo = email
	mailDoc.Subject = subject
	mailDoc.From = senderName
	
    ' Create a MIME entity for the HTML content
	Dim mime As NotesMIMEEntity
	Dim stream As NotesStream
	Set mime = mailDoc.CreateMIMEEntity
	Set stream = session.CreateStream
	Call stream.WriteText(body)
	Call mime.SetContentFromText(stream, "text/html; charset=iso-8859-1", ENC_IDENTITY_7BIT)
	
	' Set the "From" field after creating the MIME entity
	mailDoc.From = senderName
	
    ' Send the email
	Call mailDoc.Send(False)
	
    ' Pause for 5 seconds
	startTime = Now
	waitTime = 5 ' seconds
	endTime = startTime + (waitTime / 86400) ' convert seconds to days (1 day = 86400 seconds)
	
	Do While Now < endTime
        ' Wait
	Loop
	
    ' Clean up
	Set doc = coll.GetNextDocument(doc)
	Set mailDoc = Nothing
	Set emailField = Nothing
Wend

Msgbox "Emails sent successfully!"

End Sub

So "Email Script 1" does everything I want but it looks ugly when received (especially on mobile device). "Email Script 2" looks just like I want it to, but the Sender Name is personal and I want to mask it as another mailbox , just like Script 1 does so well. How can I become a happy person by getting the best format AND dictate the Sender Name? Below are images of the 2 different msgs as received in GMail:

In order to (more) successfully fake the sender of an email you need to do one thing:

You need to add „@yourdomain“ to the principal address with yourdomain = your domino domain:

principal = {'Custom Research Study' <studyemail@email.com>@yourdomain}

That way the router will not manipulate the mail further and keep that principal.

BUT there will still be a „sent by“ stamp in the email.

There is another way to completely fake the sender: if you have the proper rights you can create the mail directly in the mail.box instead of the db where the agent runs. Then instead of maildoc.send(false) you just use maildoc.Save(True,True) to send it.

The problem with the linebreaks is: The router automatically wraps mails after 80 characters. You just use chr(10) (the linux line feed) for your linebreak where windows usually uses chr(13) & chr(10). That makes your mail look ugly.

Better add the line breaks with default Lotusscript NotesRichtextItem functions, then you are sure, that the router correctly interprets them as such:

Call bodyItem.Appendtext ("Good afternoon,")
Call bodyItem.AddNewLine(1)
Call bodyItem.Appendtext ("Researchers at the University of HCL in New York, New York are interested in hearing your views on our study topic in your State.")
Call bodyItem.AddNewLine(1)
Call bodyItem.Appendtext ("As a potentially eligible candidate in your State, you are invited to complete a brief survey on our research topic. Because the laws were recently changed in your State, this research will help us to gain an understanding of its impact, risk & factors among eligible candidates like you in your State.")
	

By changing the number in AddNewLine you can also enter empty lines.

This will most probably also make your pure Richtext mail look good.

Thank you, Torsten Link, for your prompt reply & assistance. I took your advice and changed my "Email Script 2" as you advised with Principal including . The good news is that is solved my sender name problem. The bad news is that the Body of the message is gone upon receipt (see image below). The only change I made was your recommendation

principal = {'Custom Research Study' <studyemail@email.com>@yourdomain}

This is how received now:

As for your suggestion re: "AddNewLine", I did so with my "Email Script 1". But no change in how it's received. Perhaps that is what you were referring to by saying the router wraps after 80 characters, and that AddNewLine will only help be place hard returns where I want? But the resulting msg received is still ugly as initially shown. I'm not understanding how this "email" code is manipulated by the router while other methods are not. Maybe I need to accomplish this another way. The goal is to 1) produce a mass mailing of 10,000s+ from a Notes application of records, 2) manipulate sender name, and 3) have look decent (ie. not ugly).

OK, I'll try to explain what happens:

With your first code you create a normal richtext mail. When the router takes it and finds out that the recipients are external to Domino then it converts the richtext to mime.

When converting richtext to mime there are rules that are followed. One of them is: Wrap long lines. The default is not 80 (as I stated earlier) but 75 as you can read here in the documentation under "Outbound line length".

This makes your text look ugly.

Your second code already creates MIME. So router does not need to convert anything and will just "pass thru" the html code --> Text does not get wrapped.

So why doesn't this work as as soon as you modify the principal: This modification tells the router to "completely leave alone" this mail... The downside: Router does also not "fix" any issues with your mail...

The next part is speculation: Although I can't find an error directly I guess, that your mail is not a correct MIME Mail as you create it. Router sees this and just fixes it for you... But as stated: adding the "@yourdomain" tells the router: Leave this alone...

I'd probably go the route of directly creating the mail in the mail.box. Then you do not need the "@youdomain" hack to fake the sender and router should treat your mime mail right.

Thanks again, Torsten. Very informative, and all the different scenarios a bit over my head. I did attempt to directly compose in mail.box, and I got the same results as my Original "Email Script 2". No change, though I've been piecing things from all kinds of different sources, I could be missing something obvious

I think I may approach this another way. Instead of using an Action Button in a view, I'll create a scheduled agent to act on a view, "Signed By" and/or "Run on behalf of" the user account that I want to designate as SendFrom. This appears to result in good sender name AND good Body msg. A workaround to trigger it.

fyi, my code to compose directly in mail.box below. While I have rights to do this, the application is going to be managed by regular users, which I assume would need additional privilege to do the same?

Sub Initialize
    Dim session As New NotesSession
    Dim workspace As New NotesUIWorkspace
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim collection As NotesDocumentCollection
    Dim doc As NotesDocument
    Dim memo As NotesDocument
    Dim mailBox As NotesDatabase
    Dim mailDoc As NotesDocument
' Get the current database
Set db = session.CurrentDatabase

' Get the current view
Set view = workspace.CurrentView.View

' Get the selected documents in the view
Set collection = workspace.CurrentView.Documents

' Get the mail.box database
Set mailBox = session.GetDatabase(db.Server, "mail.box")

If Not mailBox Is Nothing Then
    ' Create a new memo document in the mail.box database
    Set mailDoc = mailBox.CreateDocument
    
    ' Set the form of the memo document
    mailDoc.Form = "Memo"
    
    ' Set the subject of the memo
    mailDoc.Subject = "Mail.box"
    
    ' Set the principal and send-from values
    mailDoc.Principal = "Custom Research Study &lt;studyemail@email.com&gt;"        
    mailDoc.SendFrom = "Custom Research Study &lt;studyemail@email.com&gt;"
    
    
    ' Set the MIME body content
    Dim stream As NotesStream
    Set stream = session.CreateStream
    stream.WriteText "Good afternoon," &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Researchers at the University of HCL in New York, New York are interested in hearing your views on our study topic in your State." &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "As a potentially eligible candidate in your State, you are invited to complete a brief survey on our research topic. Because the laws were recently changed in your State, this research will help us to gain an understanding of its impact, risk &amp; factors among eligible candidates like you in your State." &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Please use the link below to access the survey, and answer our generic questions to the best of your ability. All survey participants will be receive a $10 reward." &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Your participation is completely voluntary. You can choose to be in the study or not. If you'd like to participate or have any questions about the study, or have trouble entering our survey, please email or contact me at emailusername@email.com. You may also contact the research team if you no longer wish to receive recruitment e-mails or mailings." &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Thank you in advance for your participation." &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Researcher FirstName LastName, PhD" &amp; Chr(10) &amp; Chr(10)
    stream.WriteText "Please use the following link to take our survey: https://www.hcltechsw.com/domino"
    
    ' Create the MIME entity and set the body content
    Dim mimeBody As NotesMIMEEntity
    Set mimeBody = mailDoc.CreateMIMEEntity("Body")
    Call mimeBody.SetContentFromText(stream, "text/plain; charset=iso-8859-1", ENC_NONE)
    
    ' Loop through the selected documents and add recipients
    Set doc = collection.GetFirstDocument
    While Not doc Is Nothing
        ' Get the email address from the field Email_DM
        Dim recipient As String
        recipient = doc.GetItemValue("Email_DM")(0)
        
        ' Add recipient to the memo
        Call mailDoc.ReplaceItemValue("SendTo", recipient)
        
        Set doc = collection.GetNextDocument(doc)
    Wend
    
    ' Save and send the memo
    Call mailDoc.Save(True, False)
    Call mailDoc.Send(True)
    
    ' Cleanup
    Set mailDoc = Nothing
    Set mailBox = Nothing
Else
    MsgBox "Unable to access mail.box database.", 16, "Error"
End If

' Cleanup
Set collection = Nothing
Set view = Nothing
Set db = Nothing
Set session = Nothing

End Sub

When creating the mail directly in the mail.box then there is no need for mailDoc.Send. Indeed this will result in the mail being sent twice.

Save is enough. Router will send any document that is in the mail.box without needing the "send" method.

But you are right: If the user is involved then creating directly in mail.box often cannot be used directly. In that casee you also need to work with an agent that is signed by someone who is allowed to do this. This agent then is called by the user using a button / another agent with NotesAgent.RunOnServer. Of course then you need the possibility to "inform" the server agent about the collection to work on, probably by flagging them with the first agent or putting them in a folder, so that the second agent can pick it up.

Thanks again for all your insight Torsten. You're right about the mailDoc.Send being unnecessary when created in the router. Just as you told the first time when suggesting it. Sorry for that oversight. My solution was to use Agent on schedule, "Run on behalf of" property set to preferred sender. It works fine for my current project.

But I hope to one day find a way to easily (action button, in LotusScript) send html msgs to clients/subjects in a Notes app as needed, with proper sender name. So far, I've been able to clumsily compose a New Memo in a shared mail.nsf programmatically (using Formula). The user can edit the memo further and/or click Send when ready.

Your explanation helps me decide the path. Thanks again.