Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add smart reply to remove boilerplate #53

Merged
merged 15 commits into from
Apr 15, 2017
Merged

Add smart reply to remove boilerplate #53

merged 15 commits into from
Apr 15, 2017

Conversation

crccheck
Copy link
Contributor

@crccheck crccheck commented Apr 14, 2017

Why are we doing this?

Multitenant bots will have to specify page id when sending a message. To do that now, they would have to do messenger.send(senderId, responseObj, session._pageId), which is very not ideal. Luckily everything has been backwards compatible and the page routing logic has been hidden. This adds another backwards compatible change so bots only have to do reply(responseObj), and the state required has been tucked into the reply function.

Some other changes:

  • new test.env. I didn't want to add another .env, but I needed stuff in the test environment that isn't applicable to users. This means we can add comments to example.env

closes #50

Did you document your work?

Some missing docs have been added to the Readme, new functionality is there too, and existing docs are updated.

How can someone test these changes?

Steps to manually verify the change:

  1. npm i
  2. npm t

Link to an existing bot and make sure your existing bot works:

  1. npm link
  2. go to your bot
  3. npm link launch-vehicle-fbm
  4. run and test your bot

What possible risks or adverse effects are there?

  • The function signature for send is changed. But it's done in a backwards compatible change. That means that the arguments are currently introspected before being used, which adds a mess of code. We just have to hope to mature enough so the page config transition lets us delete the adapter code.
  • in Add plumbing for page specific operations #49, I made send(senderId, responseObj, pageId) but here I changed my mind and went with send(pageId, senderId, responseObj) because putting pageId at the end looked so hacky. Now the arguments are in a more logical order.
  • This seems like a lot of LOC, but it's almost all docs and tests. I'm not really happy with how many lines it is, but reading the diff, it seems reasonable.

What are the follow-up tasks?

  • log a deprecation warning when bot is launched w/o page config
  • none

Are there any known issues?

None

Did the test coverage decrease?

new code is covered

Copy link
Contributor

@stripethree stripethree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't try this yet, but going to now. Changes requested re: wanting more info on WIP comments.

src/app.js Outdated
@@ -181,6 +202,7 @@ class Messenger extends EventEmitter {
.then((session) => this.saveSession(session));
}

// WIP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear what this WIP is referring to. Doesn't seem to match anything in the follow-up tasks...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I was marking that these methods are vestigial from the beauty lens bot and they're kinda dead code at this point but we want to bring them back eventually. I didn't want to start yak shaving to bring them up to "code" 😸 to keep this PR smaller. But I wanted to leave a mark to remind myself to stop trying to work on them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, cool. Seems like good candidates for linking to issues.

src/app.js Outdated
debug('onAuth for user:%d with param: %j', senderId, optinRef);
}

/*
This is not an event triggered by Messenger, it is the post-back from the
static Facebook login page that is made to look similar to an 'event'
*/
// WIP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here.

src/app.js Outdated
@@ -355,17 +378,25 @@ class Messenger extends EventEmitter {
return this.cache.set(session._key, session);
}

send(recipientId/*: string|number */, messageData/*: Object */, pageId/*: string|void */)/* Promise<Object> */ {
send(arg1/*: string|number */, arg2/*: string|number|Object */, arg3/*: Object|void */)/* Promise<Object> */ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is going to be refactored into simpler logic, have you considered making the new paradigm a wrapper function for the time being and then we replace send down the line? This would also mean changing the third arg to the pageAccessToken rather than the ID, but I think that's a fair tradeoff since that is currently an optional arg and it would reduce LOC.

pageSend(pageId, recipientId, messageData) {
  const pageAccessToken = this.pages[pageId];
  return this.send(recipientId, messageData, pageAccessToken);
}
send(recipientId, messageData, accessToken) {
  // kills ~10 LOC here
  const pageAccessToken = accessToken || config.get('messenger.pageAccessToken');
  const options = {... }
  debug('message.send: %j', options);
  return reqPromise.post(options)
    ...
}

Later on, the contents of send can be merged into pageSend or send can be replace by pageSend.

Both approaches are a bit awkward TBH. I find the above alternative easier to follow and to me, it communicates more about where the code is headed. It does come with downsides though. In either case, I think some additional comments or a link to an issue describe the next steps would provide some useful context.

TL;DR - I'm okay with this even though it is a bit tough to read, but wanted to propose an alternative as a thought exercise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been working on this concept on and off for a few weeks. I think I thought of that approach but I can't remember why I didn't stick with it. I'll give it a shot with pageSend 👍

@stripethree
Copy link
Contributor

Tried with my test bot via enterprise-fbm and things are working as expected. Did not try it with the bot deployed on multiple pages.

@stripethree
Copy link
Contributor

stripethree commented Apr 14, 2017

Noticed that the previous version did not allow a single page to send with reply without a pages arg sent to Messenger. This is remedied with the latest updates; holding off on further review as Chris said there's a few more things coming. I'm liking what the application level bot code looks like (enterprise-fbm, for example below) esp. with the PR that also removes the need to call start.

const { Messenger, responses } = require('launch-vehicle-fbm');
const messenger = new Messenger();

messenger.start(); // gone soon...

messenger.on('text.greeting', ({reply, firstName}) => {
  reply(new responses.Text(`🤖  Beep bop boop. Well hello there, ${firstName}, I am a bot.`));
});

messenger.on('text.help', ({reply}) => {
  reply(new responses.Text('🤖  I am here to offer my services to assist you.'));
});

messenger.on('text', ({reply, senderId, text, source}) => {
  reply(new responses.Text(`Echo: "${text}"`));
});

messenger.on('message.image', ({reply, url}) => {
  reply(new responses.Image(url));
});

@crccheck
Copy link
Contributor Author

I'm moving this back to WIP to change some design. After IRL discussion, moving towards forcing {pages} is drastic since most bots will only have one page. It's a big step to ask people from doing new Messenger() to new Messenger({pages}) so I'm backtracking that and going to keep the config based stuff now so you only need to do new Messenger({pages}) if you need to support multiple pages.

@crccheck crccheck changed the title Add smart reply to remove boilerplate WIP Add smart reply to remove boilerplate Apr 14, 2017
@crccheck crccheck changed the title WIP Add smart reply to remove boilerplate Add smart reply to remove boilerplate Apr 14, 2017
Copy link
Contributor Author

@crccheck crccheck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok took off WIP again. I'm not liking how many LOC this is but it's almost all docs and tests.

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T123456/B33Z/Pajamas
SLACK_CHANNEL=channel
LOG_FILE=/var/log/my-bot/chat.log
ALLOW_CONFIG_MUTATIONS=Y
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALLOW_CONFIG_MUTATIONS is the new config I needed. This will let you do PORT=-1 in #54 without potentially confusing users.

Copy link
Contributor

@stripethree stripethree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on a test bot with both the old and new way, without passing in pages to the Messenger constructor.

this.pages = {[config.get('facebook.pageId')]: config.get('messenger.pageAccessToken')};
} else {
this.pages = {};
debug("MISSING options.pages; you won't be able to reply or get profile information");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my favorite line in this PR. It shows how those two config variables are actually optional depending on what your bot is doing. While the SDK doesn't exactly gracefully degrade, we could make it.

@crccheck crccheck merged commit 2717a96 into master Apr 15, 2017
@crccheck crccheck deleted the smart-response/#50 branch April 15, 2017 00:26
@crccheck
Copy link
Contributor Author

I did a test w/ slack ghost just now too and 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add messenger.send helper to reduce boilerplate
2 participants