Questions and discussion about using ProcessMaker: user interface, running cases & functionality
By cosyxu
#794768
Hi Everyone,


Does anybody know how to show or include an upload attachment in an email template ?
1.PNG
1.PNG (12.17 KiB) Viewed 4003 times
My process is: a requester submit a "web-entry"form which includes a upload control, and then manager will receive an email template which includes the upload file for him to download or view.

Any ideas how it works ?

Many thanks.

Yuan
User avatar
By amosbatto
#794789
Yuan, I found a solution, but it involves hacking the PM source code, because the sendMessage() web service doesn't support email attachments.

First, edit the file workflow/engine/methods/services/soap2.php with a plain text editor and change the sendMessage() function definition starting on line 448 to:
Code: Select all
function SendMessage ($params)
{
    $vsResult = isValidSession( $params->sessionId );

    if ($vsResult->status_code !== 0) {
        return $vsResult->getPayloadArray();
    }

    if (ifPermission( $params->sessionId, 'PM_CASES' ) == 0) {
        $result = new wsResponse( 2, G::LoadTranslation('ID_NOT_PRIVILEGES') );

        return $result->getPayloadArray();
    }

    $ws = new wsBase();
    
    //set optional variables:
    $aVariables   = isset($params->variables)   ? json_decode($params->variables, true)   : null;
    $aAttachments = isset($params->attachments) ? json_decode($params->attachments, true) : null;
    $bShowMessage = isset($params->showMessage) ? $params->showMessage                    : true;
    $delIndex     = isset($params->delIndex)    ? $params->delIndex                       : 0;
    $aConfig      = isset($params->config)      ? json_decode($params->config, true)      : array();
    
    $res = $ws->sendMessage( $params->caseId, $params->from, $params->to, $params->cc, $params->bcc, $params->subject, $params->template, 
        $aVariables, $aAttachments, $bShowMessage, $delIndex, $aConfig);
    
    return $res->getPayloadArray();
}
Then, edit the file workflow/engine/methods/services/wsdl2.php and change the definition of sendMessageRequest starting on line 501 to:
Code: Select all
      <xs:element name="sendMessageRequest">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="sessionId" type="xs:string"/>
            <xs:element name="caseId" type="xs:string"/>
            <xs:element name="from" type="xs:string"/>
            <xs:element name="to" type="xs:string"/>
            <xs:element name="cc" type="xs:string"/>
            <xs:element name="bcc" type="xs:string"/>
            <xs:element name="subject" type="xs:string"/>
            <xs:element name="template" type="xs:string"/>
            <xs:element name="variables" minOccurs="0" type="xs:string"/>
            <xs:element name="attachments" minOccurs="0" type="xs:string"/>
            <xs:element name="showMessage" minOccurs="0" type="xs:integer"/>
            <xs:element name="delIndex" minOccurs="0" type="xs:integer"/>
            <xs:element name="config" minOccurs="0" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
Then, add an email template to your process whose filename is "newCase". Here is an example:
emailTemplateEmailFromWebEntry.png
emailTemplateEmailFromWebEntry.png (40.17 KiB) Viewed 3985 times
Then, edit the <STARTING-EVENT-UID>Post.php file which was generated for your web entry.
It is located at this location on your PM server:
<INSTALL-DIRECTORY>/shared/sites/<WORKSPACE>/public/<PROCESS-UID>/<STARTING-EVENT-UID>Post.php
For example on my server:
/opt/pm3.2/shared/sites/workflow/public/739008884599dbeafc7c8b1091050959/852722968599dbedd1e7980062377595Post.php

