4.5.6.1 Email Processing

Origin8.5 provides a mail object to process emails using LabTalk script. The following script example shows how to get new emails from the mail server and analyze data from the email's attachment at regular intervals automatically in Origin.

In Addition, the following LabTalk features are demonstrated:

  • Use of functions and passing argument by reference to get more then one values back from a function, see ProcessEmail function
  • LabTalk timer
  • Using Analysis Template to encapurate complicated processing to simplify script
  • ASCII import, string processing and graph export

Script File

You can save the following into a file called emailserver.ogs in the UFF folder:

[Main]
////////////////////////////////////////////////////////////////////////
// define functions
////////////////////////////////////////////////////////////////////////

@global=1; // to ensure all functions defined in this section will become global

Function Init_Server(string strPOPServer, string strName, string strPassword, string strSMTPServer)
{
   // Setup omail dll
   // ********** NO SUPPORT FOR SSL, SO SERVERS LIKE GMAIL CANNOT BE USED **********
  dll -a mail omail; //Create an '''mail''' object mail. 
  mail.POP.Server$ = strPOPServer$; // Incoming mail server
  mail.POP.UserName$ = strName$; // email server user name/account
  mail.POP.Password$ = strPassword$; // email server password
  mail.POP.Path$ = "C:\OriginMails"; // Path to save emails in the local computer
  mail.POP.Port = 110; // Incoming server port
  mail.POP.Timeout = 20; //Incoming server timeouts
 
  mail.SMTP.Server$ = strSMTPServer$; // Outgoing mail server
  mail.SMTP.From$ = strName$; // The sender's email address
  mail.SMTP.Timeout= 10; // The connection timeout in seconds
}

//The following function will analyze data from the email's attachment. 
//It performs Linear Fit using an Analysis Template.
//returns number of mails on server, including the one being read and processed
// if successfully process one email, 0 if no mail on server or not the right subject, <0 if error occurs
//status bar will be updated after each call to indicate number of emails on server
//Function int ProcessEmail(ref int nSuccess, string strSubject$ = "Origin LRFit Test" )
Function int ProcessEmail(ref int nSuccess, string strSubject)
{
	nSuccess = 0;
	mail.POP.LeaveMessage = 0; // do not leave emails on the Server, you may change this to 0 during testing
	int nMailsLeft = mail.POP.Retrieve();
	if( nMailsLeft < 0 )
	{
		return -1;
	}
	if(nMailsLeft == 0)
		return 0;
	
        string strTrim = mail.POP.Subject$;
	strTrim.TrimLeft(); //Trim SPACE on the left

	//if( mail.POP.Subject$ != strSubject$ )
        if( strTrim$ != strSubject$ )
		return nMailsLeft;

	// Load Origin's analysis Template
	string fname$ = SYSTEM.PATH.PROGRAM$ + "Samples\Curve Fitting\Linear Regression.OGW";
	doc -a %(fname$); //load ogw template as active window
	// Read some text from the email body to use as our page Long Name
	page.LongName$ = mail.POP.Text1$; //For Plain Text's email.
	page.title = 1;
	// Now import the attached data file into our analysis template's Data Sheet
	page.active$ = Data;
	//import the attached ASCII file and rename the book with the file's name
	//impasc fname:=mail.POP.Attachment1$ Options.Names.FNameToBk:=0;
        impasc fname:=mail.POP.Attachment1$;
        
        //Wait for automatic update to complete
	run -p au;

	// Activate Origin's custom report sheet
	page.active$ = "Fit Summary";
	// done with the attached file, so we can delete it
	mail.POP.DeleteAttachments(1);
	nSuccess = 1;
	return nMailsLeft;
}

