Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single file lex #4

Merged
merged 4 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Amazon Lex is amazing, except it has very low automation. There's no CloudForma

Also, when trying to create or update anything, the CLI wants you to pass in a checksum so it can figure out if it needs to update or create, this can be annoying.

Lexbelt fixes all this.
`lexbelt` fixes all this.

```
usage: lexbelt [<flags>] <command> [<args> ...]
Expand All @@ -16,7 +16,6 @@ Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--profile=PROFILE AWS credentials/config file profile to use
--region=REGION AWS region
--verbose Verbose Logging - not implemented yet
-v, --version Show application version.

Commands:
Expand All @@ -30,5 +29,56 @@ Commands:
Adds or updates an intent

put-bot --name=NAME [<flags>] <file>
Adds or updates a bot
```
Adds or updates a bo

provision [<flags>] <file>
Provisions and builds an entire Lex bot including slots, intents and the actual bot
```
###Getting lexbelt
Easiest way to install if you're on a Mac or Linux (amd64 or arm64) is to use [Homebrew](https://brew.sh/)

Type:

```
brew tap sethkor/tap
brew install lexbelt
```

For other platforms take a look at the releases in Github. I build binaries for:

|OS | Architecture |
|:------------ |:-------------------------------------- |
|Mac (Darwin) | amd64 (aka x86_64) |
|Linux | amd64, arm64, 386 (32 bit) |
|Windows | amd64, 386 (32 bit) |

Let me know if you would like a particular os/arch binary regularly built.

###Monobots
A monobot will provision everything you need for a lex bot. This includes the slots, intents and the bot plus it will build it
lexbelt expects your lex yaml files in the following directory structure for a mono bot to be provisioned.
```
your-lex-workspace
├──slots
├──intents
├──bots
└──monobot
```

You can take a look at examples/yaml/monobot/OrderFlowersMono.yaml to see an example monobot yaml file like so:
```
LexBotProvisioner:
lexBotName: OrderFlowersOnceMore
lexBot: OrderFlowersBot.yaml
lexIntent: OrderFlowers.yaml
lexSlot:
- FlowerTypes.yaml
```

The yaml/json syntax for slots, intents and bots are all based directly of the AWS API Put API calls, so any attribute
supported by the AWS API will be supported in the API now or in the future can be included in a yaml file

###TODO
* Publishing bots
* Any other feature requested.
* Windows Testing
73 changes: 73 additions & 0 deletions bot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lexmodelbuildingservice"
)

type botYaml struct {
LexBot *lexmodelbuildingservice.PutBotInput `locationName:"lexBot" type:"structure"`
}

func putBot(svc *lexmodelbuildingservice.LexModelBuildingService, file string, poll int) {

var myBot botYaml
readAndUnmarshal(file, &myBot)

if myBot.LexBot == nil {
log.Fatal("Yaml file is not as expected, please check your syntax.")
}

if *putBotCommandName != "" {
myBot.LexBot.Name = putBotCommandName
}

getResult, err := svc.GetBot(&lexmodelbuildingservice.GetBotInput{
Name: myBot.LexBot.Name,
VersionOrAlias: aws.String("$LATEST"),
})

checkError(err)

myBot.LexBot.Checksum = getResult.Checksum

putResult, err := svc.PutBot(myBot.LexBot)

checkError(err)

//loop and poll the status
if !*dontWait {
currentStatus := *putResult.Status
fmt.Print(currentStatus)
for {

if currentStatus == "READY" {
fmt.Println()
break
} else if currentStatus == "FAILED" {
fmt.Printf("\n%s\n", *getResult.FailureReason)
break
}

time.Sleep((time.Duration(poll) * time.Second))

getResult, err = svc.GetBot(&lexmodelbuildingservice.GetBotInput{
Name: myBot.LexBot.Name,
VersionOrAlias: aws.String("$LATEST"),
})

checkError(err)

if currentStatus != *getResult.Status {
currentStatus = *getResult.Status
fmt.Printf("\n" + currentStatus)
} else {
fmt.Print(".")
}
}
}
}
56 changes: 29 additions & 27 deletions examples/json/bots/OrderFlowersBot.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
{
"intents": [
{
"intentVersion": "$LATEST",
"intentName": "OrderFlowers"
}
],
"name": "OrderFlowersBot",
"locale": "en-US",
"abortStatement": {
"messages": [
"lexBot" : {
"intents": [
{
"content": "Sorry, I'm not able to assist at this time",
"contentType": "PlainText"
"intentVersion": "$LATEST",
"intentName": "OrderFlowers"
}
]
},
"clarificationPrompt": {
"maxAttempts": 2,
"messages": [
{
"content": "I didn't understand you, what would you like to do?",
"contentType": "PlainText"
}
]
},
"voiceId": "Salli",
"childDirected": false,
"idleSessionTTLInSeconds": 600,
"description": "Bot to order flowers on the behalf of a user"
],
"name": "OrderFlowersBot",
"locale": "en-US",
"abortStatement": {
"messages": [
{
"content": "Sorry, I'm not able to assist at this time",
"contentType": "PlainText"
}
]
},
"clarificationPrompt": {
"maxAttempts": 2,
"messages": [
{
"content": "I didn't understand you, what would you like to do?",
"contentType": "PlainText"
}
]
},
"voiceId": "Salli",
"childDirected": false,
"idleSessionTTLInSeconds": 600,
"description": "Bot to order flowers on the behalf of a user"
}
}
26 changes: 14 additions & 12 deletions examples/json/intents/AskTime.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"name": "AskTime",
"description": "Intent to ask what the time is",
"version": "1",
"sampleUtterances": [
"lexIntent" : {
"name": "AskTime",
"description": "Intent to ask what the time is",
"version": "1",
"sampleUtterances": [
"Whats the time",
"What time is it",
"Time please",
"Time"
],
"slots": [],
"fulfillmentActivity": {
"codeHook": {
"uri": "arn:aws:lambda:us-west-2:166330533654:function:LexLambdaSampleFulfilment",
"messageVersion": "1.0"
},
"type": "CodeHook"
],
"slots": [],
"fulfillmentActivity": {
"codeHook": {
"uri": "arn:aws:lambda:ap-southeast-2:293499315857:function:LexLambdaSampleFulfilment",
"messageVersion": "1.0"
},
"type": "CodeHook"
}
}
}
Loading