diff --git a/README.md b/README.md index 87665c6..26f373a 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,10 @@ Commands: Adds or updates an intent put-bot --name=NAME [] - Adds or updates a bo + Adds or updates a bot + + export [] + Export existing AWS Lex configs and write to workspace ``` ## Getting lexbelt Easiest way to install if you're on a Mac or Linux (amd64 or arm64) is to use [Homebrew](https://brew.sh/) @@ -51,8 +54,7 @@ For other platforms take a look at the releases in Github. I build binaries for Let me know if you would like a particular os/arch binary regularly built. -Lexbelt wants your lex workspace to look like the following: - +Lexbelt expects your workspace to look like this: ``` your-lex-workspace ├──slots diff --git a/bot.go b/bot.go index 54b32a9..df78ad9 100644 --- a/bot.go +++ b/bot.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "log" "os" "path/filepath" "time" @@ -11,35 +10,16 @@ import ( "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" ) -type botYaml struct { - LexBot *lexmodelbuildingservice.PutBotInput `locationName:"lexBot" type:"structure"` -} - -func publishBot(svc *lexmodelbuildingservice.LexModelBuildingService, name string) string { - - getResult, err := svc.CreateBotVersion(&lexmodelbuildingservice.CreateBotVersionInput{ - Name: aws.String(name), - }) - - checkError(err) - - return *getResult.Version -} - func putBot(svc *lexmodelbuildingservice.LexModelBuildingService, file string, name string, poll int, publish *string) { - var myBot botYaml + var myBot lexmodelbuildingservice.PutBotInput readAndUnmarshal(file, &myBot) - if myBot.LexBot == nil { - log.Fatal("Yaml file is not as expected, please check your syntax.") - } - if publish != nil { //publish each intent separator := string(os.PathSeparator) basePath := filepath.Dir(file) + separator + ".." + separator - for _, v := range myBot.LexBot.Intents { + for _, v := range myBot.Intents { intentVersion, err := putIntent(svc, basePath+"intents"+separator+*v.IntentName+filepath.Ext(file), true) checkError(err) v.IntentVersion = aws.String(intentVersion) @@ -47,23 +27,23 @@ func putBot(svc *lexmodelbuildingservice.LexModelBuildingService, file string, n } if name != "" { - myBot.LexBot.Name = &name + myBot.Name = &name } getResult, err := svc.GetBot(&lexmodelbuildingservice.GetBotInput{ - Name: myBot.LexBot.Name, + Name: myBot.Name, VersionOrAlias: aws.String("$LATEST"), }) checkError(err) - myBot.LexBot.Checksum = getResult.Checksum + myBot.Checksum = getResult.Checksum if publish != nil { - myBot.LexBot.CreateVersion = aws.Bool(true) + myBot.CreateVersion = aws.Bool(true) } - putResult, err := svc.PutBot(myBot.LexBot) + putResult, err := svc.PutBot(&myBot) checkError(err) @@ -78,20 +58,20 @@ func putBot(svc *lexmodelbuildingservice.LexModelBuildingService, file string, n getAliasResult, err := svc.GetBotAlias(&lexmodelbuildingservice.GetBotAliasInput{ Name: publish, - BotName: myBot.LexBot.Name, + BotName: myBot.Name, }) checkError(err) _, err = svc.PutBotAlias(&lexmodelbuildingservice.PutBotAliasInput{ Name: publish, - BotName: myBot.LexBot.Name, + BotName: myBot.Name, BotVersion: putResult.Version, Checksum: getAliasResult.Checksum, }) checkError(err) fmt.Printf("Bot %s was published as version %s and alias \"%s\".\n", - *myBot.LexBot.Name, + *myBot.Name, *putResult.Version, *publish) @@ -104,7 +84,7 @@ func putBot(svc *lexmodelbuildingservice.LexModelBuildingService, file string, n time.Sleep(time.Duration(poll) * time.Second) getResult, err = svc.GetBot(&lexmodelbuildingservice.GetBotInput{ - Name: myBot.LexBot.Name, + Name: myBot.Name, VersionOrAlias: aws.String("$LATEST"), }) diff --git a/examples/json/bots/OrderFlowersBot.json b/examples/json/bots/OrderFlowersBot.json index 1be3bd2..9855ef5 100644 --- a/examples/json/bots/OrderFlowersBot.json +++ b/examples/json/bots/OrderFlowersBot.json @@ -1,33 +1,31 @@ { - "lexBot" : { - "intents": [ + "intents": [ + { + "intentVersion": "$LATEST", + "intentName": "OrderFlowers" + } + ], + "name": "OrderFlowersBot", + "locale": "en-US", + "abortStatement": { + "messages": [ { - "intentVersion": "$LATEST", - "intentName": "OrderFlowers" + "content": "Sorry, I'm not able to assist at this time", + "contentType": "PlainText" } - ], - "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" - } + ] + }, + "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" } \ No newline at end of file diff --git a/examples/json/intents/AskTime.json b/examples/json/intents/AskTime.json index 53a22f2..dc3a3a9 100644 --- a/examples/json/intents/AskTime.json +++ b/examples/json/intents/AskTime.json @@ -1,21 +1,19 @@ { - "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:ap-southeast-2:293499315857:function:LexLambdaSampleFulfilment", - "messageVersion": "1.0" - }, - "type": "CodeHook" - } + "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:ap-southeast-2:293499315857:function:LexLambdaSampleFulfilment", + "messageVersion": "1.0" + }, + "type": "CodeHook" } } \ No newline at end of file diff --git a/examples/json/intents/OrderFlowers.json b/examples/json/intents/OrderFlowers.json index 543a2a2..9efc585 100644 --- a/examples/json/intents/OrderFlowers.json +++ b/examples/json/intents/OrderFlowers.json @@ -1,84 +1,82 @@ { - "lexIntent" : { - "name": "OrderFlowers", - "description": "Intent to order a bouquet of flowers for pick up", - "sampleUtterances": [ - "I would like to pick up flowers", - "I would like to order some flowers" - ], - "slots": [ - { - "slotType": "FlowerTypes", - "name": "FlowerType", - "slotConstraint": "Required", - "valueElicitationPrompt": { - "maxAttempts": 2, - "messages": [ - { - "content": "What type of flowers would you like to order?", - "contentType": "PlainText" - } - ] - }, - "priority": 1, - "slotTypeVersion": "$LATEST", - "sampleUtterances": [ - "I would like to order {FlowerType}" - ], - "description": "The type of flowers to pick up" - }, - { - "slotType": "AMAZON.DATE", - "name": "PickupDate", - "slotConstraint": "Required", - "valueElicitationPrompt": { - "maxAttempts": 2, - "messages": [ - { - "content": "What day do you want the {FlowerType} to be picked up?", - "contentType": "PlainText" - } - ] - }, - "priority": 2, - "description": "The date to pick up the flowers" + "name": "OrderFlowers", + "description": "Intent to order a bouquet of flowers for pick up", + "sampleUtterances": [ + "I would like to pick up flowers", + "I would like to order some flowers" + ], + "slots": [ + { + "slotType": "FlowerTypes", + "name": "FlowerType", + "slotConstraint": "Required", + "valueElicitationPrompt": { + "maxAttempts": 2, + "messages": [ + { + "content": "What type of flowers would you like to order?", + "contentType": "PlainText" + } + ] }, - { - "slotType": "AMAZON.TIME", - "name": "PickupTime", - "slotConstraint": "Required", - "valueElicitationPrompt": { - "maxAttempts": 2, - "messages": [ - { - "content": "Pick up the {FlowerType} at what time on {PickupDate}?", - "contentType": "PlainText" - } - ] - }, - "priority": 3, - "description": "The time to pick up the flowers" - } - ], - "confirmationPrompt": { - "maxAttempts": 2, - "messages": [ - { - "content": "Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}. Does this sound okay?", - "contentType": "PlainText" - } - ] + "priority": 1, + "slotTypeVersion": "$LATEST", + "sampleUtterances": [ + "I would like to order {FlowerType}" + ], + "description": "The type of flowers to pick up" }, - "rejectionStatement": { - "messages": [ - { - "content": "Okay, I will not place your order.", - "contentType": "PlainText" - } - ] + { + "slotType": "AMAZON.DATE", + "name": "PickupDate", + "slotConstraint": "Required", + "valueElicitationPrompt": { + "maxAttempts": 2, + "messages": [ + { + "content": "What day do you want the {FlowerType} to be picked up?", + "contentType": "PlainText" + } + ] + }, + "priority": 2, + "description": "The date to pick up the flowers" }, - "fulfillmentActivity": { - "type": "ReturnIntent" + { + "slotType": "AMAZON.TIME", + "name": "PickupTime", + "slotConstraint": "Required", + "valueElicitationPrompt": { + "maxAttempts": 2, + "messages": [ + { + "content": "Pick up the {FlowerType} at what time on {PickupDate}?", + "contentType": "PlainText" + } + ] + }, + "priority": 3, + "description": "The time to pick up the flowers" } + ], + "confirmationPrompt": { + "maxAttempts": 2, + "messages": [ + { + "content": "Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}. Does this sound okay?", + "contentType": "PlainText" + } + ] + }, + "rejectionStatement": { + "messages": [ + { + "content": "Okay, I will not place your order.", + "contentType": "PlainText" + } + ] + }, + "fulfillmentActivity": { + "type": "ReturnIntent" } } \ No newline at end of file diff --git a/examples/json/slots/FlowerTypes.json b/examples/json/slots/FlowerTypes.json index b051246..ec6fb07 100644 --- a/examples/json/slots/FlowerTypes.json +++ b/examples/json/slots/FlowerTypes.json @@ -1,21 +1,19 @@ { - "lexSlot" : { - "name": "FlowerTypes", - "description": "Types of flowers to pick up", - "enumerationValues": [ - { - "value": "tulips" - }, - { - "value": "lilies" - }, - { - "value": "roses" - }, - { - "value": "carnations" - } - ] - } + "name": "FlowerTypes", + "description": "Types of flowers to pick up", + "enumerationValues": [ + { + "value": "tulips" + }, + { + "value": "lilies" + }, + { + "value": "roses" + }, + { + "value": "carnations" + } + ] } \ No newline at end of file diff --git a/examples/yaml/bots/OrderFlowersBot.yaml b/examples/yaml/bots/OrderFlowersBot.yaml index 5cd68a3..b556b31 100644 --- a/examples/yaml/bots/OrderFlowersBot.yaml +++ b/examples/yaml/bots/OrderFlowersBot.yaml @@ -1,19 +1,18 @@ -lexBot: - intents: - - intentVersion: 1 - intentName: OrderFlowers - 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 +intents: + - intentVersion: 1 + intentName: OrderFlowers +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 diff --git a/examples/yaml/bots/TalkingClock.yaml b/examples/yaml/bots/TalkingClock.yaml index 5eb6f25..aabee40 100644 --- a/examples/yaml/bots/TalkingClock.yaml +++ b/examples/yaml/bots/TalkingClock.yaml @@ -1,21 +1,20 @@ -lexBot: - name: Another Clock - description: A Lex bot that tells you the time - locale: en-US - voiceId: Salli - childDirected: false - idleSessionTTLInSeconds: 600 - intents: - - intentName: AskTime - intentVersion: $LATEST - - intentName: AskDay - intentVersion: $LATEST - clarificationPrompt: - maxAttempts: 3 - messages: - - content: Sorry, I don't understand what you would like to do - contentType: PlainText - abortStatement: - messages: - - content: Sorry, I can't help you right now - contentType: PlainText \ No newline at end of file +name: Another Clock +description: A Lex bot that tells you the time +locale: en-US +voiceId: Salli +childDirected: false +idleSessionTTLInSeconds: 600 +intents: + - intentName: AskTime + intentVersion: $LATEST + - intentName: AskDay + intentVersion: $LATEST +clarificationPrompt: + maxAttempts: 3 + messages: + - content: Sorry, I don't understand what you would like to do + contentType: PlainText +abortStatement: + messages: + - content: Sorry, I can't help you right now + contentType: PlainText \ No newline at end of file diff --git a/examples/yaml/intents/AskDay.yaml b/examples/yaml/intents/AskDay.yaml index 6fcaf31..f21652e 100644 --- a/examples/yaml/intents/AskDay.yaml +++ b/examples/yaml/intents/AskDay.yaml @@ -1,14 +1,13 @@ -lexIntent: - name: AskDay - description: Intent to ask what the day is - version: 1 - sampleUtterances: - - 'Whats the day' - - 'What day is it' - - 'Day please' - - 'Four' - fulfillmentActivity: - codeHook: - uri: arn:aws:lambda:us-west-2:166330533654:function:LexLambdaSampleFulfilment - messageVersion: "1.0" - type: CodeHook +name: AskDay +description: Intent to ask what the day is +version: 1 +sampleUtterances: + - 'Whats the day' + - 'What day is it' + - 'Day please' + - 'Four' +fulfillmentActivity: + codeHook: + uri: arn:aws:lambda:us-west-2:166330533654:function:LexLambdaSampleFulfilment + messageVersion: "1.0" + type: CodeHook diff --git a/examples/yaml/intents/AskTime.yaml b/examples/yaml/intents/AskTime.yaml index 1171534..c8759cb 100644 --- a/examples/yaml/intents/AskTime.yaml +++ b/examples/yaml/intents/AskTime.yaml @@ -1,13 +1,12 @@ -lexIntent: - name: AskTime - description: Intent to ask what the time is - version: 1 - sampleUtterances: - - 'Whats the time' - - 'What time is it' - - 'Time please' - fulfillmentActivity: - codeHook: - uri: arn:aws:lambda:ap-southeast-2:293499315857:function:LexLambdaSampleFulfilment - messageVersion: "1.0" - type: CodeHook +name: AskTime +description: Intent to ask what the time is +version: 1 +sampleUtterances: + - 'Whats the time' + - 'What time is it' + - 'Time please' +fulfillmentActivity: + codeHook: + uri: arn:aws:lambda:ap-southeast-2:293499315857:function:LexLambdaSampleFulfilment + messageVersion: "1.0" + type: CodeHook diff --git a/examples/yaml/intents/OrderFlowers.yaml b/examples/yaml/intents/OrderFlowers.yaml index 0a05329..9adcf9f 100644 --- a/examples/yaml/intents/OrderFlowers.yaml +++ b/examples/yaml/intents/OrderFlowers.yaml @@ -1,54 +1,53 @@ -lexIntent: - name: OrderFlowers - description: Intent to order a bouquet of flowers for pick up - sampleUtterances: - - I would like to pick up flowers - - I would like to order some flowers - - Flowers please - - Can I have some flowers - slots: - - slotType: FlowerTypes - slotTypeVersion: $LATEST - name: FlowerType - slotConstraint: Required - valueElicitationPrompt: - maxAttempts: 2 - messages: - - content: What type of flowers would you like to order? - contentType: PlainText - priority: 1 - sampleUtterances: - - I would like to order {FlowerType} - description: The type of flowers to pick up - - slotType: AMAZON.DATE - name: PickupDate - slotConstraint: Required - valueElicitationPrompt: - maxAttempts: 2 - messages: - - content: What day do you want the {FlowerType} to be picked up? - contentType: PlainText - priority: 2 - description: The date to pick up the flowers - - slotType: AMAZON.TIME - name: PickupTime - slotConstraint: Required - valueElicitationPrompt: - maxAttempts: 2 - messages: - - content: Pick up the {FlowerType} at what time on {PickupDate}? - contentType: PlainText - priority: 3 - description: The time to pick up the flowers - confirmationPrompt: - maxAttempts: 2 - messages: - - content: Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}. Does this sound okay? - contentType: PlainText - rejectionStatement: - messages: - - content: Okay, I will not place your order. - contentType: PlainText - fulfillmentActivity: - type: ReturnIntent +name: OrderFlowers +description: Intent to order a bouquet of flowers for pick up +sampleUtterances: + - I would like to pick up flowers + - I would like to order some flowers + - Flowers please + - Can I have some flowers +slots: + - slotType: FlowerTypes + slotTypeVersion: $LATEST + name: FlowerType + slotConstraint: Required + valueElicitationPrompt: + maxAttempts: 2 + messages: + - content: What type of flowers would you like to order? + contentType: PlainText + priority: 1 + sampleUtterances: + - I would like to order {FlowerType} + description: The type of flowers to pick up + - slotType: AMAZON.DATE + name: PickupDate + slotConstraint: Required + valueElicitationPrompt: + maxAttempts: 2 + messages: + - content: What day do you want the {FlowerType} to be picked up? + contentType: PlainText + priority: 2 + description: The date to pick up the flowers + - slotType: AMAZON.TIME + name: PickupTime + slotConstraint: Required + valueElicitationPrompt: + maxAttempts: 2 + messages: + - content: Pick up the {FlowerType} at what time on {PickupDate}? + contentType: PlainText + priority: 3 + description: The time to pick up the flowers +confirmationPrompt: + maxAttempts: 2 + messages: + - content: Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}. Does this sound okay? + contentType: PlainText +rejectionStatement: + messages: + - content: Okay, I will not place your order. + contentType: PlainText +fulfillmentActivity: + type: ReturnIntent diff --git a/examples/yaml/slots/FlowerTypes.yaml b/examples/yaml/slots/FlowerTypes.yaml index 1b315dc..8f200ca 100644 --- a/examples/yaml/slots/FlowerTypes.yaml +++ b/examples/yaml/slots/FlowerTypes.yaml @@ -1,23 +1,22 @@ -lexSlot: - name: FlowerTypes - description: types of flowers to pick up from a yaml file - enumerationValues: - - value: tulips - synonyms: - - dutch - - holland - - value: lilies - - value: roses - - value: carnations - - value: daisy - - value: petuna - - value: lavender - synonyms: - - purple - - value: carnation - synonyms: - - english - - fancy - - fluffy - - value: orchid +name: FlowerTypes +description: types of flowers to pick up from a yaml file +enumerationValues: + - value: tulips + synonyms: + - dutch + - holland + - value: lilies + - value: roses + - value: carnations + - value: daisy + - value: petuna + - value: lavender + synonyms: + - purple + - value: carnation + synonyms: + - english + - fancy + - fluffy + - value: orchid diff --git a/examples/yaml/slots/UpperFlowerTypes.yaml b/examples/yaml/slots/UpperFlowerTypes.yaml new file mode 100644 index 0000000..67cb487 --- /dev/null +++ b/examples/yaml/slots/UpperFlowerTypes.yaml @@ -0,0 +1,22 @@ + Name: UpperFlowerTypes + Description: types of flowers to pick up from a yaml file + EnumerationValues: + - Value: tulips + Synonyms: + - dutch + - holland + - Value: lilies + - Value: roses + - Value: carnations + - Value: daisy + - Value: petuna + - Value: lavender + Synonyms: + - purple + - Value: carnation + Synonyms: + - english + - fancy + - fluffy + - Value: orchid + diff --git a/export.go b/export.go new file mode 100644 index 0000000..1ccad3e --- /dev/null +++ b/export.go @@ -0,0 +1,63 @@ +package main + +import ( + "os" + + "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" +) + +func exportLex(svc *lexmodelbuildingservice.LexModelBuildingService, toJson bool) { + + //ensure the needed child dirs are present + os.Mkdir("slots", 0744) + os.Mkdir("intents", 0744) + os.Mkdir("bots", 0744) + + //get slots + err := svc.GetSlotTypesPages(&lexmodelbuildingservice.GetSlotTypesInput{}, func(page *lexmodelbuildingservice.GetSlotTypesOutput, lastPage bool) bool { + + for _, v := range page.SlotTypes { + result, err := svc.GetSlotType(&lexmodelbuildingservice.GetSlotTypeInput{ + Name: v.Name, + Version: v.Version, + }) + checkError(err) + marshalAndWrite("./slots/"+*result.Name, toJson, result) + + } + return true + }) + checkError(err) + + //get Intents + err = svc.GetIntentsPages(&lexmodelbuildingservice.GetIntentsInput{}, func(page *lexmodelbuildingservice.GetIntentsOutput, lastPage bool) bool { + + for _, v := range page.Intents { + result, err := svc.GetIntent(&lexmodelbuildingservice.GetIntentInput{ + Name: v.Name, + Version: v.Version, + }) + checkError(err) + marshalAndWrite("./intents/"+*result.Name, toJson, result) + + } + return true + }) + checkError(err) + + //get bots + err = svc.GetBotsPages(&lexmodelbuildingservice.GetBotsInput{}, func(page *lexmodelbuildingservice.GetBotsOutput, lastPage bool) bool { + + for _, v := range page.Bots { + result, err := svc.GetBot(&lexmodelbuildingservice.GetBotInput{ + Name: v.Name, + VersionOrAlias: v.Version, + }) + checkError(err) + marshalAndWrite("./bots/"+*result.Name, toJson, result) + + } + return true + }) + checkError(err) +} diff --git a/intent.go b/intent.go index ca97deb..a46a8c9 100644 --- a/intent.go +++ b/intent.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "log" "os" "path/filepath" @@ -10,37 +9,18 @@ import ( "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" ) -type intentYaml struct { - LexIntent *lexmodelbuildingservice.PutIntentInput `locationName:"lexIntent" type:"structure"` -} - -func publishIntent(svc *lexmodelbuildingservice.LexModelBuildingService, name string) string { - - getResult, err := svc.CreateIntentVersion(&lexmodelbuildingservice.CreateIntentVersionInput{ - Name: aws.String(name), - }) - - checkError(err) - - return *getResult.Version -} - func putIntent(svc *lexmodelbuildingservice.LexModelBuildingService, file string, publish bool) (string, error) { - var myIntent intentYaml + var myIntent lexmodelbuildingservice.PutIntentInput readAndUnmarshal(file, &myIntent) - if myIntent.LexIntent == nil { - log.Fatal("Yaml file is not as expected, please check your syntax.") - } - if publish { //For publishing, check the intent to see if it has any slots custom slots. If we find a custom slot and the //version specified is latest, we must publish the slot and then update this intent put operation with the //version separator := string(os.PathSeparator) basePath := filepath.Dir(file) + separator + ".." + separator - for _, v := range myIntent.LexIntent.Slots { + for _, v := range myIntent.Slots { if v.SlotTypeVersion != nil { //assume if no version is present, it's a built in type and we don't need to do anything if *v.SlotTypeVersion == latestVersion { @@ -55,20 +35,20 @@ func putIntent(svc *lexmodelbuildingservice.LexModelBuildingService, file string } if *putIntentCommandName != "" { - myIntent.LexIntent.Name = putIntentCommandName + myIntent.Name = putIntentCommandName } getResult, err := svc.GetIntent(&lexmodelbuildingservice.GetIntentInput{ - Name: myIntent.LexIntent.Name, + Name: myIntent.Name, Version: aws.String(latestVersion), }) checkError(err) - myIntent.LexIntent.Checksum = getResult.Checksum + myIntent.Checksum = getResult.Checksum - myIntent.LexIntent.CreateVersion = aws.Bool(publish) - result, err := svc.PutIntent(myIntent.LexIntent) - fmt.Printf("Intent %s was published as version %s\n", *myIntent.LexIntent.Name, *result.Version) + myIntent.CreateVersion = aws.Bool(publish) + result, err := svc.PutIntent(&myIntent) + fmt.Printf("Intent %s was published as version %s\n", *myIntent.Name, *result.Version) checkError(err) return *result.Version, err diff --git a/lexbelt.go b/lexbelt.go index 4459b64..528424f 100644 --- a/lexbelt.go +++ b/lexbelt.go @@ -31,6 +31,9 @@ var ( putBotCommandPublish = putBotCommand.Flag("publish", "Publish a new version the bot with the provided alias").String() putBotCommandPoll = putBotCommand.Flag("poll", "Poll time").Default("3").Int() dontWait = putBotCommand.Flag("dont-wait", "Don't wait for the build to completed before exiting").Default("false").Bool() + + exportCommand = app.Command("export", "Export existing AWS Lex configs and write to workspace") + exportCommandJson = exportCommand.Flag("json", "export as json").Default("false").Bool() ) var ( @@ -86,6 +89,8 @@ func main() { putIntent(svc, (*putIntentCommandFile).Name(), *putIntentCommandPublish) case putBotCommand.FullCommand(): putBot(svc, (*putBotCommandFile).Name(), *putBotCommandName, *putBotCommandPoll, putBotCommandPublish) + case exportCommand.FullCommand(): + exportLex(svc, *exportCommandJson) } } diff --git a/slot.go b/slot.go index 6edf91c..cfd75b7 100644 --- a/slot.go +++ b/slot.go @@ -2,53 +2,30 @@ package main import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/lexmodelbuildingservice" ) -type slotYaml struct { - LexSlot *lexmodelbuildingservice.PutSlotTypeInput `locationName:"lexSlot" type:"structure"` -} - -//func publishSlot(svc *lexmodelbuildingservice.LexModelBuildingService, name string) (string, error) { -// -// getResult, err := svc.CreateSlotTypeVersion(&lexmodelbuildingservice.CreateSlotTypeVersionInput{ -// Name: aws.String(name), -// }) -// -// var slotVersion string -// if err == nil { -// slotVersion = *getResult.Version -// } -// -// return slotVersion, err -//} - func putSlotType(svc *lexmodelbuildingservice.LexModelBuildingService, file string, publish bool) (string, error) { - var mySlotType slotYaml + var mySlotType lexmodelbuildingservice.PutSlotTypeInput readAndUnmarshal(file, &mySlotType) - if mySlotType.LexSlot == nil { - log.Fatal("Yaml file is not as expected, please check your syntax.") - } - if *putSlotTypeCommandName != "" { - mySlotType.LexSlot.Name = putSlotTypeCommandName + mySlotType.Name = putSlotTypeCommandName } getResult, err := svc.GetSlotType(&lexmodelbuildingservice.GetSlotTypeInput{ - Name: mySlotType.LexSlot.Name, + Name: mySlotType.Name, Version: aws.String("$LATEST"), }) checkError(err) - mySlotType.LexSlot.Checksum = getResult.Checksum - mySlotType.LexSlot.CreateVersion = aws.Bool(publish) - result, err := svc.PutSlotType(mySlotType.LexSlot) + mySlotType.Checksum = getResult.Checksum + mySlotType.CreateVersion = aws.Bool(publish) + result, err := svc.PutSlotType(&mySlotType) checkError(err) - fmt.Printf("Slot %s was published as version %s\n", *mySlotType.LexSlot.Name, *result.Version) + fmt.Printf("Slot %s was published as version %s\n", *mySlotType.Name, *result.Version) return *result.Version, err } diff --git a/utils.go b/utils.go index 0259c87..e6fd653 100644 --- a/utils.go +++ b/utils.go @@ -52,3 +52,16 @@ func readAndUnmarshal(fileName string, destination interface{}) { } } + +func marshalAndWrite(fileName string, toJson bool, source interface{}) { + var file []byte + extension := ".yaml" + if toJson { + file, _ = json.MarshalIndent(source, "", " ") + extension = ".json" + } else { + file, _ = yaml.Marshal(source) + } + err := ioutil.WriteFile(fileName+extension, file, 0644) + checkError(err) +}