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

feat(slack): add includeBotMessages option for interacting with bot_message #635

Merged
merged 1 commit into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/bottender/src/slack/SlackBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ export default class SlackBot extends Bot<
verificationToken,
origin,
skipLegacyProfile,
includeBotMessages,
}: {
accessToken: string;
sessionStore?: SessionStore;
sync?: boolean;
verificationToken?: string;
origin?: string;
skipLegacyProfile?: boolean | null;
skipLegacyProfile?: boolean;
includeBotMessages?: boolean;
}) {
const connector = new SlackConnector({
accessToken,
verificationToken,
origin,
skipLegacyProfile,
includeBotMessages,
});
super({ connector, sessionStore, sync });
this._accessToken = accessToken;
Expand Down
23 changes: 16 additions & 7 deletions packages/bottender/src/slack/SlackConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ type EventsAPIBody = {
export type SlackRequestBody = EventsAPIBody | { payload: string };

type CommonConstructorOptions = {
skipLegacyProfile?: boolean | null;
skipLegacyProfile?: boolean;
verificationToken?: string;
includeBotMessages?: boolean;
};

type ConstructorOptionsWithoutClient = {
Expand All @@ -63,8 +64,14 @@ export default class SlackConnector

_skipLegacyProfile: boolean;

_includeBotMessages: boolean;

constructor(options: ConstructorOptions) {
const { verificationToken, skipLegacyProfile } = options;
const {
verificationToken,
skipLegacyProfile,
includeBotMessages,
} = options;
if ('client' in options) {
this._client = options.client;
} else {
Expand All @@ -83,15 +90,17 @@ export default class SlackConnector

this._verificationToken = verificationToken || '';

this._skipLegacyProfile =
typeof skipLegacyProfile === 'boolean' ? skipLegacyProfile : true;

if (!this._verificationToken) {
warning(
false,
'`verificationToken` is not set. Will bypass Slack event verification.\nPass in `verificationToken` to perform Slack event verification.'
);
}

this._skipLegacyProfile =
typeof skipLegacyProfile === 'boolean' ? skipLegacyProfile : true;

this._includeBotMessages = includeBotMessages || false;
}

_getRawEventFromRequest(body: SlackRequestBody): SlackRawEvent {
Expand Down Expand Up @@ -304,8 +313,8 @@ export default class SlackConnector
mapRequestToEvents(body: SlackRequestBody): SlackEvent[] {
const rawEvent = this._getRawEventFromRequest(body);

if (this._isBotEventRequest(body)) {
return []; // FIXME
if (!this._includeBotMessages && this._isBotEventRequest(body)) {
return [];
}

return [new SlackEvent(rawEvent)];
Expand Down
8 changes: 8 additions & 0 deletions packages/bottender/src/slack/SlackEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,14 @@ export default class SlackEvent implements Event<SlackRawEvent> {
}
return null;
}

/**
* Determine if the event is a bot message event.
*
*/
get isBotMessage(): boolean {
return (this._rawEvent as any).subtype === 'bot_message';
}
}

// https://api.slack.com/events
Expand Down
19 changes: 19 additions & 0 deletions packages/bottender/src/slack/__tests__/SlackConnector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const RtmMessage = {
function setup({
verificationToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
skipLegacyProfile,
includeBotMessages,
} = {}) {
const mockSlackOAuthClient = {
getUserInfo: jest.fn(),
Expand All @@ -164,6 +165,7 @@ function setup({
accessToken,
verificationToken,
skipLegacyProfile,
includeBotMessages,
}),
mockSlackOAuthClient,
};
Expand Down Expand Up @@ -396,6 +398,23 @@ describe('#mapRequestToEvents', () => {
expect(events).toHaveLength(1);
expect(events[0]).toBeInstanceOf(SlackEvent);
});

it('should not include bot message by default', () => {
const { connector } = setup();
const events = connector.mapRequestToEvents(botRequest.body);

expect(events).toHaveLength(0);
});

it('should include bot message when includeBotMessages is true', () => {
const { connector } = setup({
includeBotMessages: true,
});
const events = connector.mapRequestToEvents(botRequest.body);

expect(events).toHaveLength(1);
expect(events[0]).toBeInstanceOf(SlackEvent);
});
});

describe('#createContext', () => {
Expand Down
15 changes: 15 additions & 0 deletions packages/bottender/src/slack/__tests__/SlackEvent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@ const message = {
ts: '1355517523.000005',
};

const botMessage = {
type: 'message',
subtype: 'bot_message',
ts: '1358877455.000010',
text: 'Pushing is the answer',
botId: 'BB12033',
username: 'github',
icons: {},
};

const channelsMessage = {
type: 'message',
channel: 'C2147483705',
Expand Down Expand Up @@ -894,3 +904,8 @@ describe('interactive message event', () => {
expect(new SlackEvent(message).action).toEqual(null);
});
});

it('#isBotMessage', () => {
expect(new SlackEvent(message).isBotMessage).toEqual(false);
expect(new SlackEvent(botMessage).isBotMessage).toEqual(true);
});