I have a vb.net application which uses EWS to send mail. The user account has no mailbox, but has permissions to send on behalf of another mailbox. Normally this code runs fine because it has the full email address to send to, however it fails when I try to find the address by resolving the name :
When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids.
The code is as follows :
Private Function ResolveName(ByVal Name As String) As String
Dim returnValue As NameResolutionCollection
returnValue = _MainService.ResolveName(Name)
Dim resolution As NameResolution
For Each resolution In returnValue
Return resolution.Mailbox.Address
Next
Call _Owner.LogThreadMessage(frmMain.ObjectTypes.Error, "Error resolving address", Name)
Return ""
End Function
I think somehow it is trying to use the user account to access an address book, rather than the mailbox.
Just incase anyone else runs into the same problem, I fixed this by looking in the directory only :
returnValue = _MainService.ResolveName(Name, ResolveNameSearchLocation.DirectoryOnly, True)
I think this is now looking at the global address list rather than in contacts, which doesn't exist.
Related
On a domino-built website I have a button that runs a lotusscript agent. Part of this agent sends emails out. Below is summary code/snippet to give you the idea of what I am doing
(only relevant lines of code):
dim sendtoString as string
dim sendtoArray as variant
sendtoString = "mailaddress1,mailaddress2" '<----- two email addresses in a string
sendtoArray = split(sendtoString,|,|)
maildoc.sendto = sendtoArray
maildoc.save(true,true) '<--- so I can look at it as a saved document
'maildoc.send(false) '<----- NOTE as of right now I am not sending, choosing to simply look at the saved version until I get this right
The strange thing is TWO documents are SAVED. I have not enabled the "send" line yet because I do not want multiple emails to be sent from the code, instead hoping the router will do this for me.
Maybe the send is going to work fine, and individuals will NOT receive multiple emails (if six email addresses are in the original string, I dont want six emails landing in each person's inbox).....and maybe I need to use the "SaveMessageOnSend" property instead.
Anyone have any insight on what is going on here?
Using LotusScript, you can generate and send email messages. When creating the email message, recipient email addresses must be assigned to the SendTo field. To send an email to a single recipient, simply set the object value to a valid email address. For example:
doc.SendTo = "someone#ibm.com"
However, when sending email to multiple recipients, you must create an array of values and append the values to the SendTo, CopyTo, or BlindCopyTo field(s). This can be achieved by building either a static or dynamic array of values.
For a full answer you can find on this blog: https://flylib.com/books/en/2.348.1/sending_email_to_multiple_recipients_using_lotusscript.html
I created a makro in excel to send all TODOs to the responsible people. Now I want to add the sender address into the CC. I know how to set the CC but I don't know how to get the current sender address.
Set session = CreateObject("Notes.NotesSession")
Set db = session.GETDATABASE("", "")
Call db.OPENMAIL
Set doc = db.CREATEDOCUMENT
Call doc.REPLACEITEMVALUE("CopyTo", strEmail)
I think it should work with the notes session, but I didn't find any method for this.
You can just use NotesSession.UserName(). This is Notes mail you are sending. You don't need a full SMTP-style address with the # and the DNS domain name. You can just put the user's Notes username in an addressing field and the Domino router will do the lookup and it will just work.
The above is true as long as (a) the server that you have established the session with is either the user's home mail server, a member of the same Notes domain (which is not the same thing as a DNS domain), or a member of a Notes domain that includes the user's Notes domain as part of its Directory Assistance (or its cascading address book list if it's using 20-year-old configurations), and (b) the username is unique within the above scope.
another suggestion, copy sender from last sent mail, to test
Set view = db.GetView("(($Sent))")
Set sentdoc = View.GetLastDocument
sender=sentdoc.getItemValue("From")
The way I automated Lotus Notes and sending emails was using this site below:
Send files using Lotus Notes
The area you want to pay attention to is at the bottom, which takes "noDocument" and adds the relevant titles "Subject", "to", "Sendto" etc.
'Add values to the created e-mail main properties.
With noDocument
.Form = "Memo"
.SendTo = vaRecipients
.CopyTo = vaCopyTo
.Subject = stSubject
.Body = vaMsg
.SaveMessageOnSend = True
.PostedDate = Now()
.Send 0, vaRecipients
End With
Use NotesSession.userName() to get the current username. If you really want the full email address you might also be able use #namelookup formula.
However, I would stay away from accessing notes via COM as it does not work on 64bit and IBM couldn't care less about it. I had several excel files which used this handy technique, but they are all broken since we moved to 64bit. Check this old kb https://www-304.ibm.com/support/docview.wss?uid=swg21454291
I am new to a Notes environment, so I've spent a lot of time reading here and other forums in an attempt to learn how to VBA an email via Lotus/IBM Notes.
There seems to be 2 main approaches; I am using the NotesUI method, since one of the requirements for the email is to embed an image of a portion of the Excel worksheet, as well as attaching the file itself.
At this stage, I have functioning code which achieves this (more often than not!) from the email address of the person who runs the macro. I can claim no credit for this - it has been borrowed with gratitude from the web.
However, the team has a shared email account, from which I wish to send the email.
I have seen some discussion of Principal and being able to specify a FromName, but I've so far been unable to achieve this last part.
The code I am using to successfully send an email with an attachment and an image of a section of my worksheet is below - and tips on how to modify the existing code to send from another email address would be most welcomed!
Sub SendEmbedMail(mailTo As String, stSubject As String, _
copyData As Range, Optional msgBeforeEmbed As String, _
Optional msgAfterEmbed As String, Optional attachFile As Workbook)
Dim Notes As Object, db As Object, WorkSpace As Object
Dim UIdoc As Object, UserName As String, MailDbName As String
Dim AttachMe As Object, EmbedObj As Object
'Create & Open New Document
Set WorkSpace = CreateObject("Notes.NotesUIWorkspace")
Call WorkSpace.COMPOSEDOCUMENT(, , "Memo")
Set UIdoc = WorkSpace.CURRENTDOCUMENT
Call UIdoc.inserttext(mailTo)
Call UIdoc.gotofield("Body")
Call UIdoc.inserttext(msgBeforeEmbed)
copyData.CopyPicture
Call UIdoc.Paste
Call UIdoc.inserttext(msgAfterEmbed)
Call UIdoc.gotofield("Subject")
Call UIdoc.inserttext(stSubject)
If Not attachFile Is Nothing Then
Set AttachMe = UIdoc.Document.CreateRichTextItem("Attachment")
Set EmbedObj = AttachMe.EmbedObject(1454, vbNullString, _
attachFile.FullName, "Attachment")
End If
Call UIdoc.Send(0, mailTo)
End Sub
Writing the document directly to the server's mail.box file is often used as a solution for this. See the first answer to this question, and look at the code of the OpenNTF Team Mailbox project for more details. Doing this generally won't completely remove the sender's info from the message, though. (It may vary depending on the Notes and Domino versions, but Notes has never been fully cooperative with spoofing attempts done this way.)
If you want to completely hide the identity of the sender, the approach that works best is to use an agent running on the server to send the message - or in your case, to re-send it. The agent can be signed by a generic Notes id instead of the developer's or the server's id, so by the time the actual send to the actual recipient occurs, the end-user isn't part of the process. In your case, you could accomplish that by creating a mail-in database and changing your VBA code from Call UIdoc.inserttext(mailTo) to Call UIdoc.inserttext("My mail-in database name goes here") but you'll also have to put your mailTo value somewhere, otherwise the agent won't know where to re-send it. You can do that by adding a line of code like this:
Call UIdoc.Document.ReplaceItemValue("actualRecipient",mailTo)
Your agent can be set up to run after new mail arrives in the mail-in database, and it can then clean up the message by removing the From and ReplyTo and INETFrom (if they exist - see here) items, and setting the SendTo and Principal and INETFrom fields. Omitting the basic framework code for the agent (some examples here) and assuming that doc is the variable that contains the NotesDocument that you are re-sending, the actual working part of the agent could be similar to this:
doc.RemoveItem("From")
doc.RemoveItem("InetFROM")
doc.RemoveItem("ReplyTo")
if doc.hasItem("actualRecipient") then
doc.ReplaceItemValue("SendTo",doc.actualRecipient(0))
doc.RemoveItem("actualRecipient")
else
' here you'll want to do something sensible if a message arrives in the mail-in
' database but it doesn't have an actualRecipient; i.e., it wasn't sent by your
' VBA code!
End if
Call doc.ReplaceItemValue("Principal","support#company.com#Your Notes Domain Goes Here <support#company.com>")
Call doc.ReplaceItemValue("INETFrom", "support#company.com")
Call doc.Send()
You could also do this using back-end classes (not UI). I wrote a class to help with creating emails, it includes changing the from-address to anything you like:
http://blog.texasswede.com/lotusscript-mail-notification-class/
You just have to add a method to insert a picture in the text, you can use the approach described by Thomas Hampel at http://blog.tomcat2000.com/blog/tomcat2000.nsf/dx/notesapi-import-pictures-into-richtext-fields-using-backend-classes.htm.
I composed a new email. Before sending this email, I would like (using VBA) to get the senders email address.
I wrote the following example code. When I run this code, the first message box displays the email subject correctly, however the second message box shows nothing (the message box is empty).
Sub email_test()
Dim eSubject As String
Dim eSender As String
eSubject = Application.ActiveInspector.currentItem.subject
MsgBox eSubject
eSubject = Application.ActiveInspector.currentItem.SenderEmailAddress
MsgBox eSender
End Sub
A new mail item doesn't have the Sender* related properties set. They are set right after the message is processed by the transport provider and can be get, for example, from the Sent Items folder. You can handle the ItemAdd event of the Items class which comes from the Sent Items folder. Be aware, the SaveSentMessageFolder property of the MailItem class can be used to set a Folder object that represents the folder in which a copy of the e-mail message will be saved after being sent. Also the DeleteAfterSubmit property can be set, in that case a copy of the mail message is not saved after being sent.
You may be interested in the SendUsingAccount property which allows to get or set set an Account object that represents the account under which the MailItem is to be sent.
Use MailItem.SendUsingAccount.SmtpAddress. If MailItem.SendUsingAccount is null, you can asssume the default account will be used - the address can be accessed from Application.Session.CurrentUser.Address. In case of an Exchange mailbox, use Application.Session.CurrentUser.AdderssEntry.GetExchangeUser.PrimarySmtpAddress
Despite the fact that I know almost nothing about LDAP and AD apart from the basics of what it does (in this case, Microsoft) I have been asked to modify a program so that it will retrieve the user's email address. The application can be configured to use LDAP. I'm not sure exactly how it is using it - something to do with synchronising the application's passwords with the user's LDAP password. The application has a password, which might not be the same as the user's LDAP password. There is some mechanism to synchronise the passwords - but in theory that shouldn't concern me - I'm told that it works.
Of course, we didn't have an LDAP server here for me to try things out on.
So I have installed Windows 2003 server on a PC, and enabled LDAP on it (a massive learning curve, I can tell you). I have added a couple of users. and even managed to get one of them to be a member of Domain Admin.
In the application I'm working on, there is a setup facility to configure the connection to the LDAP. This has a helpful Test Settings button. If I put in the server IP address and the port number, and press Test Settings then it tells me that the test was successful. Hmm - that seems unlikely. There are other pieces of information it asks for:
Service Account DN
Service Account Password
User Account Container.
If I leave those blank, and save the settings then I am now able to start up the application and put only the username in with any or no password - which is not right, of course - it should prevent me from starting up my app. So I can only assume that I need to set up those three pieces of info.
The LDAP server I created is called, I believe, Aware.Server
So I have put DC=AWare, DC=Server into the Service account DN (I'm just guessing here, not really sure what should be in there) and cn=Users, DC=AWare.Server into the User Account Container (again, I don't really know what that is, or what is meant to be in there).
I have no idea what the Service Account Password is, so I leave that blank.
When I press Test Settings it asks me for a user name and password.
If I leave those blank then it says that the test was successful. I'm beginning to worry.
If I put in a user name that I have entered into LDAP, with a password, it says that the test was successful.
Actually, if I put anything at all into those boxes, it says that it is successful.
However, if I put something into the Service Account Password then the test is not successful - it says that the service account supplied has either an invalid user name or password.
So the main question at this point is - how do I find out what the service account password is?
And is the behaviour that I'm getting to be expected?
Thanks
Steve
Code for validating sign on includes:
Public Shared Function ValidateUser(ByVal server As String, ByVal port As Integer, ByVal userBase As String, ByVal userName As String, ByVal password As String, ByVal bindUser As String, ByVal bindPassword As String) As LdapValidatorResult
Dim retVal As New LdapValidatorResult
Dim conn As New Novell.Directory.Ldap.LdapConnection()
Try
'connect to the specificed server for user validation
conn.Connect(server, port)
retVal.Result = LdapValidatorResultType.Success
Try
'now authenticate to we can then go on to see if the username specificed exists
conn.Bind(bindUser, bindPassword)
'construct the distinguished name to uniquely id the specified user
Dim searchString As String = String.Format("CN={0},{1}", userName, userBase)
'look to see if the user attempting to login to a-ware exists
Dim sResults As LdapSearchResults = conn.Search(searchString, Novell.Directory.Ldap.LdapConnection.SCOPE_SUB, Nothing, Nothing, False) '"(&(!(objectClass=computer)))"
If sResults.hasMore Then
Try
'now validate the user with the password as the final check
Dim userDN As String = sResults.next.DN
conn.Bind(userDN, password)
retVal.Result = LdapValidatorResultType.Success
Catch ex As Novell.Directory.Ldap.LdapException
If ex.ResultCode = Novell.Directory.Ldap.LdapException.INVALID_CREDENTIALS Then
retVal.Result = LdapValidatorResultType.InvalidUserNameOrPassword
End If
retVal.ExceptInfo = ex
End Try
Else
retVal.Result = LdapValidatorResultType.NonExistentUser
End If
Catch ex As Novell.Directory.Ldap.LdapException
Select Case ex.ResultCode
Case Novell.Directory.Ldap.LdapException.INVALID_CREDENTIALS
retVal.Result = LdapValidatorResultType.InvalidBindUserNameOrPassword
Case Novell.Directory.Ldap.LdapException.CONNECT_ERROR
retVal.Result = LdapValidatorResultType.ServerDown
End Select
retVal.ExceptInfo = ex
End Try
Catch ex As Novell.Directory.Ldap.LdapException
Dim cause As System.Net.Sockets.SocketException = TryCast(ex.Cause, System.Net.Sockets.SocketException)
If cause IsNot Nothing Then
Select Case cause.ErrorCode
Case 1101
retVal.Result = LdapValidatorResultType.InvalidNameIp
Case 1106
retVal.Result = LdapValidatorResultType.RefusedConnectionOnPort
Case 10060
retVal.Result = LdapValidatorResultType.ServerDown
End Select
End If
retVal.ExceptInfo = ex
End Try
Return retVal
End Function
It looks like it wants you to create a user account in your domain for the app to use. Every object has a distinguished name (DN). So it's asking for the DN of the user you created and its password, as well as the DN of the container that you created the user in. I can't tell what your domain DNS name is, but I'm guessing it's AWare.Server. So, if you create a user with username appuser in the default Users container with the password P#ssw0rd, then you would give the following:
Service Account DN: CN=appuser,CN=Users,DC=AWare,DC=Server
Service Account Password: P#ssw0rd
User Account Container: CN=Users,DC=AWare,DC=Server