Adding initial system for middlewares
- This will allow people to write middlewares for different channelIds - Adding default TextMiddleware - Currently reply looks into channelId for composing a message, this might need some more refinement; possibly custom response type will solve the problem. While this lays foundation it is in no way complete and adding some middlewares will open up all the rough edges. Writing unit test is next.
This commit is contained in:
Родитель
518c8571f7
Коммит
b89d0900c7
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"arrow_spacing": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"braces_spacing": {
|
||||
"level": "ignore",
|
||||
"spaces": 0,
|
||||
"empty_object_spaces": 0
|
||||
},
|
||||
"camel_case_classes": {
|
||||
"level": "error"
|
||||
},
|
||||
"coffeescript_error": {
|
||||
"level": "error"
|
||||
},
|
||||
"colon_assignment_spacing": {
|
||||
"level": "ignore",
|
||||
"spacing": {
|
||||
"left": 0,
|
||||
"right": 0
|
||||
}
|
||||
},
|
||||
"cyclomatic_complexity": {
|
||||
"level": "ignore",
|
||||
"value": 10
|
||||
},
|
||||
"duplicate_key": {
|
||||
"level": "error"
|
||||
},
|
||||
"empty_constructor_needs_parens": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"ensure_comprehensions": {
|
||||
"level": "warn"
|
||||
},
|
||||
"eol_last": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"indentation": {
|
||||
"value": 4,
|
||||
"level": "error"
|
||||
},
|
||||
"line_endings": {
|
||||
"level": "ignore",
|
||||
"value": "unix"
|
||||
},
|
||||
"max_line_length": {
|
||||
"value": 256,
|
||||
"level": "error",
|
||||
"limitComments": true
|
||||
},
|
||||
"missing_fat_arrows": {
|
||||
"level": "ignore",
|
||||
"is_strict": false
|
||||
},
|
||||
"newlines_after_classes": {
|
||||
"value": 3,
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_backticks": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_debugger": {
|
||||
"level": "warn",
|
||||
"console": false
|
||||
},
|
||||
"no_empty_functions": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_empty_param_list": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_implicit_braces": {
|
||||
"level": "ignore",
|
||||
"strict": true
|
||||
},
|
||||
"no_implicit_parens": {
|
||||
"level": "ignore",
|
||||
"strict": true
|
||||
},
|
||||
"no_interpolation_in_single_quotes": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_nested_string_interpolation": {
|
||||
"level": "warn"
|
||||
},
|
||||
"no_plusplus": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_private_function_fat_arrows": {
|
||||
"level": "warn"
|
||||
},
|
||||
"no_stand_alone_at": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_tabs": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_this": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_throwing_strings": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_trailing_semicolons": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_trailing_whitespace": {
|
||||
"level": "error",
|
||||
"allowed_in_comments": false,
|
||||
"allowed_in_empty_lines": true
|
||||
},
|
||||
"no_unnecessary_double_quotes": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_unnecessary_fat_arrows": {
|
||||
"level": "warn"
|
||||
},
|
||||
"non_empty_constructor_needs_parens": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"prefer_english_operator": {
|
||||
"level": "ignore",
|
||||
"doubleNotLevel": "ignore"
|
||||
},
|
||||
"space_operators": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"spacing_after_comma": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"transform_messes_up_line_numbers": {
|
||||
"level": "warn"
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
#
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# Licensed under the MIT license.
|
||||
#
|
||||
#
|
||||
# Microsoft Bot Framework: http://botframework.com
|
||||
#
|
||||
#
|
||||
# Bot Builder SDK Github:
|
||||
# https://github.com/Microsoft/BotBuilder
|
||||
#
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# MIT License:
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -18,10 +18,10 @@
|
|||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
@ -31,58 +31,62 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
|
||||
Util = require 'util'
|
||||
Timers = require 'timers'
|
||||
|
||||
BotBuilder = require 'botbuilder'
|
||||
{Robot, Adapter, TextMessage, User} = require 'hubot'
|
||||
{ Robot, Adapter, TextMessage, User } = require 'hubot'
|
||||
{ registerMiddleware, middlewareFor } = require './middlewares'
|
||||
|
||||
LogPrefix = "hubot-botframework:"
|
||||
LogPrefix = "hubot-botframework-adapter:"
|
||||
|
||||
class BotFrameworkAdapter extends Adapter
|
||||
constructor: (@robot) ->
|
||||
super @robot
|
||||
|
||||
constructor: (robot) ->
|
||||
super robot
|
||||
@appId = process.env.BOTBUILDER_APP_ID
|
||||
@appPassword = process.env.BOTBUILDER_APP_PASSWORD
|
||||
@endpoint = process.env.BOTBUILDER_ENDPOINT || "/api/messages"
|
||||
@robot.logger.info "#{LogPrefix} Adapter loaded. Using appId #{@appId}"
|
||||
|
||||
@connector = new BotBuilder.ChatConnector
|
||||
@connector = new BotBuilder.ChatConnector {
|
||||
appId: @appId
|
||||
appPassword: @appPassword
|
||||
}
|
||||
|
||||
@connector.onEvent (events, cb) => @onBotEvents events, cb
|
||||
|
||||
using: (name) ->
|
||||
MiddlewareClass = middlewareFor(name)
|
||||
new MiddlewareClass(@robot)
|
||||
|
||||
onBotEvents: (activities, cb) ->
|
||||
@robot.logger.info "#{LogPrefix} onBotEvents"
|
||||
activities = [activities] unless Array.isArray activities
|
||||
@handleActivty activity for activity in activities
|
||||
|
||||
handleActivty: (activity) ->
|
||||
@robot.logger.info "#{LogPrefix} Handling activity Channel: #{activity.source}; type: #{activity.type}"
|
||||
@robot.receive @using(activity.source).toReceivable(activity)
|
||||
|
||||
for activity in activities
|
||||
address = activity.address
|
||||
user = @robot.brain.userForId address.user.id, name: address.user.name, room: address.conversation.id
|
||||
user.activity = activity
|
||||
if activity.type == 'message'
|
||||
@robot.receive new TextMessage(user, activity.text, activity.sourceEvent.clientActivityId)
|
||||
send: (context, messages...) ->
|
||||
@robot.logger.info "#{LogPrefix} send"
|
||||
console.log(messages)
|
||||
@reply context, messages...
|
||||
|
||||
send: (context, strings...) ->
|
||||
@robot.logger.info "#{LogPrefix} Message"
|
||||
@reply context, strings...
|
||||
|
||||
reply: (context, strings...) ->
|
||||
@robot.logger.info "#{LogPrefix} Sending reply"
|
||||
for str in strings
|
||||
msg =
|
||||
type: 'message'
|
||||
text: str
|
||||
address: context.user.activity.address
|
||||
@connector.send [msg]
|
||||
|
||||
reply: (context, messages...) ->
|
||||
@robot.logger.info "#{LogPrefix} reply"
|
||||
for msg in messages
|
||||
channelId = msg.channelId || '*'
|
||||
payload = [@using(channelId).toSendable(context, msg)]
|
||||
@connector.send payload, (err, _) -> throw err if err
|
||||
|
||||
run: ->
|
||||
@robot.router.post @endpoint, @connector.listen()
|
||||
@robot.logger.info "#{LogPrefix} Adapter running."
|
||||
Timers.setTimeout(=> @emit "connected", 1000)
|
||||
Timers.setTimeout (=> @emit "connected"), 1000
|
||||
|
||||
exports.use = (robot) ->
|
||||
new BotFrameworkAdapter robot
|
||||
new BotFrameworkAdapter robot
|
||||
|
||||
exports.middlewares = require './middlewares'
|
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# Licensed under the MIT license.
|
||||
#
|
||||
# Microsoft Bot Framework: http://botframework.com
|
||||
#
|
||||
# Bot Builder SDK Github:
|
||||
# https://github.com/Microsoft/BotBuilder
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
# MIT License:
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
{ Robot, TextMessage, Message, User } = require 'hubot'
|
||||
|
||||
LogPrefix = "hubot-botframework-middleware:"
|
||||
|
||||
class BaseMiddleware
|
||||
constructor: (@robot) ->
|
||||
@robot.logger.info "#{LogPrefix} creating middleware..."
|
||||
|
||||
toReceivable: (activity) ->
|
||||
throw new Error('toReceivable not implemented')
|
||||
|
||||
toSendable: (context, message) ->
|
||||
throw new Error('toSendable not implemented')
|
||||
|
||||
class TextMiddleware extends BaseMiddleware
|
||||
toReceivable: (activity) ->
|
||||
@robot.logger.info "#{LogPrefix} TextMiddleware toReceivable"
|
||||
address = activity.address
|
||||
user = @robot.brain.userForId address.user.id, name: address.user.name, room: address.conversation.id
|
||||
user.activity = activity
|
||||
|
||||
if activity.type == 'message'
|
||||
return new TextMessage(user, activity.text, activity.sourceEvent.clientActivityId)
|
||||
|
||||
return new Message(user)
|
||||
|
||||
toSendable: (context, message) ->
|
||||
@robot.logger.info "#{LogPrefix} TextMiddleware toSendable"
|
||||
if typeof message is 'string'
|
||||
return {
|
||||
type: 'message'
|
||||
text: message
|
||||
address: context.user.activity.address
|
||||
}
|
||||
|
||||
message
|
||||
|
||||
Middlewares = {
|
||||
'*': TextMiddleware
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerMiddleware: (name, middleware) ->
|
||||
Middlewares[name] = middleware
|
||||
|
||||
middlewareFor: (name) ->
|
||||
Middlewares[name] || Middlewares['*']
|
||||
|
||||
BaseMiddleware
|
||||
TextMiddleware
|
||||
}
|
Загрузка…
Ссылка в новой задаче