Created
March 31, 2018 21:40
-
-
Save doppelganger9/c011d8d9322e267762bb4115cd2e8004 to your computer and use it in GitHub Desktop.
NodeJS Script to convert DialogFlow exported project for Alexa to new Alexa Skill Kit Interaction model schema.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as fs from 'fs'; | |
/** | |
* put your Exported to Alexa DialogFlow project in the `alexa-export` directory | |
* run this script, it will generate an IntentSchemaV2.json that should pass the new | |
* Alexa Skill Kit schema definition validations. | |
* This is based on my project, it is by no means exhaustive, feel free to fork and | |
* add what you need. | |
*/ | |
// you can adapt this to whatever dir name you unzipped the exported DialogFlow project for Alexa | |
const ALEXA_EXPORT_DIR = 'alexa-export'; | |
// CHANGE THIS! put your invocation name here. | |
const invocationName = 'change this'; | |
const INTENTS_FILE = `${ALEXA_EXPORT_DIR}/IntentSchema.json`; | |
const TYPES_DIR = `${ALEXA_EXPORT_DIR}/customSlotTypes/`; | |
const UTTERANCES_FILE = `${ALEXA_EXPORT_DIR}/SampleUtterances.txt`; | |
// ------------------------------------------------------------------------------------------ | |
/* what this script does is */ checkExpectationsOrExit() && convertToNewASKInteractionModelAndSaveTo(`${ALEXA_EXPORT_DIR}/IntentSchemaV2.json`); | |
// ------------------------------------------------------------------------------------------ | |
function checkExpectationsOrExit() { | |
if (!fs.existsSync(INTENTS_FILE)) { | |
console.error(`file ${INTENTS_FILE} not found`); | |
process.exit(1); | |
} | |
if (!fs.existsSync(UTTERANCES_FILE)) { | |
console.error(`file ${UTTERANCES_FILE} not found`); | |
process.exit(1); | |
} | |
if (!fs.existsSync(TYPES_DIR)) { | |
console.error(`directory ${TYPES_DIR} not found`); | |
process.exit(1); | |
} | |
return true; | |
} | |
function convertToNewASKInteractionModelAndSaveTo(exportedFileName) { | |
const intentSchemaJson = fs.readFileSync(INTENTS_FILE, { encoding: 'utf-8' }); | |
const sampleUtterancesText = fs.readFileSync(UTTERANCES_FILE, { encoding: 'utf-8' }); | |
// Alexa Rules | |
// Intent names must begin with an alphabetic character and may only contain alphabets, periods, and underscores | |
// remove '?', '+', '!', 'ç' from intent names, then deduplicates | |
// Samples cannot contain '?', '+', '-' (must sanitize them, then deduplicates) | |
const dedup = samples => { | |
return [...new Set(samples.map(sanitize))]; | |
}; | |
const sanitize = text => { | |
if (/[\?\!]/.test(text)) { | |
return text.replace(/[\?\!]/, ''); | |
} | |
if (/ç/i.test(text)) { | |
return text.replace(/ç/i, 'c'); | |
} | |
if (/\+/.test(text)) { | |
return text.replace(/\+/, 'plus'); | |
} | |
if (/\-/.test(text)) { | |
return text.replace(/\-/, 'moins'); | |
} | |
return text; | |
}; | |
const newIntentSchema = { | |
interactionModel: { | |
languageModel: { | |
invocationName, | |
intents: [ | |
{ | |
name: 'AMAZON.CancelIntent', | |
samples: [], | |
}, | |
{ | |
name: 'AMAZON.HelpIntent', | |
samples: [], | |
}, | |
{ | |
name: 'AMAZON.StopIntent', | |
samples: [], | |
}, | |
// default intents, don't know yet if it is required or not. | |
// we'll merge them with ours. | |
] | |
.concat( | |
JSON.parse(intentSchemaJson).intents.map(x => { | |
return { | |
name: x.intent, | |
slots: x.slots, | |
samples: sampleUtterancesText | |
.split('\n') | |
.filter(u => u.startsWith(x.intent + '\t')) | |
.map(u => u.split('\t')[1].trim()), | |
}; | |
}), | |
) | |
// here we sanitize and dedup samples and intent names to avoid "Build Model" errors | |
.map(intent => { | |
return { | |
...intent, | |
name: sanitize(intent.name), | |
samples: dedup(intent.samples), | |
}; | |
}), | |
types: fs.readdirSync(TYPES_DIR).map(type => { | |
return { | |
name: type, | |
values: fs | |
.readFileSync(TYPES_DIR + type, { encoding: 'utf-8' }) | |
.split('\n') | |
.filter(x => x.length > 0) | |
.map(x => { | |
return { | |
name: { | |
value: x, | |
}, | |
}; | |
}), | |
}; | |
}), | |
}, | |
}, | |
}; | |
fs.writeFileSync(exportedFileName, JSON.stringify(newIntentSchema, null, 2), { encoding: 'utf-8' }); | |
console.log(`wrote ${exportedFileName} file`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, you saved me quite some time!