Closed jflaflamme closed 6 years ago
Hi Jean-Francois,
I understand the need to extend the receiver, the chat-platform.js uses a pattern similar to express.js, it creates a server that can be expanded chaining middlewares. So for its own nature it can be extended, unfortunately the documentation is missing, but I can work on that.
I don’t like very much the idea of the second pin, the first reason is above, the second is that once the extended feature is included in the core of RedBot, it breaks older installation since the new message starts going through the first pin rather then the second catch-all pin.
I’ve a couple ideas about that, let’s catch up on monday and help me figure out which is the best.
Thanks for you interest in RedBot and have a good week end
Guido Il 22 giu 2018, 17:30 +0200, Jean-Francois Laflamme notifications@github.com, ha scritto:
Hello @guidone I saw the pass-thru branch and some work regarding different receivers but not for other types than messages. Any plans to make it work in a near future? Otherwise, I was thinking to do another output pin for all unsupported event types in facebook receiver node. I forked and tried to implement via chat-platform.js to use a new function "unsupportedMessage" instead of inboundMessage but a bit stuck on the return part, seem not possible to return directly there :-) chat-platform.js function unsupportedMessage(payload, chatServer) { if (chatServer.isDebug()) { // eslint-disable-next-line no-console console.log(orange('-- INBOUND MESSAGE --')); // eslint-disable-next-line no-console console.log(prettyjson.render(payload)); // eslint-disable-next-line no-console console.log(''); } return [null, payload] } facebook-chat.js var unsupportedEvents = entry.changes; // for non-messenging (other webhooks...) _(unsupportedEvents).each(function (unsupportedEvent) { chatServer.receiveUnsupported(unsupportedEvent); } I could use http request node but I would lose all the magic of the FB receiver node :) use-case: same webhook URL for page events and messenger. Let me know your thoughts and if out of scope. Cheers for all the great work as usual! — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Ciao Jean-Francois,
If you give a look at facebook-chat.js you see that every kind of input message is handled by middlewares
For example
// get plain text messages
Facebook.in(function(message) {
return new Promise(function(resolve, reject) {
var chatContext = message.chat();
if (_.isString(message.originalMessage.message.text) && !_.isEmpty(message.originalMessage.message.text)) {
message.payload.content = message.originalMessage.message.text;
message.payload.type = 'message';
when(chatContext.set('message', message.payload.content))
.then(function () {
resolve(message);
}, function (error) {
reject(error);
});
} else {
resolve(message);
}
});
});
This intercepts the text message. It's possible to chain as many middleware as you like, the first middleware that resolve putting a value in message.payload.type skips the rest of the chain.
So handling unsupported message types it's just a matter of adding the right middleware. My idea is to put in the Facebook/Telegram/Slack configuration the same editor of the function node where it's possible to add middlewares
For example
server.in(function(message) {
return new Promise(function(resolve, reject) {
if (...) {
message.payload.content = 'some content';
message.payload.type = 'my-new-type';
}
resolve(message);
});
});
In the similar way it's possible to expand for outgoing messages. It's quite flexible, it's even possible to add asynchronous request on inbound/outbound requests, for example to send tracking info to collect stats in an external platform.
And if at some point the changes are merged into the main project, nothing breaks.
What do you think?
Grazie mille! Merci mille-fois!
I think it is a clever way of doing it without breaking any past/future message types and allowing new middlewares. That answer 100% of my problem and the problem also of debugging new message types in the future as a bonus.
I was currently running an express "reverse proxy" in front to send the request to the right endpoint depending on node-red on the content but I for sure prefer to keep this maintainable.
Happy to test a branch :-)
Hi,
where this entry.changes
come from, I was not able to find them in the documentation?
var unsupportedEvents = entry.changes; // for non-messenging (other webhooks...)
_(unsupportedEvents).each(function (unsupportedEvent) {
chatServer.receiveUnsupported(unsupportedEvent);
}
Hello @guidone
This is part of the payload from Facebook.
Hi, here is the beta
npm install node-red-contrib-chatbot@0.13.4-beta-1
Here some documentation
https://github.com/guidone/node-red-contrib-chatbot/wiki/Extend-node
Is adds a new node where it's possible to extend the connector.
In facebook messenger these messages (https://developers.facebook.com/docs/graph-api/webhooks/) are routed to the connector and can be handled by a middleware in the extend node
Thanks for that @guidone that is the perfect approach.
However, I have errors even before going thru the extend node.
I think this condition should check of message exists before (in this case, it is a changes type)
I
if (_.isString(message.originalMessage.message.text) && !_.isEmpty(message.originalMessage.message.text)) {
Full debug info
-- INBOUND MESSAGE --
changes:
-
field: feed
value:
from:
id: 1431850056628523
name: Getloy
item: status
post_id: 1431850056128523_1719052135208312
verb: add
published: 0
created_time: 1530235035
message: hello
id: 123456789
time: 1530235038
-------------------------- Error in chat-platform.js ---------------------------
TypeError: Cannot read property 'text' of undefined
at /usr/src/node-red/node_modules/node-red-contrib-chatbot/lib/chat-platform/chat-platform.js:307:13
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
function (message) {
return new Promise(function(resolve, reject) {
var chatContext = message.chat();
if (_.isString(message.originalMessage.message.text) && !_.isEmpty(message.originalMessage.message.text)) {
message.payload.content = message.originalMessage.message.text;
message.payload.type = 'message';
when(chatContext.set('message', message.payload.content))
.then(function () {
resolve(message);
}, function (error) {
reject(error);
});
} else {
resolve(message);
}
});
}
29 Jun 01:17:22 - [error] [chatbot-facebook-node:a4313c6.1b49cc] TypeError: Cannot read property 'text' of undefined
at Object.dump (/usr/src/node-red/node_modules/node-red-contrib-chatbot/lib/helpers/lcd.js:27:13)
at /usr/src/node-red/node_modules/node-red-contrib-chatbot/lib/chat-platform/chat-platform.js:307:13
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
I have created a pull request. https://github.com/guidone/node-red-contrib-chatbot/pull/219
Ok, I've cherry picked your commits, some check here and there and I'll merge.
I'd like to improve the list of handled message types in a way that if the user improve a platform by adding an handler for a message type, this type appears on the types dropdown in the Rules node
.
But I think I'll add this in the next branch
Thank you for that, awesome collaboration, I am closing the issue :)
Hello @guidone
I saw the pass-thru branch and some work regarding different receivers but not for other types than messages. Any plans to make it work in a near future?
Otherwise, I was thinking to do another output pin for all unsupported event types in facebook receiver node. I forked and tried to implement via chat-platform.js to use a new function "unsupportedMessage" instead of inboundMessage but a bit stuck on the return part, seem not possible to return directly there :-)
chat-platform.js
facebook-chat.js
I could use http request node but I would lose all the magic of the FB receiver node :) use-case: same webhook URL for page events and messenger.
Let me know your thoughts and if out of scope. Cheers for all the great work as usual!