Lotus Script agent to export an email to a text file

Hi,

I have been trying to create an agent that will export emails to a text file. I have been using the following:

Public Sub saveFile

Dim uidoc As NotesUIDocument

Dim plainText As String

Dim fileNum As Integer

Dim workspace As New NotesUIWorkspace



Messagebox("f you")



Set uidoc = workspace.CurrentDocument

’ Set uidoc = CurrentDocument

plainText =	uidoc.FieldGetText( "Body" ) 

’ Messagebox( uidoc.FieldGetText( “Body” ) )

'get a free file

fileNum = Freefile

Open "x:\jr\Email.txt" For Output As fileNum

’ write the formatted text to the file

Print #fileNum, plainText

’ close the file

Close #fileNum

End Sub

This agent works fine when I have the email of interest open and select the agent from the actions menu. However, when I try to set this agent up to run on new mail, no new text files are created. The log tells me that the script ran.

Anyone know what could be causing this problem?

cheers!

Subject: Lotus Script agent to export an email to a text file

When you are running a background agent or a scheduled agent there is not UI, so you cannot use that.

Subject: RE: Lotus Script agent to export an email to a text file

I have changed the code to not use UI. However it is still not doing anything. I think that the problem may have something to do with selecting the appropriate documents. How do I select documents that have been found by an agent? I have tried the following and still no luck:

Public Sub saveFile

Dim doc As NotesDocument

Dim plainText As String

Dim fileNum As Integer

Dim document_list As NotesDocumentCollection

Dim db As NotesDatabase



Set db=session.currentdatabase

Set document_list = db.alldocuments



For i = 1 To document_list.Count

'go through all documents selected by agent export them

	Set doc = document_list.GetNthDocument(i)

’ Set uidoc = CurrentDocument

	plainText =	doc.FieldGetText( "Body" ) 

'get a free file

	fileNum = Freefile

	Open "x:\sas\jr\JREmail.csv" For Output As fileNum

’ write the formatted text to the file

	Print #fileNum, plainText

’ close the file

	Close #fileNum		

Next i

End Sub

Subject: RE: Lotus Script agent to export an email to a text file

Where do you create a new NotesSession object? Have a look at what your code does (and more importantly what it doesn’t) in the LS debugger.

Furthermore, the use of GetNthDocument is usually best avoided. Not sure if the influence on performance is as bad on NotesViewCollections as it is on NotesViews, but it’s not even worth to try.

Next, while you did comment out the reference to the NotesUIDocument, you are still using FieldGetText, which is a method of NotesUIDocument, but not of Notesdocument. Use GetItemValue instead (and look up the exact syntax in Designer help, if you are unsure on how to use it).

Opening and closing the file you write to on each iteration of the loop doesn’t look like a good idea to me either. If you are on Notes 6 or above (which I assume, as this is the Notes 6 and 7 forum), you might have a look at the NotesStream class which IMHO provides a much easier (and very fast) way to concatenate strings and write them to a file.

Good luck.

Subject: RE: Lotus Script agent to export an email to a text file

Thanks,

I took your advice and used the debugger, and after some changes i got this working. The agent now does exactly what i want when I right click on it and hit “run” in the design window. That is, it looks at new mail and exports new messages to a text file.

The problem now is with the trigger. I have tried setting up this agent to run on the event ‘after new mail has arrived’ and on a schedule. When I do this, the agent does not do anything. According to the log however, the agent runs as it was meant to. What could be causing this to happen when I introduce a trigger as opposed to manually running the agent?

thanks again,

JR

Subject: RE: Lotus Script agent to export an email to a text file

Let me first point out, that if you want only new documents to be exportet, you should not use .AllDocuments to build the collection , but rather .UnprocessedDocuments anyway.

The main difference is, that the triggered agent runs on the server, whereas the agent you run from designer runs on your local workstation. This has multiple implications:

First and foremost, the agent will try to access the server’s local file system (x:\sas\jr\JREmail.csv), not on your machine. Did you check if anything was written to that directory? Does it even exist? Is this even a Windows server? Does x happen to be a mapped network drive (which would worsen the matter)?

Next, you need proper execution rights to run the agent on the server at all. Is your ID allowed to run agents? File I/O is considered a “restricted operation” in LotusScript. For an agent that attempts to do file I/O to run, it must be set to runtime security level 2 (in the agent’s properties). But even that won’t help, if your name is not in the server document’s field, that allows you to run “unrestricted methods and operations” (Yes, that’s right: What is called a “restricted operation” in Designer, is called an “unrestricted operation” in the Admin client).

On Windows the Domino service usually runs under the local system authority. Even if there is a drive letter equivalent to x, the local system account cannot see it, if it is a mapped drive.

Lots of stuff to check, so good luck again.

Subject: RE: Lotus Script agent to export an email to a text file

Thanks.

Right - my issues are beginning to make sense. Running on server vs. local machine would explain what I am seeing. When I run manually the text file appears as expected. When the agent runs off the new mail trigger, no text file appears. Looking at the log after running the agent off the trigger it indicates that the agent ran, so it would seem i do have rights to run agents on the server.

