Skip to main content

I enjoy having the ability to speak to a room and auto-magically set a cooking timer, play NPR, or check the weather. I then thought it would be amusing to be able to start a workflow as well. If I can order a pizza with my voice, I should be able to start a workflow too! 

 

With the Nintex Workflow Cloud, the ability to externally start a workflow (Nintex Workflow Cloud External Start ) opens up a world cloud of possibilities. With the right tools, anything can become a start event. In this blog post, I'll walk you through how I wired up Alexa to successfully start a Nintex Workflow with code samples and Alexa skills kit examples.

 

Alexa Skill Development

For demo purposes, I'll be calling into a leave approval workflow built in NWC. To build the Alexa skill that will help kick-off this workflow, we need a few important bits of information:

Skill Info

  • Skill Type - What type of skill you're making.
    • Select: Custom Interaction Model
  • Name - Something of your choosing.
    • In my case, "Time off"
  • Invocation Name: Something of your choosing.
    • In my case, "for time off"

 

Interaction Model 

This defines the voice interface for the Alexa skill and it is built with the following sub-parts:

  • Intent Schema - This defines the user intents, which define slots (variables) tied to each intent (function).
  • Sample Utterances - This defines the phrases the user can speak and tells Alexa where to expect the given slots for your various intents.

 

Intent Schema Example


   "intents":  
      { 
         "intent":"DayOff",
         "slots":e 
            { 
               "name":"Day",
               "type":"AMAZON.DATE"
            }
         ]
      },
      { 
         "intent":"DaysOff",
         "slots":> 
            { 
               "name":"DayStart",
               "type":"AMAZON.DATE"
            },
            { 
               "name":"DayEnd",
               "type":"AMAZON.DATE"
            }
         ]
      }
   ]
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

Sample Utterances Example

DayOff ask for time off {Day}
DayOff ask for {Day} off
DayOff I want {Day} off
DayOff I want a vacation {Day}
DayOff I want to take a vacation {Day}
DaysOff ask for time off from {DayStart} to {DayEnd}
DaysOff ask for time off starting {DayStart} until {DayEnd}
DaysOff ask for vacation from {DayStart} to {DayEnd}
DaysOff ask for vacation starting {DayStart} until {DayEnd}
DaysOff I want time off from {DayStart} to {DayEnd}
DaysOff I want time off starting {DayStart} until {DayEnd}
DaysOff I want to take vacation from {DayStart} to {DayEnd}
DaysOff I want to take vacation starting {DayStart} until {DayEnd}
DaysOff I want a vacation from {DayStart} to {DayEnd}
DaysOff I want a vacation starting {DayStart} until {DayEnd}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

Configuration

  • Service Endpoint Type: HTTPS (I haven't learned AWS Lambda yet)
    • HTTPS URL: North America
      • This is used to give Alexa interactions a better response time by directing users' requests to a particular geographical region. European designers may want to point to Europe here.
      • In my sample, I'm pointing to an endpoint I created at ngrok since my demo service runs locally.
      • Note: For test purposes, you may want to point to an HTTPS endpoint inspector such as Hookbin - Capture and Inspect HTTP Requests .
  • Account Linking: No

 

SSL Certificate

  • Certificate for NA Endpoint:
    • Select: My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority.
    • For example, my endpoint is: https://<random-8char-long-hex-string>.ngrok.io/dayoff 

 

Sample Request from Amazon

Once the above configuration is complete, you can go ahead and test what Amazon will send you. Here's a sample of the JSON body:

{
    "version": "1.0",
    "session": {
        "new": true,
        "sessionId": "SessionId.9adaf721-b8bb-482b-b35c-8d54c8bed912",
        "application": {
            "applicationId": "amzn1.ask.skill.<intentionally_hidden_uuid>"
        },
        "attributes": {},
        "user": {
            "userId": "amzn1.ask.account.<intentionally_hidden_token>"
        }
    },
    "request": {
        "type": "IntentRequest",
        "requestId": "EdwRequestId.f4b67ca1-3420-4d68-89ff-6cc660784d74",
        "timestamp": "2016-10-13T01:24:07Z",
        "locale": "en-US",
        "intent": {
            "name": "DayOff",
            "slots": {
                "Day": {
                    "name": "Day",
                    "value": "2016-10-14"
                }
            }
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

Nintex Workflow Development

Workflow Example

Now that's the Alexa/Amazon-side of things complete. Let's have a look at our sample workflow below. Quick explanation of the Run-If action. I simply ignore the DayEnd variable if it is less than DayStart (it doesn't make sense to take end a vacation before it starts). When a date isn't defined, it is set to "0001-01-01 00:00:00". That conveniently will fail the Run-If check, allowing me to have both single day off and multiple days off scenarios covered by the same workflow that takes two (start & end) variables. 

 

Start event Configuration

More importantly, let's have a look at the start variables that we've defined in the External Start event below. The DayEnd and DayStart variables are accepted as DateTime (ISO 8601, I believe) variables.

 

These appear in the external start's swagger API under the following path:

paths/<wf_id/instances>/post/parameters

 

Swagger API Example

{
  "swagger": "2.0",
  "info": {
    "title": "LeaveApprovalTest-Alexa",
    "description": ",
    "version": "1.0.0"
  },
  "schemes":
    "https"
  ],
  "basePath": "/api/v1/workflow/published",
  "produces":
    "application/json"
  ],
  "consumes":
    "application/json"
  ],
  "host": "<my-domain>.workflowcloud.com",
  "paths": {
    "/2da2e395-9e86-4f2d-bb2e-18e499acac82/instances": {
      "post": {
        "summary": "Starts the workflow",
        "description": "Starts workflow: LeaveApprovalTest-Alexa",
        "operationId": "wf2da2e395-9e86-4f2d-bb2e-18e499acac82",
        "parameters": e
          {
            "name": "API Parameters",
            "required": true,
            "in": "body",
            "schema": {
              "type": "object",
              "properties": {
                "startData": {
                  "type": "object",
                  "properties": {
                    "se_day_end1": {
                      "title": "DayEnd",
                      "description": ",
                      "type": "string",
                      "format": "date-time"
                    },
                    "se_day_start1": {
                      "title": "DayStart",
                      "description": ",
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "options": {
                  "type": "object",
                  "properties": {
                    "callbackUrl": {
                      "title": "callbackUrl",
                      "description": "A Url to return the results back (https urls only)",
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          {
            "name": "token",
            "type": "string",
            "in": "query",
            "description": "A security token to start the workflow"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "x-ntx-callback-schema": {
              "type": "object",
              "properties": {
                "returnData": {
                  "type": "object",
                  "properties": {
                    "se_day_end1": {
                      "title": "DayEnd",
                      "description": ",
                      "type": "string",
                      "format": "date-time"
                    },
                    "se_day_start1": {
                      "title": "DayStart",
                      "description": ",
                      "type": "string",
                      "format": "date-time"
                    },
                    "c_duration_builder1": {
                      "title": "DurationBuilder",
                      "description": ",
                      "type": "string"
                    },
                    "c_placeholder_var1": {
                      "title": "PlaceholderVar",
                      "description": ",
                      "type": "string"
                    }
                  }
                },
                "workflow": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          },
          "410": {
            "description": "Gone"
          },
          "429": {
            "description": "Too Many Requests"
 
Be the first to reply!

Reply