Skip to content

Instantly share code, notes, and snippets.

@doppelganger9
Created March 31, 2018 21:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doppelganger9/c011d8d9322e267762bb4115cd2e8004 to your computer and use it in GitHub Desktop.
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.
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`);
}
@AlexPernot
Copy link

Thanks, you saved me quite some time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment