Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Create app call response posts as bot (#7789) (#7859)
Browse files Browse the repository at this point in the history
* apps post as bot

show command error in correct thread

add AppMetadataForClient type

* fix tests

(cherry picked from commit edad2ed)

Co-authored-by: Michael Kochell <6913320+mickmister@users.noreply.github.com>
  • Loading branch information
mattermost-build and mickmister committed Apr 12, 2021
1 parent fa5f455 commit 08290f1
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 17 deletions.
2 changes: 1 addition & 1 deletion actions/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function executeCommand(message: string, args: CommandArgs): ActionFunc {
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
GlobalActions.sendEphemeralPost(callResp.markdown, args.channel_id, args.parent_id);
GlobalActions.sendEphemeralPost(callResp.markdown, args.channel_id, args.parent_id, callResp.app_metadata?.bot_user_id);
}
return {data: true};
case AppCallResponseTypes.ERROR:
Expand Down
4 changes: 2 additions & 2 deletions actions/global_actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,11 @@ export function showMobileSubMenuModal(elements: any[]) { // TODO Use more speci
dispatch(openModal(submenuModalData));
}

export function sendEphemeralPost(message: string, channelId?: string, parentId?: string): void {
export function sendEphemeralPost(message: string, channelId?: string, parentId?: string, userId?: string): void {
const timestamp = Utils.getTimestamp();
const post = {
id: Utils.generateId(),
user_id: '0',
user_id: userId || '0',
channel_id: channelId || getCurrentChannelId(getState()),
message,
type: PostTypes.EPHEMERAL,
Expand Down
2 changes: 1 addition & 1 deletion components/apps_form/apps_form_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class AppsFormContainer extends React.PureComponent<Props, State> {
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
sendEphemeralPost(callResp.markdown);
sendEphemeralPost(callResp.markdown, call.context.channel_id, call.context.root_id || call.context.post_id, callResp.app_metadata?.bot_user_id);
}
break;
case AppCallResponseTypes.FORM:
Expand Down
2 changes: 1 addition & 1 deletion components/dot_menu/dot_menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class DotMenu extends React.PureComponent<Props, State> {
const res = await this.props.actions?.doAppCall(call, AppCallTypes.SUBMIT, this.props.intl);

const callResp = (res as {data: AppCallResponse}).data;
const ephemeral = (message: string) => sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id);
const ephemeral = (message: string) => sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id, callResp.app_metadata?.bot_user_id);
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
data: {
type: 'ok',
markdown: 'Nice job!',
app_metadata: {
bot_user_id: 'botuserid',
},
},
}),
getChannel: jest.fn().mockResolvedValue({
Expand Down Expand Up @@ -81,7 +84,7 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
values: undefined,
}, 'submit', {});

expect(baseProps.sendEphemeralPost).toHaveBeenCalledWith('Nice job!', 'some_channel_id', 'some_root_id');
expect(baseProps.sendEphemeralPost).toHaveBeenCalledWith('Nice job!', 'some_channel_id', 'some_root_id', 'botuserid');
});

test('should handle error call response', async () => {
Expand All @@ -92,6 +95,9 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
data: {
type: 'error',
error: 'The error',
app_metadata: {
bot_user_id: 'botuserid',
},
},
}),
getChannel: jest.fn().mockResolvedValue({
Expand All @@ -108,6 +114,6 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
const wrapper = shallow<ButtonBindingUnwrapped>(<ButtonBindingUnwrapped {...props}/>);
await wrapper.instance().handleClick();

expect(props.sendEphemeralPost).toHaveBeenCalledWith('The error', 'some_channel_id', 'some_root_id');
expect(props.sendEphemeralPost).toHaveBeenCalledWith('The error', 'some_channel_id', 'some_root_id', 'botuserid');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Props = {
doAppCall: (call: AppCallRequest, type: AppCallType, intl: IntlShape) => Promise<ActionResult>;
getChannel: (channelId: string) => Promise<ActionResult>;
};
sendEphemeralPost: (message: string, channelID?: string, rootID?: string) => void;
sendEphemeralPost: (message: string, channelID?: string, rootID?: string, userID?: string) => void;
}

type State = {
Expand Down Expand Up @@ -69,7 +69,7 @@ export class ButtonBinding extends React.PureComponent<Props, State> {

this.setState({executing: false});
const callResp = (res as {data: AppCallResponse}).data;
const ephemeral = (message: string) => this.props.sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id);
const ephemeral = (message: string) => this.props.sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id, callResp.app_metadata?.bot_user_id);
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ describe('components/post_view/embedded_bindings/select_binding', () => {
data: {
type: 'ok',
markdown: 'Nice job!',
app_metadata: {
bot_user_id: 'botuserid',
},
},
}),
getChannel: jest.fn().mockResolvedValue({
Expand Down Expand Up @@ -120,7 +123,7 @@ describe('components/post_view/embedded_bindings/select_binding', () => {
values: undefined,
}, 'submit', {});

expect(props.sendEphemeralPost).toHaveBeenCalledWith('Nice job!', 'some_channel_id', 'some_root_id');
expect(props.sendEphemeralPost).toHaveBeenCalledWith('Nice job!', 'some_channel_id', 'some_root_id', 'botuserid');
});
});

