Skip to content

Commit

Permalink
Merge branch 'master' into feature/first_command
Browse files Browse the repository at this point in the history
  • Loading branch information
fletcherist authored Jul 1, 2018
2 parents c00ee08 + c2339a8 commit 438044d
Show file tree
Hide file tree
Showing 24 changed files with 171 additions and 111 deletions.
20 changes: 9 additions & 11 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
module.exports = {
"parser": "babel-eslint",
"extends": "standard",
"plugins": [],
rules: {
'no-return-await': 0,
'space-before-function-paren': ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}]
}
extends: 'standard',
rules: {
'no-return-await': 0,
'space-before-function-paren': ['error', {
anonymous: 'always',
named: 'never',
asyncArrow: 'always'
}]
}
}
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<a name="1.1.9"></a>
## 1.1.9 (2018-06-30)


### Bug Fixes

* more strict fuse options ([979a019](https://github.com/fletcherist/yandex-dialogs-sdk/commit/979a019))
* searchRegexps always returns true ([c266eac](https://github.com/fletcherist/yandex-dialogs-sdk/commit/c266eac))



2 changes: 1 addition & 1 deletion examples/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ alice.command(['сколько стоит bitcoin', 'стоимость bitcoin'

// Example for regular expressions #3
alice.command(/(https?:\/\/[^\s]+)/g, ctx => {
return ctx.reply('I am matching any url you send me').
return ctx.reply('I am matching any url you send me.')
})

alice.any(async (ctx) => {
Expand Down
25 changes: 25 additions & 0 deletions examples/middlewares.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const Alice = require('../src/index')
const alice = new Alice()

const aliceCorsMiddleware = (params) => {
return ctx => {
if (ctx.server) {
ctx.server.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
next()
})
}
}
}
// now all requests will be answered with
// with cors headers
alice.use(aliceCorsMiddleware())

// Example for pure strings #1
alice.command('дай совет', async (ctx) => {
ctx.reply('Make const not var')
})

const port = 8080
alice.listen('/', port).then(console.log('listening on:', port))
16 changes: 10 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"name": "yandex-dialogs-sdk",
"version": "1.1.7",
"version": "1.1.9",
"description": "Build your skill for Alice with ease.",
"main": "src/index.js",
"scripts": {
"test": "jest"
"lint": "eslint src",
"test": "jest",
"version": "npm run changelog && git add CHANGELOG.md",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
"release": "conventional-github-releaser -p angular"
},
"repository": {
"type": "git",
Expand All @@ -28,19 +32,19 @@
},
"homepage": "https://github.com/fletcherist/yandex-dialogs-sdk#readme",
"dependencies": {
"body-parser": "^1.18.2",
"express": "^4.16.3",
"fuse.js": "^3.2.0",
"node-fetch": "^2.1.1",
"ramda": "^0.25.0"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"conventional-changelog-cli": "^2.0.0",
"conventional-github-releaser": "^3.1.0",
"eslint": "^4.19.0",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-import": "^2.10.0",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-promise": "^3.7.0",
"eslint-plugin-standard": "^3.0.1"
"eslint-plugin-standard": "^3.0.1",
"jest": "^23.2.0"
}
}
78 changes: 50 additions & 28 deletions src/alice.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
const express = require('express')
const bodyParser = require('body-parser')
const Commands = require('./commands')
const { Sessions, Session } = require('./sessions')
const { Sessions } = require('./sessions')
const { merge } = require('ramda')

const Ctx = require('./ctx')

const {
selectCommand,
selectSession,
selectSessionId,
selectUserId,
isFunction
} = require('./utils')

Expand All @@ -19,11 +16,12 @@ const DEFAULT_ANY_CALLBACK = () => 'Что-то пошло не так. Я не
class Alice {
constructor(config = {}) {
this.anyCallback = DEFAULT_ANY_CALLBACK
this.commands = new Commands()
this.commands = new Commands(config.fuseOptions || null)
this.middlewares = []
this.scenes = []
this.currentScene = null
this.sessions = new Sessions()
this.config = config

this._handleEnterScene = this._handleEnterScene.bind(this)
this._handleLeaveScene = this._handleLeaveScene.bind(this)
Expand All @@ -34,7 +32,15 @@ class Alice {

}

/*
* Attach alice middleware to the application
* @param {Function} middleware - function, that receives {context}
* and makes some modifications with it.
*/
use(middleware) {
if (!isFunction(middleware)) {
throw new Error('Any middleware could only be a function.')
}
this.middlewares.push(middleware)
}

Expand Down Expand Up @@ -72,31 +78,42 @@ class Alice {
async handleRequestBody(req, sendResponse) {
const requestedCommandName = selectCommand(req)

/* clear old sessions */
if (this.sessions.length > (this.config.sessionsLimit || 1000)) {
this.sessions.flush()
}

/* initializing session */
const sessionId = selectSessionId(req)
const session = this.sessions.findOrCreate(sessionId)

/* check whether current scene is not defined */
if (!session.data.currentScene) {
session.update({currentScene: null})
if (!session.getData('currentScene')) {
session.setData('currentScene', null)
}

/* give control to the current scene */
if (session.currentScene !== null) {
if (session.getData('currentScene') !== null) {
const matchedScene = this.scenes.find(scene => {
return scene.name === session.currentScene
})

/*
* Checking whether that's the leave scene
* activation trigger
*/
if (session.currentScene.isLeaveCommand(requestedCommandName)) {
session.currentScene.handleRequest(req, sendResponse)
session.currentScene = null
return true
} else {
const sceneResponse = await session.currentScene.handleRequest(
req, sendResponse
)
if (sceneResponse) {
if (matchedScene) {
if (matchedScene.isLeaveCommand(requestedCommandName)) {
matchedScene.handleRequest(req, sendResponse, session)
session.setData('currentScene', null)
return true
} else {
const sceneResponse = await matchedScene.handleRequest(
req, sendResponse, session
)
if (sceneResponse) {
return true
}
}
}
} else {
Expand All @@ -106,9 +123,9 @@ class Alice {
const matchedScene = this.scenes.find(scene =>
scene.isEnterCommand(requestedCommandName))
if (matchedScene) {
session.currentScene = matchedScene
const sceneResponse = await session.currentScene.handleRequest(
req, sendResponse
session.setData('currentScene', matchedScene.name)
const sceneResponse = await matchedScene.handleRequest(
req, sendResponse, session
)
if (sceneResponse) {
return true
Expand All @@ -119,22 +136,26 @@ class Alice {
let requestedCommands = this.commands.search(requestedCommandName)

/*
* Инициализация контекста запроса
* Initializing context of the request
*/
const ctxDefaultParams = {
req: req,
session: session,
sendResponse: sendResponse || null
sendResponse: sendResponse || null,
/*
* if Alice is listening on express.js port, add this server instance
* to the context
*/
server: this.server || null
}

/*
* Если новая сессия, то запускаем стартовую команду
*/
if (req.session.new && this.firstCommand) {
const ctx = new Ctx(ctxDefaultParams)
return await this.firstCommand.call(this, ctx)
return await this.firstCommand(ctx)
}

/*
* Команда нашлась в списке.
* Запускаем её обработчик.
Expand All @@ -144,15 +165,16 @@ class Alice {
const ctx = new Ctx(merge(ctxDefaultParams, {
command: requestedCommand
}))
return await requestedCommand.callback.call(this, ctx)

return await requestedCommand.callback(ctx)
}

/*
* Такой команды не было зарегестрировано.
* Переходим в обработчик исключений
*/
const ctx = new Ctx(ctxDefaultParams)
return await this.anyCallback.call(this, ctx)
return await this.anyCallback(ctx)
}

/*
Expand All @@ -173,10 +195,10 @@ class Alice {
async listen(callbackUrl = '/', port = 80, callback) {
return new Promise(resolve => {
const app = express()
app.use(bodyParser.json())
app.use(express.json())
app.post(callbackUrl, async (req, res) => {
const handleResponseCallback = response => res.send(response)
const replyMessage = await this.handleRequestBody(req.body, handleResponseCallback)
await this.handleRequestBody(req.body, handleResponseCallback)
})
this.server = app.listen(port, () => {
// Resolves with callback function
Expand Down
36 changes: 18 additions & 18 deletions src/button.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const button = params => {
// Button has been created from string
if (typeof params === 'string') {
return {
title: params
}
}
// Button has been created from string
if (typeof params === 'string') {
return {
title: params
}
}

if (typeof params === 'object') {
const {
if (typeof params === 'object') {
const {
title,
text,
tts,
Expand All @@ -17,20 +17,20 @@ const button = params => {
} = params

if (!title && !text) {
throw new Error('text is a required parameter')
throw new Error('text is a required parameter')
}

return {
title: title || text,
tts,
url,
hide,
payload
title: title || text,
tts,
url,
hide,
payload
}
}
}

// Handles when you pass neither String nor Object as button params
throw new Error('Invalid button constructor argument. Use String or Object instead.')
// Handles when you pass neither String nor Object as button params
throw new Error('Invalid button constructor argument. Use String or Object instead.')
}

module.exports = button
module.exports = button
2 changes: 1 addition & 1 deletion src/buttonBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ButtonBuilder {
throw new Error('Invalid ButtonBuilder constructor type. Should be object')
}
const {
title, text, url, shouldHide, payload
title, text
} = buttonConstructor
if (!title && !text) {
throw new Error('Button [title] or [text] is required for ButtonBuilder constructor.')
Expand Down
12 changes: 6 additions & 6 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ const TYPE_REGEXP = 'regexp'
const TYPE_ARRAY = 'array'

class Commands {
constructor(config = {}) {
constructor(config = null) {
this.commands = []
this.fuseOptions = {
this.fuseOptions = config || {
tokenize: true,
treshold: config.fuzzyTreshold || 0.1,
distance: config.fuzzyDistance || 10,
threshold: 0.1,
distance: 10,
keys: ['name']
}
}
Expand All @@ -36,7 +36,7 @@ class Commands {
_searchRegexps(requestedCommandName) {
const regexpCommands = this._regexps
// @TODO: include matches and captured groups
return regexpCommands.filter(reg => requestedCommandName.match(reg))
return regexpCommands.filter(reg => requestedCommandName.match(reg.name))
}

search(requestedCommandName) {
Expand Down Expand Up @@ -73,7 +73,7 @@ class Commands {

class Command {
constructor(name, callback) {
if (!name) throw new Error('Command name is not specified')
if (name === undefined) throw new Error('Command name is not specified')
this.name = name
this.callback = callback
this.type = this._defineCommandType(this.name)
Expand Down
2 changes: 1 addition & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
module.exports.ALICE_PROTOCOL_VERSION = '1.0'
module.exports.DEFAULT_END_SESSION = false
module.exports.DEFAULT_END_SESSION = false
Loading

0 comments on commit 438044d

Please sign in to comment.