Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

Commit

Permalink
feat: add autopilot module
Browse files Browse the repository at this point in the history
add module to manage all autopilot terraform resources
add examples usages
add terratests to ensure the module is working as expected
add documentation using terraform-docs
  • Loading branch information
RJPearson94 committed Sep 13, 2020
0 parents commit 2fcbf06
Show file tree
Hide file tree
Showing 53 changed files with 2,231 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Default owner for all pull requests
* @RJPearson94
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "terraform"
directory: "/"
schedule:
interval: "daily"

- package-ecosystem: "terraform"
directory: "/modules/*"
schedule:
interval: "daily"
19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# IDE's
.idea
.vscode
*.iml

# Terraform
*.backup
*.tfstate
*.tfstate.*
*.tfplan
.terraform/
crash.log

# Misc
.history
.DS_Store

# Testing
vendor
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# terraform-twilio-autopilot

This is a terraform module for managing an autopilot assistant.

!> This module will destroy the model build before creating a new one

This module uses the Community Twilio Terraform Provider (also maintained by the module [author](https://github.com/RJPearson94))

- [Terraform Registry](https://registry.terraform.io/providers/RJPearson94/twilio/latest)
- [Github](https://github.com/RJPearson94/terraform-provider-twilio)

The following resources can be managed via the module:

- [Assistant](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_assistant)
- [Field Type](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_field_type)
- [Field Value](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_field_value)
- [Model Build](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_model_build)
- [Tasks](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_task)
- [Task Fields](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_task_field)
- [Task Samples](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_task_sample)
- [Webhooks](https://registry.terraform.io/providers/RJPearson94/twilio/latest/docs/resources/autopilot_webhook)

!> **Disclaimer**: This project is not an official Twilio project and is not supported or endorsed by Twilio in any way. It is maintained in [my](https://github.com/RJPearson94) free time.

## Examples

Examples of how the Terraform module can be used can be found [here](./examples)

## Requirements

| Name | Version |
| --------- | --------------- |
| terraform | >= 0.13, < 0.14 |
| twilio | >= 0.2.0 |

## Providers

| Name | Version |
| ------ | -------- |
| twilio | >= 0.2.0 |

## Inputs

| Name | Description | Type | Default | Required |
| ----------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | :------: |
| assistant_name | The unique name of the Autopilot assistant | `string` | n/a | yes |
| callback | The callback webhook | <pre>object({<br> url = string<br> events = list(string)<br> })</pre> | `null` | no |
| default_language | The default language to use for the task, sample and fields | `string` | n/a | yes |
| defaults | The defaults JSON of the Autopilot assistant | `string` | `null` | no |
| development_stage | Whether the assistant is in development stage | `bool` | `false` | no |
| enable_logging | Whether query logging is enabled | `bool` | `false` | no |
| polling | n/a | <pre>object({<br> enabled = bool<br> max_attempts = number<br> delay_in_ms = number<br> })</pre> | <pre>{<br> "delay_in_ms": null,<br> "enabled": true,<br> "max_attempts": null<br>}</pre> | no |
| stylesheet | The stylesheet JSON of the Autopilot assistant | `string` | `null` | no |
| tasks | The tasks of the Autopilot assistants | <pre>list(object({<br> name = string<br> actions = object({<br> json = string<br> url = string<br> })<br> fields = list(object({<br> name = string<br> type = object({<br> built_in = string<br> custom = object({<br> name = string<br> values = list(object({<br> language_override = string<br> value = string<br><br> synonyms = list(object({<br> language_override = string<br> value = string<br> }))<br> }))<br> })<br> })<br> }))<br> samples = list(object({<br> tagged_text = string<br> language_override = string<br> source_channel = string<br> }))<br> }))</pre> | n/a | yes |
| webhooks | The webhooks which will be triggered on specific events | <pre>list(object({<br> name = string<br> url = string<br> method = string<br> events = list(string)<br> }))</pre> | `[]` | no |

## Outputs

| Name | Description |
| ----------- | ----------------------------------- |
| assistant | The generated Autopilot assistant |
| model_build | The generated Autopilot model build |
| tasks | The generated tasks |
| webhooks | The generated Autopilot webhooks |

## Modules

This module utilises additional sub-modules which can be seen [here](./modules)
7 changes: 7 additions & 0 deletions examples/appointment_booking/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "javascript" "task_mapper" {
source = file("${path.module}/helper/taskMapper.js")

vars = {
input = [for filePath in fileset(path.module, "tasks/*.json") : file(filePath)]
}
}
9 changes: 9 additions & 0 deletions examples/appointment_booking/defaults.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"defaults": {
"assistant_initiation": "task://greeting",
"fallback": "task://fallback",
"collect": {
"validate_on_failure": "task://collect_fallback"
}
}
}
44 changes: 44 additions & 0 deletions examples/appointment_booking/helper/taskMapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function mapActions(actions) {
if (!actions) {
return {
json: null,
url: null,
};
}

return {
json: actions.json ? JSON.stringify(actions.json) : null,
url: actions.url || null,
};
}

function mapField(field) {
return {
name: field.name,
type: {
built_in: field.type.built_in || null,
custom: field.type.custom || null,
},
};
}

function mapSample(sample) {
return {
tagged_text: sample.tagged_text,
language_override: sample.language_override || null,
source_channel: sample.source_channel || null,
};
}

function mapTasks(tasks) {
return tasks.map(JSON.parse).map(function (task) {
return {
name: task.name,
actions: mapActions(task.actions),
fields: (task.fields || []).map(mapField),
samples: (task.samples || []).map(mapSample),
};
});
}

mapTasks(input);
15 changes: 15 additions & 0 deletions examples/appointment_booking/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "random_string" "random" {
length = 16
special = false
}

module "appointment_booking" {
source = "../../"

assistant_name = "appointment-booking-${random_string.random.result}"
defaults = file("${path.module}/defaults.json")
stylesheet = file("${path.module}/stylesheet.json")
default_language = "en-US"

tasks = data.javascript.task_mapper.result
}
3 changes: 3 additions & 0 deletions examples/appointment_booking/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "assistant_sid" {
value = module.appointment_booking.assistant.sid
}
38 changes: 38 additions & 0 deletions examples/appointment_booking/stylesheet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"style_sheet": {
"voice": {
"say_voice": "Polly.Matthew"
},
"name": "",
"collect": {
"validate": {
"on_failure": {
"messages": [
{
"say": {
"speech": "I didn't get that. What did you say?"
}
},
{
"say": {
"speech": "I still didn't catch that. Please repeat."
}
},
{
"say": {
"speech": "Let's try one last time. Say it again please."
}
}
],
"repeat_question": false
},
"on_success": {
"say": {
"speech": ""
}
},
"max_attempts": 4
}
}
}
}
119 changes: 119 additions & 0 deletions examples/appointment_booking/tasks/book_appointments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{
"name": "book_appointments",
"actions": {
"json": {
"actions": [
{
"say": "Okay lets get you a new appointment. I just need you to answer a few questions."
},
{
"collect": {
"name": "schedule_appt",
"questions": [
{
"question": "Please tell me the date you want to come in.",
"name": "appt_date",
"type": "Twilio.DATE"
},
{
"question": "Thanks, and what time?",
"name": "appt_time",
"type": "Twilio.TIME"
},
{
"question": "Awesome, last question. What is the best number to reach you on?",
"name": "appt_phone_number",
"type": "Twilio.PHONE_NUMBER"
}
],
"on_complete": {
"redirect": "task://complete_booking"
}
}
}
]
}
},
"fields": [
{
"name": "ApptDate",
"type": {
"built_in": "Twilio.DATE"
}
},
{
"name": "ApptTime",
"type": {
"built_in": "Twilio.TIME"
}
}
],
"samples": [
{
"tagged_text": "Can I make a new appointment"
},
{
"tagged_text": "Get me a new appointment please."
},
{
"tagged_text": "Can I get a new appointment?"
},
{
"tagged_text": "New appointment please"
},
{
"tagged_text": "I want to make an appointment"
},
{
"tagged_text": "Appointment"
},
{
"tagged_text": "New appointment"
},
{
"tagged_text": "get me a new appointment"
},
{
"tagged_text": "make appointment"
},
{
"tagged_text": "I'd like to make a new appointment"
},
{
"tagged_text": "I want a new appointment"
},
{
"tagged_text": "Can I get a new appointment at {ApptTime} on {ApptDate}?"
},
{
"tagged_text": "I'd like to book an appointment on {ApptDate} at {ApptTime}"
},
{
"tagged_text": "I want an appointment at {ApptTime} on {ApptDate}"
},
{
"tagged_text": "Can I get an appointment"
},
{
"tagged_text": "Can I book a new appointment please?"
},
{
"tagged_text": "Can I have a new appointment at {ApptTime} on {ApptDate}?"
},
{
"tagged_text": "book appointment for {ApptDate}"
},
{
"tagged_text": "book appointment for {ApptTime} on {ApptDate}"
},
{
"tagged_text": "Can I get a new appointment on {ApptDate}?"
},
{
"tagged_text": "book appointment for {ApptTime}"
},
{
"tagged_text": "book an appointment for {ApptTime}"
}
]
}
49 changes: 49 additions & 0 deletions examples/appointment_booking/tasks/cancel_appointments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "cancel_appointments",
"actions": {
"json": {
"actions": [
{
"say": "Okay I've cancelled your appointment. What else can I help you with?"
},
{
"listen": {
"tasks": ["book_appointments", "list_appointments", "goodbye"]
}
}
]
}
},
"samples": [
{
"tagged_text": "Can you help me cancel my appointment?"
},
{
"tagged_text": "I need to cancel my appointment please"
},
{
"tagged_text": "Cancel appointment"
},
{
"tagged_text": "need to cancel"
},
{
"tagged_text": "I need to cancel my session"
},
{
"tagged_text": "I want to cancel my appointment"
},
{
"tagged_text": "cancel appt"
},
{
"tagged_text": "can't make my appointment"
},
{
"tagged_text": "can't come in"
},
{
"tagged_text": "Please cancel my appointment?"
}
]
}
Loading

0 comments on commit 2fcbf06

Please sign in to comment.