Skip to Content
Author's profile photo Hiroyuki Otaki

NetWeaver BPM 7.20: Enhanced task notification

Overview

In some cases, people like e-mail and prefer to see much information in it. However, NetWeaver BPM7.2 cannot permit editing content of task notification mail sent by Human Activity. Also it is not easy to send a task execution URL by Notification Activity.

I made a trick to send modifiable task notification e-mail with task launcher URL. End users can see their own task screen when they just click a URL in e-mail. I will explain how to do it.
image

Process

First, I created a very simple sample process like below.
image

In this process, a task identification key is generated from current date and time at Start event. It is sent to end user as a part of task launcher URL.

 

Notification Activity

Here is detail of Notification Activity. Body of its message contains task launcher URL. Note that, task identification key is sent as a parameter of URL. Hence launcher can find actual task instance from Universal Work List (UWL).
image

Human Activity

Task identification key also have to be passed to Human Activity. Make sure your Input Mapping is valid.
image

Then task is prepared to have a key in its texts. In this sample, key is set at the tail of description.
image

 

Task Launcher

Next, I created a WebDynpro component and implemented task launcher. There is two important methods, findTask and launchTask. Thanks to Kenichi Unnai and his blog, I could realize my purpose.

You have to create these two methods, and call them in ComponentController.wdDoInit().

findTask method

In this method, you have to find a task instance in UWL and generate an actual URL. As described above, you can see task identification key in description of UWL item.

Source code is here. Note that it is simplified for explanation.

//begin sample code ----
public void findTask( ) throws WDUMException, UWLException, WDURLException  {
    // get task key from URL parameter
    String taskKey = WDProtocolAdapter.getProtocolAdapter().
        getRequestObject().getParameter("TaskKey");
    if (taskKey == null || taskKey.length() == 0) {
        wdComponentAPI.getMessageManager().
            reportException("Can not get 'TaskKey' parameter");
        return;
    }

    // create UWL context
    UWLContext uwlContext = new UWLContext();
    IUser user = WDClientUser.getCurrentUser().getSAPUser();
    uwlContext.setUser(user);
    uwlContext.setLocale(user.getLocale() !=
        null ? user.getLocale() : Locale.getDefault());
    // get UWL service
    IUWLService uwlService = (IUWLService) PortalRuntime.getRuntimeResources().
        getService(IUWLService.ALIAS_KEY);
    // begin session
    IUWLSession uwlSession =
        uwlService.beginSession(uwlContext, SESSION_IDLE_TIMEOUT);

    //build expression
    Expression expStatusNew = new Expression(
        Item.STATUS, StatusEnum.NEW.toString(), ComparatorEnum.EQUAL_TO);
    Expression expStatusProg = new Expression(
        Item.STATUS, StatusEnum.INPROGRESS.toString(), ComparatorEnum.EQUAL_TO);
    ArrayList expList = new ArrayList();
    expList.add(expStatusNew);
    expList.add(expStatusProg);
    CompoundExpression exp = new CompoundExpression(expList, null, null, true);
          
    // iterate over all UWL items
    IUWLItemManager itemManager = uwlService.getItemManager(uwlContext);
    UWLView uwlView = uwlService.getViewManager(uwlContext).
        getViewForItemType(ItemType.UWL_ITEM, uwlContext);
    QueryResult result = itemManager.refreshCacheAndGetItems(
        uwlContext, uwlView, queryProperty, exp);
    ItemCollection items = result.getItems();
    List list = items.list();
    for (Item item : list) {
        item = itemManager.getItemByUwlId(uwlContext, item.getInternalId());
        String description = item.getDescription();
        if (description != null && description.endsWith(taskKey)) {
            String executionURL = WDURLGenerator.getApplicationURL(
                BPM_TASK_COMP_NAME, BPM_TASK_PART_NAME, item.getAttributes());
            //store actual URL to WebDynpro context
            wdContext.currentBPMTaskElement().setUrl(executionURL);
            break;
        }
    }

    // end session
    uwlService.endSession(uwlContext);
}

public static final int SESSION_IDLE_TIMEOUT = 60;
public static final String BPM_TASK_COMP_NAME =
    "sap.com/tc~bpem~wdui~taskinstance";
public static final String BPM_TASK_PART_NAME =
    "ATaskExecution";
//end sample code ----

launchTask method

This method redirects end user to the actual URL. It just triggers Exit Plug with Url parameter.

//begin sample code ----
public void launchTask( )  {
    String url = wdContext.currentBPMTaskElement().getUrl();
    if (url != null && url.length() > 0) {
        //triggers Exit Plug with actual URL
        wdThis.wdGetUWLRedirectComponentWindowController().wdFirePlugLaunchTask(url);
    }
}
//end sample code ----

Conclusion

Task notification e-mail is completely modifiable. It can contain any information in a process instance.

End usre can see a task screen easily, just click a URL in a e-mail.

Enjoy!

