Skip Navigation LinksALVAO 10.1ALVAO Service DeskSystem Implementation in an OrganizationCustom Edits and ExtensionsCustom Program ExtensionsAutomatic Actions Triggered by Event on Request Skip Navigation Links. Skip Navigation Links Skip Navigation Links.


Automatic Actions Triggered by Event on Request

Automatic actions can be started in the following cases:

  • Request item value change (custom/system)
  • Creating a new request
  • Creating a new event
  • Editing an event
  • Deleting an event
  • Loading a new message from the service mailbox

For automatic actions to work you have to enable the Custom program extensions.

Warning:
The ALVAO database can be permanently damaged if an automatic action is defined incorrectly; therefore, always use a copy of the database in the test environment to perform creation and testing.
Tip:
Creation of a working automatic action requires good knowledge of the ALVAO database and the Service Desk WebService interface.

Preparation of new automatic action

In the folder where ALVAO Service Desk WebService is installed, copy the CodeExtension_Template.cs file in the App_Code folder and rename it according to the functionality performed by the action.

In the newly created file, enter a definition of the new automatic action into the bordered code block by implementing the ITicketAutoAction or IActAutoAction interface and set the value for the name property (name of the automatic action) in the command class constructor.

Example

Class definition:


class AssignToTester : ITicketAutoAction
{
    public string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public AssignToTester()
    {
        name = "Resolved in Version – Assign to test";
    }

    string sectionName = "Program edits"; // The name of the service the request must be in so that it can be assigned to testers (e.g. Actions performed when the request item is changed)
    string stateName = "Implementation"; // The name of the status the request must be in so that it can be assigned to testers (e.g. Actions performed when the request item is changed)

    string sectionName2 = "Program edits"; // The name of the service in which a new request is created (e.g. Actions performed when a new request is created)
    string sectionNameForCreate = "Program edits/Proposals and analyses"; // The name of the service for which a request for suggestion for the new request is to be created (e.g. Actions performed when a new request is created)

}

Defining the conditions and executed operations for automatic action

Warning:
If you only want to use some of the methods of the implemented interface within the automatic action, return the NotImplementedException exception in the body of other methods of the interface. For example:

public void OnTicketChanged(SqlConnection con, SqlTransaction trans, int ticketId, int personId, string properties)
{
    throw new NotImplementedException();
}

Actions performed when the request item is changed

Automatic actions can be executed when the following items are changed:

table.column Request item
tHdTicket.sHdTicketStateNotice Status
tHdTicket.liHdTicketSlaId SLA
tHdTicket.dHdTicketDeadline Due Date
tHdTicket.liHdTicketHdSectionId Service
tHdTicket.iHdTicketUser Requester
tHdTicket.liHdTicketSolverPersonId Solver
tHdTicket.sHdTicket Request name
tHdTicket.liHdTicketPriorityId Priority
tHdTicket.Impact Impact
tHdTicket.Urgency Urgency
tHdTicket.mHdTicketNotice Notes
tHdTicket.sHdTicketCategory Category
tHdTicket.sHdTicketGroup Group
tHdTicket.dHdTicketUserDeadline Requested due date
tHdTicket.sHdTicketDeviceCode Device number
tHdTicket.liHdTicketNodeId Device
tHdTicket.FeedbackSolveSpeed Resolution speed
tHdTicket.FeedbackProfessionality Professionalism
tHdTicket.FeedbackExpertise Expertise
tHdTicket.FeedbackComment Comments and notes
tHdTicket.RelatedAccountId Related organizations
tHdTicketCust.* Custom Items

In the created action class, implement the ITicketAutoAction interface and its method OnTicketChanged. The input parameters are the following:

  • ticketId (request number)
  • personId (id of the person who performed the event on the request) – In some cases, it might have been the system, if so, the value is NULL
  • properties (changed request items separated by comma – table.column)

In the implemented method, define both the conditions for executing the operations, and the request operations themselves.

Example of an automatic action executed when a request item is changed:

Assigning the request to a solver from the Testers group if the request is in the Program edits service and its status is Implementation.


class AssignToTester : ITicketAutoAction
{

