Open dcsan opened 4 years ago
I'm not a big fan of transforming inputs in middleware. In my opinion, input events and input texts should be immutable. Just like we do not transform the keypress inputs when receiving keypress events in browser.
And also, it's hard to provide a powerful route without using a regex. For example, if I want to provide a route matches the following inputs:
help
Help
' help '
help....
help!
helpppppp
h e l p
We can't provide a built-in way to satisfy all user requirements. So, I'd like to leave it to the users, and they can build custom routes to solve this kind of case:
import { text, route } from 'bottender/router';
// instead of doing this
text(['h', 'help'], Help)
// you could write a custom route:
function myPowerfulTextRoute(strs, action) {
return route(
(context) =>
context.event.isText &&
strs.some(str => new RegExp(str, 'i').test(context.event.text)),
action
);
}
myPowerfulTextRoute(['h', 'help'], Help)
See: https://bottender.js.org/docs/en/the-basics-routing#custom-routes
This approach could still be applied if you would like to use binary classifer model instead of regexp in the future.
Thanks for writing this out. I'll refer to this technique in future.
I think this would work, but in the end I just wrote my own fallback system based on context.event.text
Another issue with bottender router is how it binds events. I have my own session objects (game objects) per user and wanted to dispatch directly to those, but when I did something like:
const game = findGame(context.session.id) // game instance for that user
// router
text('hi', game.greeting)
This won't work as the routes do something to self bind. It seems the events have to be static methods, not methods on an instance.
I did try a reacty
text('hi', () => { game.greeting })
No good. Perhaps there is some combination of this.bind
ing the methods I used for routes but I gave up and just ended up with my own routing system as a fallback. maybe you've seen this pattern before?
Is your feature request related to a problem? Please describe. when using the router methods, is there a way to parse the text we're matching against? I want to do some basic replacement for example
lowerCase
the inputs.I could use regex but the plain matches are nicer
Describe the solution you'd like A way to process incoming text. For example a middleware on the incoming request?
as well as the lowercase example above I also want to do some synonym replacement to normalize things. This is nicer than doing complex regex everywhere... just clean up the inputs
Describe alternatives you've considered using regex but it quickly gets hard to read.
Additional context overall I really like the router with the chained responsibility and the way you've integrated regex match routes...