Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Add support for multiple attachments #8

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

ecridge
Copy link

@ecridge ecridge commented Jun 26, 2018

This changeset allows responses to be checked for multiple attachments, sensitive to their number, order, and type. It also allows for the text body sent along with the attachments to be (optionally) checked just like it is for a plain response, and makes it trivial to add support for more attachment types in the future.

The YAML syntax is unchanged (save for the addition of an <OTHER> attachment type as a catch-all), and these changes should be fully backwards compatible. To achieve this, I made two compromises, which I think are fairly natural for users: (1) attachments must come at the end of the message spec; and (2) the text body of a response is not checked if the message spec consists only of attachments.

@ecridge
Copy link
Author

ecridge commented Jun 26, 2018

@lingz one area I could use your input on is how to make sure that the output is still friendly when a response fails to match

@lingz
Copy link
Contributor

lingz commented Jun 26, 2018

Hey Joe,

Thanks a lot for this, I will do a full review tomorrow but cursory inspection looks good. A quick idea I have would be,

Attachment mismatch:
Expected: 2 Images, 1 Button
Got: No Attachments

Something like this might work?

Copy link
Contributor

@lingz lingz left a comment

Choose a reason for hiding this comment

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

Joe this looks really nice to me, apart from small comments, the only suggestion would be to make the breaking change now to prevent technical debt accumulation, since the number of users is relatively low. I'll increment the major version number to let people know, but if you add the note to README.md, that would be great. If you fix these, I can merge this and release on npm.

README.md Outdated

Tag | Meaning
--- | ---
`<CARDS>` | Any card attachment
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the docs here. I would just add a comment here that includes buttons, as this might not be obvious to them.

README.md Outdated
--- | ---
`<CARDS>` | Any card attachment
`<IMAGE>` | Any image attachment
`<OTHER>` | Any other type of attachment
Copy link
Contributor

Choose a reason for hiding this comment

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

Add some examples below here.

src/runner.ts Outdated
@@ -156,7 +156,7 @@ export class Runner {
if (response !== null) {
if (program.verbose) {
const timing = (new Date().getTime() - this.timing) || 0;
if (response.messageTypes.includes(MessageType.Text)) {
if (response.attachments.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems wrong? Should be if (response.text). Also, for printing, we should probably print the attachments if they exist like:

Bot: Here you go: <IMAGE> <BUTTON> <BUTTON>

I know this is not how it is before but this would bring it into consistency with the new formatting style.

Copy link
Author

Choose a reason for hiding this comment

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

Ah good catch, thanks.

this.textMatchChecker = new RegExp(Response.transformTags(this.original));
this.bodyText = this.original;

// Construct a list of attachments from the attachment wildcards at the
Copy link
Contributor

Choose a reason for hiding this comment

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

I like this solution, it's nice. Though I wonder why you constrain it to happening at the end of the line? Seems a bit artificial to me?

Copy link
Author

Choose a reason for hiding this comment

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

In principle they could go anywhere, but I’m not sure what the use case would be. For example:

Dialogue:
  - Human: How is my campaign doing?
  - Bot: According to <IMAGE> and <IMAGE>, it’s going great!

This doesn’t make any sense in bot framework per se, because it doesn’t define a mechanism for embedding attachments inline with the text. Presumably you would expect attachments to be [Attachment.Image, Attachment.Image], but is text supposed to be 'According to', or 'According to and , it’s going great!, or something else?

You can imagine a client which does support this (e.g. one that uses $0, $1, … to reference attachments in the attachments array), in which case you could check that text === 'According to $0 and $1, it’s going great!', and that attachments[0] === Attachment.Image and attachments[1] === Attachment.Image; but in the absence of an established convention I’m not sure how useful this would be.

Copy link
Contributor

@lingz lingz Jun 27, 2018

Choose a reason for hiding this comment

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

Actually you are right that the botbuilder platform specifically limits this ordering. However, for other platforms like Slack, it is allowed to have intermingled text + attachments, so for that reason it might be good to allow the tags anywhere, and just concatenate the text.

It could lead to this edge case where someone sends

Hi <IMAGE> there <IMAGE>

and it validates against:

HI there <IMAGE> <IMAGE>

However at the same time, we could introduce this fix as a separate PR as you don't have any example connector right now, so it would be hard to test. For now we can concatenate and it will work for most practical use cases I think.

So to summarize I think for now a good compromise is to just drop the ordering condition (remove the $ on the regex parser).

// simple array of strings.

// Check that we have the right number of attachments.
if (JSON.stringify(this.attachments) !== JSON.stringify(message.attachments)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Stringify has this tricky behavior where ordering of keys is only guaranteed in Node environment IF the object is the same (same pointer). Even if two objects look the same, they will not necessarily get stringified in the same way.

Use https://github.com/substack/json-stable-stringify to do a sort before the stringify.

Copy link
Author

@ecridge ecridge Jun 27, 2018

Choose a reason for hiding this comment

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

Interesting. I assumed that stringifying an Array<String> would be safe. If you like I can just revert ac0dd3b to avoid bringing in another library?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah that sounds like a good idea

})).to.be.true;
});
it('should ignore text with <IMAGE> if no text is expected', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually I think this should be a breaking change, and we can increment the major version of autobot to suggest this, and put a note in README.md

attachments: [Attachment.Image],
})).to.be.true;
});
it('should ignore text with <CARDS> if no text is expected', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, so I would reverse the test condition, and make it .to.be.false

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

Successfully merging this pull request may close these issues.

2 participants