Assigned Tags

      20 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Abe Zhang
      Abe Zhang
      What's the "queryProperty" mean?I can't find the declaration of that variable.
      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      Hi,

      I posted simplified source code, hence variable declaration of "queryProperty" is omitted. It is not important in my sources.
      You can find detail of the QueryProperties class below.

      http://help.sap.com/javadocs/nwce/current/uwl/com.sap.uwl/com/sap/netweaver/bc/uwl/QueryProperties.html

      Author's profile photo Abe Zhang
      Abe Zhang
      Oh,I get it.It worked when i replaced queryProperty with null.Thank you very much for posting this blog,for it really helps me.
      Author's profile photo Abe Zhang
      Abe Zhang
      Another question.
      Because it's forbidden to fire Exit plug and Suspend plug to a URL in portal.So if I want to click a button in portal to open the task page.How should I do?
      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      As you mentioned, Exit and Suspend plugs are not designed for Portal. My technique is also not fit for Portal. So I used task launcher as standalone WebDynpro application.
      Author's profile photo Abe Zhang
      Abe Zhang
      Thank you for your reply.I have solved it.
      Author's profile photo Todor Petrov
      Todor Petrov
      Hi,

      can you please give me some details on how you solved it in the portal, because we are actually facing the same issue and we need the application running in the portal.

      BR,
      Todor

      Author's profile photo Abe Zhang
      Abe Zhang
      Hi,
      instead of firing the exit plug, use the following code to open the task in a new window:

      wdComponentAPI.getWindowManager().createNonModalExternalWindow(executionURL);

      BR,
      Abe

      Author's profile photo Jun Wu
      Jun Wu
      how getHostUrl is implemented?
      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      Hello,

      it is very good question.
      I had implemented getHostUrl as custom EJB function, it retrieves host url from application properties. Because host url would be changed after transport, and hosts often have multiple network interfaces.

      You can find how to create your own EJB mapping cuntions below.
      http://www.sdn.sap.com/irj/scn/index?rid=/library/uuid/10cdec44-0add-2c10-078a-93124d0b570b

      Here is a document of application properties.
      http://help.sap.com/saphelp_nwce72/helpdata/en/45/c88109a0df570de10000000a114a6b/frameset.htm

      Enjoy,
      Hiro

      Author's profile photo Jun Wu
      Jun Wu
      thanks for the replay.
      it looks like there is no other option.
      I have to do the same.
      actually i post a thread for this.
      how to get the base url
      Author's profile photo Former Member
      Former Member
      Hi,

      As per the blog you mentioned that Taks key is generated from current date and time at Start event. Can you please eloborate on this. We are unable to figure out based on time stamp how it creates the task Key.

      Regards,
      Krishnam

      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      I have posted new blog entry for this topic.
      Please see it and send me your feedback.
      NetWeaver BPM 7.20: Generating unique value with built-in mapping functions

      Hiro

      Author's profile photo Former Member
      Former Member
      Hi,

      This blog really helps us. We are now able to redirect the task through email notification also. But only one issue is we tried to use fire plug and we are not able to achieve. But we used the below code to acheieve this. The issue with this code is its asking to login twice as we are force loggoff user in the code. Can you please let me know how to use this code and do the needful.
      public void launchTask( )  {
          String url = wdContext.currentBPMTaskElement().getUrl();
          if (url != null && url.length() > 0) {
              //triggers Exit Plug with actual URL
              wdThis.wdGetUWLRedirectComponentWindowController().wdFirePlugLaunchTask(url);
          }
      }
      Thanks.

      code which I used as above is not working for us.

      if(taskKey != null)
              {
                        wdComponentAPI.getMessageManager().reportSuccess("yes");
                        String url = wdThis.wdGetUtilityInterfaceInterface().getUWLTaskURL(taskKey);
                        String finalurl = "https://host/webdynpro/dispatcher";
                        url = url.substring(5, url.length());
                        url = finalurl+url;
                        wdComponentAPI.getMessageManager().reportSuccess("url " + url);
                        WDClientUser.forceLogoffClientUser(url);
                        String loggedin = wdThis.wdGetUtilityInterfaceInterface().getLoggedInUser();
                        wdComponentAPI.getMessageManager().reportSuccess("loggedin " + loggedin);
              }

      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      Hello Krishna,

      I don't know exact reason of your launchTask method could not work properly, but it should be work.
      Please check below again on your workspace.

      • Your plug MUST be exit plug
      • Exit plug MUST have "url" parameter

      Please check and try again.

      Hiro

      Author's profile photo Former Member
      Former Member
      Hi,

      First of all thanks for your time and effort, this blog really is a starting point for us.

      Just implemented the scource code you have provided but in the section below we are getting UWL Exception "Logged in users context or session doesn't exist.".

      QueryResult result = itemManager.refreshCacheAndGetItems(
              uwlContext, uwlView, queryProperty, exp);

      Why would this happen? Did i missed something, or a nother configuration/coding needed?

      Regards,
      Utku

      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      Hello Utku,

      Login is necessary to use UWL APIs. In this case, you must set authentication in WebDynpro application property.
      Please refer How to use UWL API for NetWeaver BPM Tasks for API usage and authentication issue.

      Enjoy,
      Hiro

      Author's profile photo Former Member
      Former Member
      Hello Hiro,

      Authentication parameter in WebDynpro application is set to true, and we do get the login screen when we deploy & run the application from the NWDS.

      The funny thing is, when we deploy & run the apllication and login it gives the UWL exception, but if i re-deploy & run it from the NWDS without closing the previous explorer tab; it doesn't need a logon, and it do work.

      Can this give you any clue about the missing part, or the problem?

      Best Regards,
      Utku

      Author's profile photo Hiroyuki Otaki
      Hiroyuki Otaki
      Blog Post Author
      Hi Utku,

      Unfortunately, I cannot understand exact reason of the problem.
      Anyway, in my practice, configuration is performed in background just after deployment. Hence system might be unstable for a while.
      Please close all browser windows, take a coffee, then try it again.

      Regards,
      Hiro

      Author's profile photo Former Member
      Former Member
      This functionality is included as part of 72 SP05 AND DOES NOT require any coding.