    public void OnTicketChanged(SqlConnection con, SqlTransaction trans, int ticketId, int personId, string properties)
    {
        if (properties.Contains("tHdTicketCust.solvedInVersion"))
        {
            try
            {
                HelpdeskWebService sdws = new HelpdeskWebService();

                // loading values
                string solvedInVersion = sdws.ReadColumn(ticketId, "tHdTicketCust", "solvedInVersion");
                string section = sdws.ReadColumn(ticketId, "TicketForeignKeyInfo", "SectionName");
                string state = sdws.ReadColumn(ticketId, "tHdTicket", "sHdTicketStateNotice");

                // checking values
                if (!String.IsNullOrEmpty(solvedInVersion) && section == sectionName && state == stateName)
                {
                    // loading data
                    using (SqlCommand Cmd = new SqlCommand(@"SELECT TOP 1 TRP.liRolePersonPersonId newSolverId
                    FROM tRolePerson TRP JOIN tRole TR ON TRP.liRolePersonRoleId=TR.iRoleId WHERE TR.sRole = N'Testers'", con, trans))
                    {
                        using(SqlDataReader reader = Cmd.ExecuteReader())
                        {
                            int newSolverId; // new request solver id

                            if (reader.Read())
                            {
                                newSolverId = int.Parse((reader["newSolverId"]).ToString());

                                // assigning to solver
                                sdws.AssignToSolver(ticketId, newSolverId);
                            }
                            reader.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

}

The whole example can be downloaded here.

To run the example, you must add the solvedInVersion custom item of the nvarchar type to the tHdTicketCust table.

Actions performed when a new request is created

In the created automatic action class, implement the ITicketAutoAction interface and its method OnTicketCreated. The input parameters are the following:

  • ticketId (request number)
  • personId (id of the person who created the request – sometimes can be other than the requester).

Example of an automatic action executed when a new request is created:

When a new request is created in the Program edits service, a new linked request will be created in the Program edits/Proposals and analyses service to create a suggestion for the new request.


class AssignToTester : ITicketAutoAction
{

    public void OnTicketCreated(SqlConnection con, SqlTransaction trans, int ticketId, int personId)
    {
        try
        {
            HelpdeskWebService sdws = new HelpdeskWebService();

            // loading values
            bool createAnalysis;
            if ((sdws.ReadColumn(ticketId, "tHdTicketCust", "createAnalysis")) != null)
                createAnalysis = bool.Parse(sdws.ReadColumn(ticketId, "tHdTicketCust", "createAnalysis"));
            else
                createAnalysis = false;
            string section = sdws.ReadColumn(ticketId, "TicketForeignKeyInfo", "SectionName");
            string name = sdws.ReadColumn(ticketId, "tHdTicket", "sHdTicket");

            // checking values
            if (section == sectionName2 && createAnalysis)
            {
                // creating the request to form a suggestion
                int newTicket = sdws.CreateTicket(personId, personId, null, null, sectionNameForCreate, null, name + " - suggestion", null, null, null, null, null,
                                                   DateTime.Now.ToUniversalTime(), DateTime.Now.ToUniversalTime(), 7);

                // creating link
                using(SqlCommand Cmd = new SqlCommand(@"INSERT INTO TicketRelation (BeginHdTicketId, EndHdTicketId, TicketRelationTypeId)
                VALUES (@rootTicket, @newTicket, 2)", con, trans))
                {
                    Cmd.Parameters.Add("@rootTicket", SqlDbType.Int).Value = ticketId;
                    Cmd.Parameters.Add("@newTicket", SqlDbType.Int).Value = newTicket;
                    Cmd.ExecuteNonQuery();
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

}

The whole example can be downloaded here.

To run the example, you must add the solvedInVersion custom item of the nvarchar type to the tHdTicketCust table.

Actions performed when an event is created

Automatic actions can be executed in the following situations:
  • Manual creation of an event using the New event or New note command in SD Console or WebApp.
  • Sending a message using the commands Send message, Reply, etc. in the SD Console or WebApp.
  • Loading an e-mail from the service mailbox using MailboxReader.
  • Loading a message manually using the Load messages from MS Outlook command in the SD Console.
  • Loading a message manually using the Save to request log in Outlook Add-in.
  • Creating a creation event for a new request.
  • By calling the web method CreateAct or CreateTicket, where the creating message is created.

In the created automatic action class, implement the IActAutoAction interface and its method OnActCreated. The input parameters are the following:

  • actId (event id),
  • personId (id of the person who created the event).

Example of an automatic action executed when an event is created:

When an event is created in the Program edits service, the event will be sent via e-mail to all managers of the service who are not authors or recipients of the event.


class SendMailsAboutNewEvent : IActAutoAction
{
   public string name;

   public string Name
   {
       get { return name; }
       set { name = value; }
   }

   public SendMailsAboutNewEvent()
   {
       name = "New event – send e-mails";
   }

   string section = "Program edits"; // The name of the service based on whose request the event will be created

   public void OnActChanged(SqlConnection con, SqlTransaction trans, int ticketId, int personId, string properties) {
       throw new NotImplementedException();
   }
   public void OnActRemoved(SqlConnection con, SqlTransaction trans, int ticketId, int personId) {
       throw new NotImplementedException();
   }

   public void OnActCreated(SqlConnection con, SqlTransaction trans, int actId, int personId)
   {
       try
       {
           HelpdeskWebService sdws = new HelpdeskWebService();

           // loading values
           int ticketId = 0, fromPersonId = 0;
           string actFrom = "", actFromEmail = "", actTo = "", actToEmail = "", actSubject = "", actPlainText = "";
           using (SqlCommand Cmd = new SqlCommand(@"SELECT liActHdTicketId, liActFromPersonId, sActFrom, sActFromEmail,
           sActTo, sActToEmail, sAct, mActNotice FROM tAct WHERE iActId = @actId", con, trans))
           {
               Cmd.Parameters.Add("@actId", SqlDbType.Int).Value = actId;
               using (SqlDataReader reader = Cmd.ExecuteReader())
               {
                   if (reader.Read())
                   {
                       ticketId = int.Parse((reader["liActHdTicketId"]).ToString());
                       fromPersonId = int.Parse((reader["liActFromPersonId"]).ToString());
                       actFrom = (reader["sActFrom"]).ToString();
                       actFromEmail = (reader["sActFromEmail"]).ToString();
                       actTo = (reader["sActTo"]).ToString();
                       actToEmail = (reader["sActToEmail"]).ToString();
                       actSubject = (reader["sAct"]).ToString();
                       actPlainText = "Hello,\n\n an event has been created for request number " + ticketId.ToString() + ":\n\n" + (reader["mActNotice"]).ToString();
                   }
                   reader.Close();
               }
           }
           string sectionName = sdws.ReadColumn(ticketId, "TicketForeignKeyInfo", "SectionName");

           // checking values
           if (sectionName == section)
           {
               // loading data
               int sectionId = int.Parse(sdws.ReadColumn(ticketId, "tHdTicket", "liHdTicketHdSectionId"));
               string sectionEmail = sdws.ReadColumn(sectionId, "tHdSection", "sHdSectionEmail");

               List<string> recipients = new List<string>();
               using (SqlCommand Cmd = new SqlCommand(@"select sPersonEmail from vHdSectionManager
               left join tPerson on iPersonId = liHdSectionManagerPersonId
               where sPersonEmail is not null and liHdSectionManagerHdSectionId = @sectionId", con, trans))
               {
                   Cmd.Parameters.Add("@sectionId", SqlDbType.Int).Value = sectionId;
                   using (SqlDataReader reader = Cmd.ExecuteReader())
                   {
                       string personEmail = "";
                       while (reader.Read())
                       {
                           personEmail = (reader["sPersonEmail"]).ToString();
                           if (!actTo.Contains(personEmail) && !actToEmail.Contains(personEmail) && !actFrom.Contains(personEmail) && !actFromEmail.Contains(personEmail))
                               recipients.Add(personEmail);
                       }
                       reader.Close();
                   }
               }

               //sending e-mail
               if (recipients.Count > 0)
                   sdws.SendMail(ticketId, sectionEmail, recipients, null, actSubject, actPlainText, false, false, con, trans);
           }
       }
       catch (Exception ex)
       {
           throw ex;
       }
   }
}

The whole example can be downloaded here.

Actions performed when an event is edited

Automatic actions can be executed when the following items are changed:

table.column Event item
tAct.dAct Date
tAct.liActKindId To
tAct.sActTo Date
tAct.sAct Subject
tAct.mActNotice Text
tDocument.liDocumentActId Attachments
tActHd.bActHdUserRead Show to requester
tAct.bWaitingForUser Waiting for Requester
tAct.nActWorkHours Work
tAct.nActTravelHours Time spent on trip
tAct.nActTravelKm Distance
tAct.bNoCharge Do not invoice/td>

In the created automatic action class, implement the IActAutoAction interface and its method OnActChanged. The input parameters are the following:

  • actId (event id),
  • personId (id of the person who changed the event),
  • properties (changed event items separated by commas – table.column).

Actions performed when an event is deleted

Automatic actions can be executed when deleting all messages and events.

In the created automatic action class, implement the IActAutoAction interface and its method OnActRemoved. The input parameters are the following:

  • actId (event id),
  • personId (id of the person who deleted the event).

Actions executed when a message is loaded

When a message is loaded from the service mailbox, automatic actions can be executed before the message is saved in an existing request log or before a new request is created.

In the automatic action's class you have created, implement the IMailMessageAutoAction interface and its method OnMessageReceived. The input parameters are the following:

  • message (the message object),
  • sectionId (id of the service in which the message was loaded),
  • ticketId (id of the request the message belongs to based on its subject; or zero, if a new request is created),
  • fromPersonId (id of the message sender or of the Host account if the message sender wasn't found).
Return true or false from the OnMessageReceived method to specify whether the message is intended for standard processing or not.

If multiple automatic actions are implemented, they will be called one by one until one of them returns false. The order in which they are called is not guaranteed.

Note:
If a message is not further processed after automatic actions, a warning will be recorded in the event log.

Example of an automatic action executed when a message is loaded:

When a message related to an existing request is loaded, the message body is checked whether it contains the "ASSIGNTO: solver name" command. If it contains the command and the solver is found by his/her name, the request will be automatically assigned to him/her and the message will not be recorded in the request log. Otherwise, the message will be processed in the standard way.

……
public class AssignToSolverByEmail : IMailMessageAutoAction
{
   public string name;

   public string Name
   {
       get { return name; }
       set { name = value; }
   }

   public AssignToSolverByEmail()
   {
       name = "Assigning to solver by e-mail";
   }

   public bool OnMessageReceived(SqlConnection con, SqlTransaction trans, Rebex.Mail.MailMessage message, int sectonId, int ticketId, int fromPersonId)
   {
       if (ticketId == 0)
           return true;

       if(message.BodyText != null)
       {
           int startIndex = message.BodyText.IndexOf("ASSIGNTO:");
           if(startIndex >= 0)
           {
               int length = message.BodyText.IndexOf("\n", startIndex) - (startIndex + 9);
               string user = message.BodyText.Substring(startIndex + 9, length).Trim();
               using (SqlCommand Cmd = new SqlCommand(@"exec spPersonSearch @sample, NULL, 0, NULL, '', 1", con, trans))
               {
                   Cmd.Parameters.Add("@sample", SqlDbType.NVarChar).Value = user;
                   using (SqlDataReader reader = Cmd.ExecuteReader())
                   {
                       if (reader.Read())
                       {
                           HelpdeskWebService sdws = new HelpdeskWebService();
                           int solverId = int.Parse((reader["PersonId"]).ToString());
                           sdws.AssignTicketToSolver(ticketId, solverId, fromPersonId, string.Empty, null, true);
                           return false;
                       }
                   }
               }
           }
       }
       return true;
   }
}

The whole example can be downloaded here.

Sending a message within the automatic action

If you need to send any message within the automatic action, use the SendMail method with the parameters described below. The message sent can also be written into the request log automatically.

Description of parameters of the SendMail method.

Parameter Data Type Description Required
ticketId int ID of the request for which the record is to be created. Yes
from string Sender e-mail. If not filled in, the sender is the service. No
recipients string[] Field for message recipients. Yes
cc string[] Field for message copy recipients. No
subject string Subject of the message. If not filled in, the request tag and name will be used. No
body string Message (can be in the HTML format). Yes
createAct bool Create event in the request log. Yes
notification bool The event created in the request log will have the Notification kind. Yes
connection SqlConnection Database connection. Yes
transaction SqlTransaction Database transaction in progress. No
priority int Number representing the message's priority in the queue for sending. The default value is 10000. For details, see the description of the Priority column in the MailMessage table. No
Note:
The method can be used also for the custom commands.
Tip:
You can use the following function to compose the HTML message: string HtmlNotificationBody(string htmlBody) which envelopes the htmlBody with standard envelope.
Tip:
The whole e-mail can be also composed individually using the MailMessage object and then using the overloaded method:
public int SendMail(MailMessage msg, int ticketId, bool createAct, bool notification, SqlConnection connection, SqlTransaction transaction, int priority);
In this way, you can send a message containing attachments and even images in the message body. /div>

Release value

  • ID of the created event if the e-mail has been sent successfully and the event has been created.
  • 0 if the e-mail has been sent successfully, but the event has not been created.
  • -1 if the e-mail has not been sent, e.g. due to incorrectly set SMTP server.
  • Any exception, as they aren't detected or processed in the method body.

 

Did not find what you were looking for? Ask our technical support team.