{"id":13799497,"url":"https://github.com/primaryobjects/chatskills","last_synced_at":"2025-04-09T20:08:36.519Z","repository":{"id":57197301,"uuid":"54052300","full_name":"primaryobjects/chatskills","owner":"primaryobjects","description":"Run and debug Alexa skills on the command-line. Create bots. Run them in Slack. Run them anywhere!","archived":false,"fork":false,"pushed_at":"2023-01-16T13:48:05.000Z","size":78,"stargazers_count":181,"open_issues_count":2,"forks_count":22,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-09T20:08:28.321Z","etag":null,"topics":["alexa","alexa-sdk","alexa-skill","amazon","amazon-alexa","amazon-alexa-skill","amazon-echo","chatbot","chatbots","conversational-ui","echo","javascript","slack","slack-bot","slackbot"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/primaryobjects.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["primaryobjects"]}},"created_at":"2016-03-16T17:22:48.000Z","updated_at":"2025-03-22T20:10:47.000Z","dependencies_parsed_at":"2023-02-10T03:46:08.315Z","dependency_job_id":null,"html_url":"https://github.com/primaryobjects/chatskills","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primaryobjects%2Fchatskills","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primaryobjects%2Fchatskills/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primaryobjects%2Fchatskills/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primaryobjects%2Fchatskills/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/primaryobjects","download_url":"https://codeload.github.com/primaryobjects/chatskills/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103873,"owners_count":21048245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alexa","alexa-sdk","alexa-skill","amazon","amazon-alexa","amazon-alexa-skill","amazon-echo","chatbot","chatbots","conversational-ui","echo","javascript","slack","slack-bot","slackbot"],"created_at":"2024-08-04T00:01:03.343Z","updated_at":"2025-04-09T20:08:36.499Z","avatar_url":"https://github.com/primaryobjects.png","language":"JavaScript","readme":"Chatskills\r\n----------\r\n\r\nRun [Alexa](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/getting-started-guide) apps on the command-line. Run them in Slack. Run them anywhere! Supports Amazon Alexa skills and intents.\r\n\r\n```bash\r\n$ npm install chatskills\r\n```\r\n\r\nChatskills is a quick and easy way to run Alexa apps outside of Amazon. Easily create your skills and intents and run them right on the command-line!\r\n\r\nChatskills does not require a server and can run directly in the console. It can also run on the web, or Slack, or anywhere. It handles requests from multiple users and maintains session memory. When a user starts a conversation with one of the skills, the skill continues to execute within a session context, until the skill terminates.\r\n\r\nHere's what an Amazon Alexa app looks like, running on the command-line.\r\n\r\n## Example\r\n\r\n```\r\n\u003e chatskills, ask hello to say hi.\r\nHello, World!\r\n\u003e chatskills, ask horoscope for Scorpio.\r\nThings are looking up today for Scorpio.\r\n\u003e chatskills, ask funny to tell me a joke\r\nKnock knock.\r\n\u003e who's there?\r\nBanana.\r\n\u003e banana who\r\nKnock knock.\r\n\u003e whos there\r\nOrange.\r\n\u003e orange who?\r\nOrange you glad I didn't say banana?\r\n```\r\n\r\nIn this example, the user accesses three different skills: [hello](https://github.com/primaryobjects/chatskills/blob/master/test.js#L4-L15), [horoscope](https://github.com/primaryobjects/chatskills/blob/master/horoscope.js), and [funny](https://github.com/primaryobjects/chatskills/blob/master/funny.js).\r\n\r\n## Usage\r\n\r\nUsing chatskills is easy. Use the Alexa syntax to add a new skill, then create some intents. Here's a simple example.\r\n\r\n```javascript\r\nvar chatskills = require('chatskills');\r\n\r\n// Create a skill.\r\nvar hello = chatskills.app('hello');\r\n\r\n// Create an intent.\r\nhello.intent('helloWorld', {\r\n    'slots': {},\r\n    'utterances': [ '{to |}{say|speak|tell me} {hi|hello|howdy|hi there|hiya|hi ya|hey|hay|heya}' ]\r\n    },\r\n    function(req, res) {\r\n        res.say('Hello, World!');\r\n    }\r\n);\r\n\r\n// Respond to input.\r\nchatskills.respond('chatskills, ask hello to say hi', function(response) {\r\n    console.log(response);\r\n});\r\n```\r\n\r\nIn the above example, the utterances grammar automatically expands to match on the following phrases:\r\n\r\n```\r\nhelloWorld      to say hi\r\nhelloWorld      say hi\r\nhelloWorld      to speak hi\r\nhelloWorld      speak hi\r\nhelloWorld      to tell me hi\r\nhelloWorld      tell me hi\r\nhelloWorld      to say hello\r\nhelloWorld      say hello\r\nhelloWorld      to speak hello\r\nhelloWorld      speak hello\r\nhelloWorld      to tell me hello\r\nhelloWorld      tell me hello\r\nhelloWorld      to say howdy\r\n...\r\n```\r\n\r\nTo interact with the chatbot using this skill, say any of the target phrases. In the above example, we've used the phrase \"to say hi\", but you can match against any of the generated phrases. For example:\r\n\r\n```\r\n\u003e chatskills, ask hello to tell me hi\r\nHello, World!\r\n\u003e chatskills, ask hello to say hello\r\nHello, World!\r\n\u003e chatskills, ask hello to say howdy\r\nHello, World!\r\n```\r\n\r\n## Reading from the Console\r\n\r\nTo create a chatbot that runs locally on the console, just include a loop for reading input.\r\n\r\n```javascript\r\nvar readlineSync = require('readline-sync');\r\n\r\n// Console client.\r\nvar text = ' ';\r\nwhile (text.length \u003e 0 \u0026\u0026 text != 'quit') {\r\n    text = readlineSync.question('\u003e ');\r\n\r\n    // Respond to input.\r\n    chatskills.respond(text, function(response) {\r\n        console.log(response);\r\n    });\r\n}\r\n```\r\n\r\nIf you're using async calls in your skills (such as request, etc) then you'll want to use an async loop, instead of the while loop above. Here's an [example](https://github.com/primaryobjects/chatskills/blob/master/chatbot.js#L39).\r\n\r\n## Reading from Slack\r\n\r\nYou don't have to use just the console! You can run your chatbot anywhere, like Slack. See [here](https://gist.github.com/primaryobjects/e1a182c7ef2f8d33731e) for full example.\r\n\r\n```javascript\r\nvar SlackBot = require('slackbots');\r\nvar bot = new SlackBot({ token: token, name: 'awesome' });\r\n\r\n// Listen to slack messages.\r\nbot.on('message', function(message) {\r\n    // Reply to humans.\r\n    if (message.type == 'message' \u0026\u0026 message.text \u0026\u0026 message.subtype != 'bot_message') {\r\n        var author = getUserById(message.user);\r\n        var channel = getChannelById(message.channel);\r\n\r\n        // Respond to input, use author.name as the session id.\r\n        chatskills.respond(message.text, author.name, function(response) {\r\n            if (channel) {\r\n                // Public channel message.\r\n                bot.postMessageToChannel(channel.name, response);\r\n            }\r\n            else {\r\n                // Private message.\r\n                bot.postMessageToUser(author.name, response);\r\n            }\r\n        });\r\n    }\r\n});\r\n```\r\n\r\n![Chatskills running on Slack](https://raw.githubusercontent.com/primaryobjects/chatskills/master/images/chatskills-slack.png)\r\n\r\n## Creating a Skill\r\n\r\nSkills are programs that your chatbot can run. They consist of intents, which are composed of utterances (phrases to match from the user input), responses, and session memory. Each skill can access session memory, so you can store and retrieve variables to help with responding intelligently to the user.\r\n\r\nHere's an example of creating a new skill, named \"horoscope\".\r\n\r\n```javascript\r\nvar horoscope = chatskills.app('horoscope');\r\n```\r\n\r\n## Creating an Intent\r\n\r\nSkills are made up of intents. This is where input from the user is matched against an array of utterances. When a match is found, that intent is executed. An intent can get/set variables in the user session by calling ```req.get('variable')``` and ```req.set('variable', value)```. An intent can output a response by calling ```res.say('hello')```.\r\n\r\nHere's an example of creating a new intent for the skill \"horoscope\".\r\n\r\n```javascript\r\nhoroscope.intent('predict', {\r\n    'slots': {'SIGN':'LITERAL'},\r\n    'utterances': [ 'for {signs|SIGN}' ]\r\n    },\r\n    function(req, res) {\r\n        res.say('Things are looking up today for ' + req.get('SIGN') + '.');\r\n    }\r\n);\r\n```\r\n\r\nThis intent can be interacted with like this:\r\n\r\n```\r\n\u003e chatskills, ask horoscope for Scorpio\r\nThings are looking up today for Scorpio.\r\n```\r\n\r\n## Launching a Skill\r\n\r\nThere are two ways to begin running a skill.\r\n\r\n#### Using an Intent to \"Run\"\r\n\r\nThe first way to launch a skill is to create an intent such as, \"run\". This would let you enter: \"chatskills, ask [skillname] to run.\". Provided the intent has a return value of true (to keep the session alive), your skill will now be running.\r\n\r\nAn example of a \"run\" skill can be found in [guessinggame](https://github.com/primaryobjects/chatskills/blob/master/guessinggame.js).\r\n\r\n```javascript\r\napp.intent('run', {\r\n        \"slots\": {},\r\n        \"utterances\": [\"{to|} {run|start|go|launch}\"]\r\n    }, function(req, res) {\r\n        var prompt = \"Guess a number between 1 and 100!\";\r\n        res.say(prompt).reprompt(prompt).shouldEndSession(false);\r\n    }\r\n);\r\n```\r\n\r\n#### Using the Launch Method\r\n\r\nThe second way to launch a skill is to create a launch method to automatically run upon starting your app. Then simply call `chatskills.launch(app)` to start your skill. You can pass the skill or the name of the skill. You can also provide an optional unique sessionId.\r\n\r\nExample: `chatskills.launch(app)` or `chatskills.launch('horoscope')` or `chatskills.launch('horoscope', 'some-unique-id')`.\r\n\r\nHere's a complete [example](https://github.com/primaryobjects/chatskills/blob/master/hello.js).\r\n\r\n```javascript\r\nvar chatskills = require('./lib/chatskills');\r\nvar readlineSync = require('readline-sync');\r\n\r\n// Create a skill.\r\nvar hello = chatskills.app('hello');\r\n\r\n// Launch method to run at startup.\r\nhello.launch(function(req,res) {\r\n    res.say(\"Ask me to say hi!\");\r\n\r\n    // Keep session open.\r\n    res.shouldEndSession(false);\r\n});\r\n\r\n// Create an intent.\r\nhello.intent('helloWorld', {\r\n    'slots': {},\r\n    'utterances': [ '{to |}{say|speak|tell me} {hi|hello|howdy|hi there|hiya|hi ya|hey|hay|heya}' ]\r\n    },\r\n    function(req, res) {\r\n        res.say('Hello, World!');\r\n    }\r\n);\r\n\r\n// Start running our skill.\r\nchatskills.launch(hello);\r\n\r\n// Console client.\r\nvar text = ' ';\r\nwhile (text.length \u003e 0 \u0026\u0026 text != 'quit') {\r\n    text = readlineSync.question('\u003e ');\r\n\r\n    // Respond to input.\r\n    chatskills.respond(text, function(response) {\r\n        console.log(response);\r\n    });\r\n}\r\n```\r\n\r\n## Starting and Ending a Session\r\n\r\nWhen a user provides input, the input is matched against each skill and their list of intents. When a match is found, a new session starts, and the skill begins executing.\r\n\r\nWhen a session has started for a user, the activated skill's intent can get/set variable values within the session. This allows you to store and retrieve data.\r\n\r\nWhile a session is open for a user, all input from the user is directed to the activated skill. In this manner, the user does not need to re-request a skill (\"chatskills, ask hello to say hi\"). Instead, the user can simply provide text, which will be matched against the currently executing skill's intents.\r\n\r\nAn intent can keep a session open by returning `true` or by calling `res.shouldEndSession(false)` and end a session by returning `false` or by calling `res.shouldEndSession(true)`. An intent may also omit a return statement, which is the same as returning false.\r\n\r\nFor an example using session, see the [horoscope](https://github.com/primaryobjects/chatskills/blob/master/horoscope.js#L31) skill. Notice, the intent asks the user a question and then returns true to keep the session going. The intent only returns false once a valid response is given, thus, ending the session.\r\n\r\nIn summary, when a user session is open, all input from the user is directed to the skill. When a user session is ended, input from the user must be received in the format, \"chatskills, ask [SKILL] text\", to execute a new skill.\r\n\r\n## Session Timeout\r\n\r\nThe default session timeout is 1 hour of no input from the user. To change the session timeout, set ```chatskills.timeout = 3600```, where the value is specified in seconds. To disable session timeout, set the value to 0.\r\n\r\n## Changing the Chatbot Name\r\n\r\nThe default chatbot name is \"chatskills\". All requests to execute a skill must begin with the chatbot name. For example, \"chatskills, ask hello to say hi\". To customize the chatbot name, use the following:\r\n\r\n```javascript\r\nchatskills.name('awesome');\r\n```\r\n\r\n## Verbose Output\r\n\r\nTo display warnings and errors, set ```chatskills.verbose = true```.\r\n\r\n## Schema and Utterances\r\n\r\nChatskills uses [alexa-app](https://www.npmjs.com/package/alexa-app) to generate many sample utterances from your intents. For a more detailed description of utterances, see [here](https://www.npmjs.com/package/alexa-app#schema-and-utterances).\r\n\r\n### Schema Syntax\r\n\r\nPass an object with two properties: slots and utterances.\r\n\r\n```javascript\r\napp.intent('sampleIntent',\r\n    {\r\n        \"slots\":{\"NAME\":\"LITERAL\",\"AGE\":\"NUMBER\"}, \r\n        \"utterances\":[ \"my {name is|name's} {names|NAME} and {I am|I'm} {1-100|AGE}{ years old|}\" ]\r\n    },\r\n    function(request,response) { ... }\r\n);\r\n```\r\n\r\n#### Slots\r\n\r\nThe slots object is a simple Name:Type mapping. The type must be one of Amazon's supported slot types: LITERAL, NUMBER, DATE, TIME, DURATION\r\n\r\n#### Custom Slot Types\r\n\r\nAs a replacement for the `LITERAL` slot type, which is no longer being supported by Amazon, it is recommended to use custom slot types in its place. Here is an example of defining a custom slot type for `DragonType`.\r\n\r\n```javascript\r\napp.intent('attack', \r\n    {\r\n        'slots': { 'DragonType': 'DRAGONTYPE' },\r\n        'utterances': ['{attack|fight|hit|use} {sword|dagger|wand} on {-|DragonType} dragon']\r\n    }, function(request,response) {\r\n        response.say('You are attacking the ' + request.slot('DragonType') + ' dragon!');\r\n    }\r\n);\r\n```\r\n\r\nYou can include custom slot types within utterances by using the syntax `{-|CustomTypeName}`. This indicates that the term should come from a list of values for the custom slot type. In the example above, the utterance uses the term `{-|DragonType}`, indicating a term should come from the list of values (shown below). For chatskills, a list of values does not need to be provided - any word will be accepted for a custom slot type and used as its value.\r\n\r\nIf publishing to the Amazon Alexa service, you would provide the custom slot types for `DragonType` by specifying the type name and a list of values. For example:\r\n\r\nType:\r\n`DRAGONTYPE`\r\n\r\nValues:\r\n```\r\ngolden\r\nfire\r\nice\r\nwater\r\nsnow\r\n```\r\n\r\nNote, chatskills and Amazon Alexa will actually accept any word for the custom slot value. It doesn't have to match a word from the list of values. In this manner, custom slot types are similar to `LITERAL`.\r\n\r\n#### Utterances\r\n\r\nThe utterances syntax allows you to generate many (hundreds or even thousands) of sample utterances using just a few samples that get auto-expanded. Any number of sample utterances may be passed in the utterances array. Below are some sample utterances macros and what they will be expanded to.\r\n\r\n#### Multiple Options mapped to a Slot\r\n\r\n```\r\n\"my favorite color is {red|green|blue|NAME}\"\r\n=\u003e\r\n\"my favorite color is {red|NAME}\"\r\n\"my favorite color is {green|NAME}\"\r\n\"my favorite color is {blue|NAME}\"\r\n```\r\n\r\n#### Generate Multiple Versions of Static Text\r\n\r\nThis lets you define multiple ways to say a phrase, but combined into a single sample utterance\r\n\r\n```\r\n\"{what is the|what's the|check the} status\"\r\n=\u003e\r\n\"what is the status\"\r\n\"what's the status\"\r\n\"check the status\"\r\n```\r\n\r\n#### Auto-Generated Number Ranges\r\n\r\nWhen capturing a numeric slot value, it's helpful to generate many sample utterances with different number values\r\n\r\n```\r\n\"buy {2-5|NUMBER} items\"\r\n=\u003e\r\n\"buy {two|NUMBER} items\"\r\n\"buy {three|NUMBER} items\"\r\n\"buy {four|NUMBER} items\"\r\n\"buy {five|NUMBER} items\"\r\n```\r\n\r\nNumber ranges can also increment in steps\r\n\r\n```\r\n\"buy {5-20 by 5|NUMBER} items\"\r\n=\u003e\r\n\"buy {five|NUMBER} items\"\r\n\"buy {ten|NUMBER} items\"\r\n\"buy {fifteen|NUMBER} items\"\r\n\"buy {twenty|NUMBER} items\"\r\n```\r\n\r\n#### Optional Words\r\n\r\n```\r\n\"what is your {favorite |}color\"\r\n=\u003e\r\n\"what is your color\"\r\n\"what is your favorite color\"\r\n```\r\n\r\n#### Using a Dictionary\r\n\r\nSeveral intents may use the same list of possible values, so you want to define them in one place, not in each intent schema. Use the app's dictionary.\r\n\r\n```\r\napp.dictionary = {\"colors\":[\"red\",\"green\",\"blue\"]};\r\n...\r\n\"my favorite color is {colors|FAVEORITE_COLOR}\"\r\n\"I like {colors|COLOR}\"\r\n```\r\n\r\n## Displaying Home Cards\r\n\r\nYou can display Amazon Alexa Home [Cards](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/providing-home-cards-for-the-amazon-alexa-app#Creating%20a%20Home%20Card%20to%20Display%20Text%20and%20an%20Image) by handling the card [object](https://www.npmjs.com/package/alexa-app#card-examples) returned in the response method. When using alexa-app, the home card will be displayed in the Amazon Alexa App on your mobile device. When using chatskills, the home card can be handled in the `chatskills.respond()` callback method, which returns two arguments: `response` and `card`.\r\n\r\nUsing the card object, you can display the card's text and image in any manner you wish. For example, if hosting your chatskills app in Slack, you may want to show the image as embedded media. Likewise, if hosting as a text chatbot on the console, you may simply want to output the card as text.\r\n\r\nBelow is an example.\r\n\r\n```javascript\r\napp.intent('example', {\r\n        \"slots\": {},\r\n        \"utterances\": [\"show a card\"]\r\n    }, function(req, res) {\r\n      // Show home card in Alexa app.\r\n      res.card({\r\n        type: 'Standard',\r\n        title: 'My Awesome Card', // this is not required for type Simple or Standard \r\n        text: 'This is an example of an Alexa home card.',\r\n        image: { // image is optional \r\n          smallImageUrl: 'http://www.yoursite.com/image.jpg', // required \r\n          largeImageUrl: null\r\n        }\r\n      });\r\n});\r\n\r\n// Respond to input.\r\nchatskills.respond(text, function(response, card) {\r\n    if (!card) {\r\n      // Text response from res.say() method.\r\n      console.log(response);\r\n    }\r\n    else {\r\n      // Home card response from res.card() method.\r\n      console.log('[DISPLAYING CARD: Title=' + card.title + ', Text=' + card.text + ']');\r\n    }\r\n});\r\n```\r\n\r\nLicense\r\n----\r\n\r\nMIT\r\n\r\nAuthor\r\n----\r\n\r\nKory Becker\r\nhttp://www.primaryobjects.com/kory-becker","funding_links":["https://github.com/sponsors/primaryobjects"],"categories":["NPM Modules"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprimaryobjects%2Fchatskills","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprimaryobjects%2Fchatskills","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprimaryobjects%2Fchatskills/lists"}