If the above is true, then I think that I have 2 possible solutions:

  1. work out whether or not the server can see the location ‘x’ and use the address that the server can understand, or

  2. work out how to force the agent to run locally

Any ideas on how to acheive no. 2?

cheers

It might be helpful if I post the code as it is now as it has changed a lot from the original posting. For example I have used the UnprocessedDocuments collection.

Public Sub saveFile

Dim doc As NotesDocument

Dim plainTextCatcher As Variant

Dim fileNum As Integer

Dim documentList As NotesDocumentCollection

Dim session As New NotesSession

Dim db As NotesDatabase

Dim plainText As String



'Set db=session.CurrentDatabase

Set db=session.GetDatabase("CN=SYD01MS/OU=SYD/OU=Server/O=WLB","MAIL1\mp905946.nsf")

Set documentList = db.UnprocessedDocuments

Set agent = session.CurrentAgent



For i = 1 To documentList.Count

'go through all documents selected by agent export them

	Set doc = documentList.GetNthDocument(i)

	plainTextCatcher =	doc.getitemvalue( "Body" ) 

	plainText = plainTextCatcher(0)

		'get a free file

	fileNum = Freefile

	Open "x:\sas\EmailJobs\emailjob.csv" For Output As fileNum

		' write the formatted text to the file

	Print #fileNum, plainText

		' close the file

	Close #fileNum		

Next i

End Sub

Subject: RE: Lotus Script agent to export an email to a text file

Have you considered adding logging to the agent? Or any error handling at all?

Subject: RE: Lotus Script agent to export an email to a text file

No, I have not considered adding loging - primarily as I don’t know how to do this, can you help?

I’m clearly new to notes, previously using Outlook / VBA, where everything seemed much simpler…especially for a simple task like exporting some text! But hey maybe notes is for real programmers only!

Subject: RE: Lotus Script agent to export an email to a text file

Well, let’s start with this little tidbit: “Agent ran” does not mean “Agent ran without errors”, so you can’t assume that you have permission to create (or even read) a file on the server.

Even in VB (from which LotusScript is largely derived), one would generally not create production code without error checking. Macros for personal use are one thing, but if you are writing code for others to use you really need to address potential failures. Some you will be able to anticipate (like invalid data) and write around, some will cause your code to fail with no way to work around the problem – but you have to be able to tell the difference.

(And yes, it is true that most of the code posted here does not contain error checking. That’s not because we don’t use it, but because it often means as much or more code as the routine we are trying to describe. It is assumed that suggestions posted in response to questions will be adapted in a safe manner.)

The general form of checking for major errors (those that you wouldn’t be able to handle locally with an If…Then “guard statement”) looks like this:

Sub Initialize

On Error Goto errorHandler

.

. 'Active code goes here

.

getOut:

Exit Sub

errorHandler:

.

.'do something with the error

.

Resume getOut

End Sub

You can get pretty specific about the way you handle errors. (See Designer Help for the On Error statement.) The example above assumes a fatal error, one that leaves you no real option but to make a note of the problem and bail out. And the best way to make a note of the problem is to use the NotesLog class. That can log to a database (which must be based on the alog4.ntf template) or to the built-in agent log (right-click on the agent entry in the view of agents in Designer and click on Log to view). You would add this to your code to log to the built-in agent log:

Dim errorLog As NotesLog

Set errorLog = New NotesLog(db.Name + " - " + “AgentNameHere”)

Call errorLog.OpenAgentLog

That sets up the agent log. Then, in the errorhandler section of the code, you’d do something like this:

.

.

.

errorHandler:

Call errorLog.LogError(Err, Error & " at line " & Erl)

Resume getOut

End Sub

Again, see the Designer Help entries on the NotesLog class, the Err, Error and Erl functions for more info. LotusScript isn’t difficult, but don’t treat it as a toy either. If you are coding applications for other people to use, take it seriously.

Subject: RE: Lotus Script agent to export an email to a text file

Thanks for that. While your post is interesting and will be useful if I ever decide to release this application for other people to use, you have not actually answered my question.

I appreciate that you are trying to educate me but please do not patronise me. Understand for example that it is not obvious to someone who has never programmed in notes before that “Agent ran” does not mean “Agent ran without errors”.

I came to this forum looking for answers / help where I have been unable to find answers myself. If you could please try to answer my questions rather than tell me I don’t know how to produce production code for widespread distribution, that would be appreciated.

Subject: RE: Lotus Script agent to export an email to a text file

Adding logging will tell you what failed. I’m not suggesting it as an excercise – it’s the diagnostic you need to tell you what has gone wrong. I’m not trying to be patronising. You want answers, and I am giving you the information you need to find those answers. Logging will tell you what the error is – like missing permissions. (And typically, a LotusScript agent that runs on a server is the exclusive province of someone who has permissions reserved for those developing for the use of others. One might consider an administrator to be somewhat, well, insane to allow end-users to write and run LotusScript on a server.)

Subject: RE: Lotus Script agent to export an email to a text file

I’m surprised to hear that it is so much easier to write code to export text to a server’s local hard drive using VBA. Perhaps that’s what hackers should be using to bypass all those pesky security protocols that refuse to let just anyone write to the server’s file structure.

Subject: RE: Lotus Script agent to export an email to a text file

Maybe i wasn’t clear with my question. Maybe its not possible.I don’t want to perform any actions on the server, as I agree, being an end user it would be insane for me to do so.

I’m trying to get this to work on my local machine. My question is, is there a way that I could force this agent / script to run on my local machine.

cheers

Subject: RE: Lotus Script agent to export an email to a text file

There is an option in your client preferences to allow your workstation to run scheduled agents locally. However, I don’t believe an “After new mail” agent will run locally because the mail is not delivered to your local mail file – it’s delivered to the server replica, and arrives in your local mail file by replication rather than by mail routing.

You can write an agent to run “when documents are created or modified”, and set it to run locally. You would find these documents by the UnprocessedDocuments property. The agent must distinguish whether a document is new or modified, and whether it was sent to you or by you, by looking at the document’s field values and header information. You might want to set a field to mark documents as processed so that they do not get exported again if they are edited (assuming you don’t want to export them again in that case).

I’m a little unclear why you want to export all received mail to a text file, including all those messages that encourage you to visit their website to buy prescription drugs cheap, enhance your personal characteristics, or help them retrieve millions of dollars in return for a generous share. But I guess that’s up to you.

Subject: RE: Lotus Script agent to export an email to a text file

Thanks Andre, sounds like your suggestion will resolve my issue. I’ll give it a go today.

I will only be exporting emails when they meet with specific criteria i.e. sent by me, and have a particular subject line. I know how to do this part already though so I saw no point in adding additional code to my posting. Also all emails that reach my inbox need to get through a layer of security first that our mail administrators have set up - so far so good I don’t get any junk. On that point however, if you know of a more secure method of selecting emails (more secure than “from” tag and “subject” tag combination), then this would help.

Subject: Try this agent

Sub Initialize On Error Goto Errhandle

Dim s As New NotesSession

Dim db As NotesDatabase

Dim coll As NotesDocumentCollection

Dim doc As NotesDocument

Dim ws As New NotesUIWorkspace

Set db = s.CurrentDatabase

Set coll = db.UnprocessedDocuments

Dim frm As String

Dim nam As NotesName

Dim fileNum As Integer

Dim pathBase As String



pathBase=ws.Prompt (PROMPT_OKCANCELEDIT, "Path in which eMails  will be extracted", "Enter Path/Folder name(The Folder should exist) i.e. C:\Temp\", "C:\Temp\")

If Len(pathBase)<1 Then

	Exit Sub

End If



For i = 1 To coll.Count

	Set doc = coll.GetNthDocument( i )

	filenames=Evaluate("@AttachmentNames",doc)

	numberoffiles=Evaluate("@Attachments", doc)

					'To extract Lotus Notes user name

	Set nam=New Notesname(doc.GetItemValue("From")(0))					

	frm=nam.Common

	

	If Instr(frm,Chr(34)) Then 'Check for " in the name, specially in single word name

		frm=Mid(frm,2,Len(frm)-2)

	End If

				'To suppress duplicate folder

	temp=doc.PostedDate(0)

	datetime=Cstr(Day(temp))+Cstr(Month(temp))+Cstr(Year(temp))+Cstr(Hour(temp))+Cstr(Minute(temp))+Cstr(Second(temp))

	temp=fullpath					

	fullpath=pathBase+ frm+" "+datetime

	

	If Strcompare(fullpath,temp) Then

		Mkdir fullpath

	End If		

	

	If numberoffiles(0)>0 Then

		

		For filecounter=0 To numberoffiles(0)-1

			Print filenames(filecounter)

			Set object = doc.GetAttachment( filenames(filecounter) )

			

			If ( object.Type = EMBED_ATTACHMENT ) Then

				fileCount = fileCount + 1

				

				

				Call object.ExtractFile(fullpath & "\"& filenames(filecounter) ) '

				

			End If

			

		Next filecounter

		

	End If

	

	'Generate email text

	fileNum% = Freefile()

	Open fullpath & "\"& "eMail.txt" For Append As fileNum%

	Set rtitem = doc.GetFirstItem( "Body" )

	

	If ( rtitem.Type = RICHTEXT ) Then

		plainText = rtitem.GetFormattedText( False, 0 )

	End If

	

		' write the formatted text to the file

	Print #fileNum%, "From: "+ doc.From(0)

	Print #fileNum%, "Date: "  +Cstr(doc.PostedDate(0))

	Print #fileNum%,"Message: "+plainText

' close the file

	Close #fileNum

	

Next

Messagebox "Selected eMail(s) & attachments are been extracted in " & pathBase & " by NameDateTime folder format"

Exit Sub

Errhandle:

’ Use the Err function to return the error number and

’ the Error$ function to return the error message.

Messagebox "Error" & Str(Err) & ": " & Error$  & " on line " & Cstr(Erl)

Resume Next

Exit Sub

End Sub