Expand All @@ -132,6 +135,9 @@ describe('components/post_view/embedded_bindings/select_binding', () => {
data: {
type: 'error',
error: 'The error',
app_metadata: {
bot_user_id: 'botuserid',
},
},
}),
getChannel: jest.fn().mockResolvedValue({
Expand All @@ -152,6 +158,6 @@ describe('components/post_view/embedded_bindings/select_binding', () => {
value: 'option1',
});

expect(props.sendEphemeralPost).toHaveBeenCalledWith('The error', 'some_channel_id', 'some_root_id');
expect(props.sendEphemeralPost).toHaveBeenCalledWith('The error', 'some_channel_id', 'some_root_id', 'botuserid');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type Props = {
doAppCall: (call: AppCallRequest, type: AppCallType, intl: IntlShape) => Promise<ActionResult>;
getChannel: (channelId: string) => Promise<ActionResult>;
};
sendEphemeralPost: (message: string, channelID?: string, rootID?: string) => void;
sendEphemeralPost: (message: string, channelID?: string, rootID?: string, userID?: string) => void;
};

type State = {
Expand Down Expand Up @@ -99,7 +99,7 @@ export class SelectBinding extends React.PureComponent<Props, State> {

const res = await this.props.actions.doAppCall(call, AppCallTypes.SUBMIT, this.props.intl);
const callResp = (res as {data: AppCallResponse}).data;
const ephemeral = (message: string) => this.props.sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id);
const ephemeral = (message: string) => this.props.sendEphemeralPost(message, this.props.post.channel_id, this.props.post.root_id, callResp.app_metadata?.bot_user_id);
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ export class AppCommandParser {
if (err.message) {
errStr = err.message;
}
displayError(errStr);
displayError(errStr, this.channelID, this.rootPostID);
}

// getSuggestionsForSubCommands returns suggestions for a subcommand's name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ export const getExecuteSuggestion = (parsed: ParsedCommand): AutocompleteSuggest
};
};

export const displayError = (err: string) => {
sendEphemeralPost(err);
export const displayError = (err: string, channelID: string, rootID?: string) => {
sendEphemeralPost(err, channelID, rootID);
};

// Shim of mobile-version intl
Expand Down
6 changes: 6 additions & 0 deletions packages/mattermost-redux/src/types/apps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ export type AppCallResponse<Res = unknown> = {
use_external_browser?: boolean;
call?: AppCall;
form?: AppForm;
app_metadata?: AppMetadataForClient;
};

export type AppMetadataForClient = {
bot_user_id: string;
bot_username: string;
}

export type AppContext = {
app_id: string;
location?: string;
Expand Down
2 changes: 1 addition & 1 deletion plugins/channel_header_plug/channel_header_plug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class ChannelHeaderPlug extends React.PureComponent<ChannelHeaderPlugProps, Chan
const res = await this.props.actions.doAppCall(call, AppCallTypes.SUBMIT, this.props.intl);

const callResp = (res as {data: AppCallResponse}).data;
const ephemeral = (message: string) => sendEphemeralPost(message, this.props.channel.id);
const ephemeral = (message: string) => sendEphemeralPost(message, this.props.channel.id, '', callResp.app_metadata?.bot_user_id);
switch (callResp.type) {
case AppCallResponseTypes.OK:
if (callResp.markdown) {
Expand Down

0 comments on commit 08290f1

Please sign in to comment.