Change lines 156-7 from:
Code: Select all
        $aMessage["MESSAGE"] = "<br />Case created in ProcessMaker<br />Case Number: $caseNr <br />Case Id: $caseId<br />Case derivated to: $assign";
    } else {
To:
Code: Select all
        $aMessage["MESSAGE"] = "<br />Case created in ProcessMaker<br />Case Number: $caseNr <br />Case Id: $caseId<br />Case derivated to: $assign";
        
        if ($result->status_code != 0){
			throw new Exception("Error routing to the first task in the case: ".$result->message);
		}
		
        $nextUserId = $result->routing->userId;
        
        G::LoadClass("pmFunctions");
        
        $aUser = userInfo($nextUserId);
        $emailTo = $aUser['mail'];
        $fullNameTo = $aUser['firstname'].' '.$aUser['lastname'];
        
        //set to same email as used in account at Config -> Email Servers:
        $emailFrom = 'amosbatto@gmail.com'; 
        
        //set to the ID of the Input Document uploaded in the web entry form
        $inpDocId = '243906473599dc51508c834093761947';
        
        //lookup information about the uploaded file in the database:
        $sql = "SELECT * FROM APP_DOCUMENT WHERE APP_UID='$caseId' AND DOC_UID='$inpDocId'";
        $dbResult = executeQuery($sql);
        if (!is_array($dbResult) or count($dbResult) == 0) {
			throw new Exception("Unable to find uploaded file in the database with query:\n$sql");
        }
        
        $fileId   = $dbResult[1]['APP_DOC_UID'];
        $version  = $dbResult[1]['DOC_VERSION'];
        $filename = $dbResult[1]['APP_DOC_FILENAME'];
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        $path = PATH_DOCUMENT. G::getPathFromUID($caseId) .PATH_SEP. $fileId .'_'. $version .'.'. $ext;
        $aAttachments = array($path);
        
        $fileLink = (G::is_https() ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] .
           ($_SERVER['SERVER_PORT'] == 80 ? '' : ':'.$_SERVER['SERVER_PORT']) . 
           '/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.'/cases/cases_ShowDocument?a='. $fileId .'&v='. $version;
        $aVars = array('productLink' => $fileLink);
        
        global $sessionId;
		global $client;
		
        $aParams = array (
           'sessionId'  => $sessionId,
           'caseId'     => $caseId,
           'from'       => $emailFrom,
           'to'         => $emailTo,
           'cc'         => '',
           'bcc'        => '',
           'subject'    => "New case #$caseNr",
           'template'   => 'newCase.html',
           'variables'  => json_encode($aVars),
           'attachments'=> json_encode($aAttachments)
        );
        $msgResult = $client->__SoapCall('sendMessage', array($aParams)); 
        
        if ($msgResult->status_code != 0) {
			throw new Exception("Error sending email: " . $msgResult->message);
		}        
    } else {
You will need to change $emailFrom and $inpDocId to match your system. This example shows how to set the variable "productLink" to display a link to the attached file, plus add it as an attached file to the email.

Note that your web entry form should only use File controls and not Multiple File controls, which currently don't work with web entry.

When the web entry form is submitted, you should receive an email like this:
EmailAttachmentFromWebEntry.png
EmailAttachmentFromWebEntry.png (37.14 KiB) Viewed 3985 times
Here is the sample process that I used to test this in PM 3.2:
(37.98 KiB) Downloaded 322 times
By cosyxu
#794830
Good morning Amosbatto,

Thank you for your detailed solution, it's really helpful.
:D

Yuan
By cosyxu
#812438
amosbatto wrote:Yuan, I found a solution, but it involves hacking the PM source code, because the sendMessage() web service doesn't support email attachments.

First, edit the file workflow/engine/methods/services/soap2.php with a plain text editor and change the sendMessage() function definition starting on line 448 to:
Code: Select all
function SendMessage ($params)
{
    $vsResult = isValidSession( $params->sessionId );

    if ($vsResult->status_code !== 0) {
        return $vsResult->getPayloadArray();
    }

    if (ifPermission( $params->sessionId, 'PM_CASES' ) == 0) {
        $result = new wsResponse( 2, G::LoadTranslation('ID_NOT_PRIVILEGES') );

        return $result->getPayloadArray();
    }

    $ws = new wsBase();
    
    //set optional variables:
    $aVariables   = isset($params->variables)   ? json_decode($params->variables, true)   : null;
    $aAttachments = isset($params->attachments) ? json_decode($params->attachments, true) : null;
    $bShowMessage = isset($params->showMessage) ? $params->showMessage                    : true;
    $delIndex     = isset($params->delIndex)    ? $params->delIndex                       : 0;
    $aConfig      = isset($params->config)      ? json_decode($params->config, true)      : array();
    
    $res = $ws->sendMessage( $params->caseId, $params->from, $params->to, $params->cc, $params->bcc, $params->subject, $params->template, 
        $aVariables, $aAttachments, $bShowMessage, $delIndex, $aConfig);
    
    return $res->getPayloadArray();
}
Then, edit the file workflow/engine/methods/services/wsdl2.php and change the definition of sendMessageRequest starting on line 501 to:
Code: Select all
      <xs:element name="sendMessageRequest">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="sessionId" type="xs:string"/>
            <xs:element name="caseId" type="xs:string"/>
            <xs:element name="from" type="xs:string"/>
            <xs:element name="to" type="xs:string"/>
            <xs:element name="cc" type="xs:string"/>
            <xs:element name="bcc" type="xs:string"/>
            <xs:element name="subject" type="xs:string"/>
            <xs:element name="template" type="xs:string"/>
            <xs:element name="variables" minOccurs="0" type="xs:string"/>
            <xs:element name="attachments" minOccurs="0" type="xs:string"/>
            <xs:element name="showMessage" minOccurs="0" type="xs:integer"/>
            <xs:element name="delIndex" minOccurs="0" type="xs:integer"/>
            <xs:element name="config" minOccurs="0" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
Then, add an email template to your process whose filename is "newCase". Here is an example:
emailTemplateEmailFromWebEntry.png
Then, edit the <STARTING-EVENT-UID>Post.php file which was generated for your web entry.
It is located at this location on your PM server:
<INSTALL-DIRECTORY>/shared/sites/<WORKSPACE>/public/<PROCESS-UID>/<STARTING-EVENT-UID>Post.php
For example on my server:
/opt/pm3.2/shared/sites/workflow/public/739008884599dbeafc7c8b1091050959/852722968599dbedd1e7980062377595Post.php

Change lines 156-7 from:
Code: Select all
        $aMessage["MESSAGE"] = "<br />Case created in ProcessMaker<br />Case Number: $caseNr <br />Case Id: $caseId<br />Case derivated to: $assign";
    } else {
To:
Code: Select all
        $aMessage["MESSAGE"] = "<br />Case created in ProcessMaker<br />Case Number: $caseNr <br />Case Id: $caseId<br />Case derivated to: $assign";
        
        if ($result->status_code != 0){
			throw new Exception("Error routing to the first task in the case: ".$result->message);
		}
		
        $nextUserId = $result->routing->userId;
        
        G::LoadClass("pmFunctions");
        
        $aUser = userInfo($nextUserId);
        $emailTo = $aUser['mail'];
        $fullNameTo = $aUser['firstname'].' '.$aUser['lastname'];
        
        //set to same email as used in account at Config -> Email Servers:
        $emailFrom = 'amosbatto@gmail.com'; 
        
        //set to the ID of the Input Document uploaded in the web entry form
        $inpDocId = '243906473599dc51508c834093761947';
        
        //lookup information about the uploaded file in the database:
        $sql = "SELECT * FROM APP_DOCUMENT WHERE APP_UID='$caseId' AND DOC_UID='$inpDocId'";
        $dbResult = executeQuery($sql);
        if (!is_array($dbResult) or count($dbResult) == 0) {
			throw new Exception("Unable to find uploaded file in the database with query:\n$sql");
        }
        
        $fileId   = $dbResult[1]['APP_DOC_UID'];
        $version  = $dbResult[1]['DOC_VERSION'];
        $filename = $dbResult[1]['APP_DOC_FILENAME'];
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        $path = PATH_DOCUMENT. G::getPathFromUID($caseId) .PATH_SEP. $fileId .'_'. $version .'.'. $ext;
        $aAttachments = array($path);
        
        $fileLink = (G::is_https() ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] .
           ($_SERVER['SERVER_PORT'] == 80 ? '' : ':'.$_SERVER['SERVER_PORT']) . 
           '/sys'.SYS_SYS.'/'.SYS_LANG.'/'.SYS_SKIN.'/cases/cases_ShowDocument?a='. $fileId .'&v='. $version;
        $aVars = array('productLink' => $fileLink);
        
        global $sessionId;
		global $client;
		
        $aParams = array (
           'sessionId'  => $sessionId,
           'caseId'     => $caseId,
           'from'       => $emailFrom,
           'to'         => $emailTo,
           'cc'         => '',
           'bcc'        => '',
           'subject'    => "New case #$caseNr",
           'template'   => 'newCase.html',
           'variables'  => json_encode($aVars),
           'attachments'=> json_encode($aAttachments)
        );
        $msgResult = $client->__SoapCall('sendMessage', array($aParams)); 
        
        if ($msgResult->status_code != 0) {
			throw new Exception("Error sending email: " . $msgResult->message);
		}        
    } else {
You will need to change $emailFrom and $inpDocId to match your system. This example shows how to set the variable "productLink" to display a link to the attached file, plus add it as an attached file to the email.

Note that your web entry form should only use File controls and not Multiple File controls, which currently don't work with web entry.

When the web entry form is submitted, you should receive an email like this:
EmailAttachmentFromWebEntry.png
Here is the sample process that I used to test this in PM 3.2:
Email_file_from_web_entry-3.pmx
Hi Amosbatto,

I was wondering whether there is any updated method to achieve this?

If I start by submitting a web-entry Dynaform, it send to the manager an email which contains a link(Link to a form), in this case, could the attachments in the "web-entry Dynaform" display at the "manager Dynaform"?

If it doesn't, could you please advise how can I add links of attachment in the "manager Dynaform" ? (I have to use ABE function)

http://wiki.processmaker.com/3.0/File_c ... _file_info would this possible?

Many thanks,
Yuan

Hello. For rental housing, there are software solu[…]

Experience heightened pleasure with Cenforce 100 M[…]

Get an instant solution to move emails to MBOX for[…]

Most Demanding OST to PST Converter

The most demanding OST to PST Converter is TrijaT[…]