//Reply the email if email's Subject agrees with the string.
//The email contains the fitted info and attaches the fitted curve.
Function int Reply_Email()
{
	string strTo = mail.POP.Sender$;
	//strTo.TrimLeft(); //Needn't trim
        mail.SMTP.To$ = strTo$;
	mail.SMTP.Subject$ = "Re:" + mail.POP.Subject$;
		
	mail.SMTP.Text$ #= empty$;
	mail.SMTP.Text1$ = "LR Fitted Results in Origin:";	
	mail.SMTP.Text2$ = "--------------------";
	
	//Get number of rows from the worksheet of data
	page.active = 2;
	mail.SMTP.Text3$ = "Number of Points = $(wks.col1.nrows)";
	mail.SMTP.Text4$ = "";
	
	//Get fitted results from Linear Fit Report
	page.active$="FitLinear1";
	getresults tr:=tree;
	mail.SMTP.Text5$ = "Intercept of Fitted Line:";
	mail.SMTP.Text6$ = "Value = $(tree.Parameters.Intercept.Value,*), Standard Error = $(tree.Parameters.Intercept.Error,*)";
	mail.SMTP.Text7$ = "";
	
	mail.SMTP.Text8$ = "Slope of Fitted Line:";
	mail.SMTP.Text9$ = "Value = $(tree.Parameters.Slope.Value,*), Standard Error = $(tree.Parameters.Slope.Error,*)";
	mail.SMTP.Text10$ = "";
	
	mail.SMTP.Text11$ = "R Value of Linear Fit: $(sqrt(tree.RegStats.C1.RsqCOD), *)";
	mail.SMTP.Text12$ = "----------------------";
	
	//Export the fitted curve
	expGraph type:=jpg path:=mail.POP.Path$ export:=specified pages:="FitLine" 
	  filename:=page.longname$;
	mail.SMTP.Attachment$ #= empty$;   // to empty the vector
	//Attach the fitted curve image
	mail.SMTP.Attachment1$ = mail.POP.Path$ + "\" + page.longname$+".jpg";
	
	page.active$="Fit Summary";
	
	if ( mail.SMTP.Send( ) )
		return 0; //Sending email failed.
        else
		return 1; //Sending email is successful.
}
// this is the function to call during timer proc, it will kill the timer on error
Function doTimerProc()
{
	int nOK;
	//int nn = ProcessEmail(nOK);
        //Subject string will be prefixed with space.
        int nn = ProcessEmail(nOK, "Origin LRFit Test");
	if(nn < 0)
	{
		ty -A "Mail Error return $(nn). Please resolve.";
		timer -k;
	}
	// update status bar
	else if(nn==0)
		type -q "$(@D,D10):No mail on server";
	else 
	{
		if(nOK == 1)
                {
			type -q "$(@D,D10):Successfully process one mail, $(nn-1) emails left";
                	int nSend = Reply_Email();
			if( nSend == 0 )
				ty -A "Replying the email(%(mail.SMTP.To$)) failed."; 
                }
		else
			type -q "$(@D,D10):Ignore one mail due to wrong subject, $(nn-1) emails left";
	}
}

////////////////////////////////////////////////////////////////////////
// start the process
////////////////////////////////////////////////////////////////////////

def timerproc {
	doTimerProc();
}
// replce with your own POP server and SMTP server, we have provided origin@originlab.com for this demo only
Init_Server("igor.originlab.com", "origin", "labtalk", "igor.originlab.com");
//Init_Server("igor", "origin", "labtalk", "igor");for inside Olab

timer 20; // Check every 20 seconds (20 seconds)
timerproc;// run it immediately now so we don't wait for timer later in case there is an error so can kill right away

To Run Sample

Before running the example, you should send an email to the account with the subject "Origin LRFit Test" and an attachment of ASCII file of data with two columns of numeric values separated by TABs. And you should also create a folder "C:\OriginMails" for the path of incoming emails.

Note that in this example it doesn't leave emails in the server.

If you have saved the code into an ogs file, you just run it by:

run.section(%Yemailserver, main);

Stop the timer

To stop the timer and prevent further timerproc macro execution, run the following script.

timer -k; //Stop the timer process

Please note that you can undefine the mail object with the following, but it is necessary unless you need to use the LabTalk mail command for something else in the same Origin session.

dll -r mail; //Remove the omail object and unload dll.