Skip to content

Commit

Permalink
fix(botpress): create conversation when user respond
Browse files Browse the repository at this point in the history
Close #2492
  • Loading branch information
munkhorgil committed Nov 24, 2020
1 parent 69480dc commit 3ee59e9
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 60 deletions.
41 changes: 31 additions & 10 deletions api/src/__tests__/widgetMutations.test.ts
Expand Up @@ -37,6 +37,7 @@ import {
} from '../db/models/definitions/constants';
import { ICustomerDocument } from '../db/models/definitions/customers';
import { IIntegrationDocument } from '../db/models/definitions/integrations';
import memoryStorage from '../inmemoryStorage';
import './setup.ts';

describe('messenger connect', () => {
Expand Down Expand Up @@ -388,21 +389,14 @@ describe('insertMessage()', () => {
})
);

const conversationId = await widgetMutations.widgetGetBotInitialMessage(
const message = await widgetMutations.widgetGetBotInitialMessage(
{},
{
integrationId: _integrationBot._id,
customerId: _customer._id
integrationId: _integrationBot._id
}
);

const message = await ConversationMessages.findOne({ conversationId });

if (message) {
expect(message.botData[0].text).toBe('Greeting bot message');
} else {
fail('Failed to create bot initial message');
}
expect(message.botData[0].text).toBe('Greeting bot message');

mock.restore();
});
Expand Down Expand Up @@ -486,6 +480,33 @@ describe('insertMessage()', () => {
}
]);

await memoryStorage().set(
`bot_initial_message_${_integrationBot._id}`,
JSON.stringify({ text: 'Hi there' })
);

const botMessage3 = await widgetMutations.widgetBotRequest(
{},
{
integrationId: _integrationBot._id,
customerId: _customer._id,
message: 'Reply message',
payload: 'Response of reply',
type: 'postback'
}
);

expect(botMessage3.botData).toEqual([
{
type: 'text',
text: 'Response of quick reply'
}
]);

await memoryStorage().removeKey(
`bot_initial_message_${_integrationBot._id}`
);

sendRequestMock.restore();
});
});
Expand Down
69 changes: 44 additions & 25 deletions api/src/data/resolvers/mutations/widgets.ts
Expand Up @@ -726,7 +726,7 @@ const widgetMutations = {
payload,
type
}: {
conversationId: string;
conversationId?: string;
customerId: string;
integrationId: string;
message: string;
Expand All @@ -740,6 +740,33 @@ const widgetMutations = {

const { botEndpointUrl } = integration.messengerData;

let sessionId = conversationId;

if (!conversationId) {
sessionId = await memoryStorage().get(
`bot_initial_message_session_id_${integrationId}`
);

const conversation = await Conversations.createConversation({
customerId,
integrationId,
operatorStatus: CONVERSATION_OPERATOR_STATUS.BOT,
status: CONVERSATION_STATUSES.CLOSED
});

conversationId = conversation._id;

const initialMessageBotData = await memoryStorage().get(
`bot_initial_message_${integrationId}`
);

await Messages.createMessage({
conversationId: conversation._id,
customerId,
botData: JSON.parse(initialMessageBotData || '{}')
});
}

// create customer message
const msg = await Messages.createMessage({
conversationId,
Expand All @@ -760,7 +787,7 @@ const widgetMutations = {
if (type !== BOT_MESSAGE_TYPES.SAY_SOMETHING) {
const botRequest = await sendRequest({
method: 'POST',
url: `${botEndpointUrl}/${conversationId}`,
url: `${botEndpointUrl}/${sessionId}`,
body: {
type: 'text',
text: payload
Expand Down Expand Up @@ -806,14 +833,16 @@ const widgetMutations = {

async widgetGetBotInitialMessage(
_root,
{ integrationId, customerId }: { integrationId: string; customerId: string }
{ integrationId }: { integrationId: string }
) {
const conversation = await Conversations.createConversation({
customerId,
integrationId,
operatorStatus: CONVERSATION_OPERATOR_STATUS.BOT,
status: CONVERSATION_STATUSES.CLOSED
});
const sessionId = `_${Math.random()
.toString(36)
.substr(2, 9)}`;

await memoryStorage().set(
`bot_initial_message_session_id_${integrationId}`,
sessionId
);

const integration = await Integrations.findOne({
_id: integrationId
Expand All @@ -823,29 +852,19 @@ const widgetMutations = {

const botRequest = await sendRequest({
method: 'POST',
url: `${botEndpointUrl}/${conversation._id}`,
url: `${botEndpointUrl}/${sessionId}`,
body: {
type: 'text',
text: 'getStarted'
}
});

const { responses } = botRequest;

const botMessage = await Messages.createMessage({
conversationId: conversation._id,
customerId,
botData: responses
});

graphqlPubsub.publish('conversationClientMessageInserted', {
conversationClientMessageInserted: botMessage
});
graphqlPubsub.publish('conversationMessageInserted', {
conversationMessageInserted: botMessage
});
await memoryStorage().set(
`bot_initial_message_${integrationId}`,
JSON.stringify(botRequest.responses)
);

return conversation._id;
return { botData: botRequest.responses };
}
};

Expand Down
2 changes: 1 addition & 1 deletion api/src/data/schema/widget.ts
Expand Up @@ -124,7 +124,7 @@ export const mutations = `
content: String
): String
widgetGetBotInitialMessage(integrationId: String, customerId: String): JSON
widgetGetBotInitialMessage(integrationId: String): JSON
widgetsKnowledgebaseIncReactionCount(articleId: String!, reactionChoice: String!): String
widgetsLeadIncreaseViewCount(formId: String!): JSON
Expand Down
6 changes: 3 additions & 3 deletions widgets/client/form/components/Field.tsx
Expand Up @@ -10,7 +10,7 @@ type Props = {
};

type State = {
dateValue: Date | string;
dateValue?: Date | string;
dateTimeValue: Date | string;
isAttachingFile?: boolean;
};
Expand Down Expand Up @@ -173,9 +173,9 @@ export default class Field extends React.Component<Props, State> {
renderDatepicker() {
return (
<Datetime
value={this.state.dateValue}
defaultValue={new Date()}
viewDate={new Date()}
value={this.state.dateValue}
onChange={this.onDateChange}
dateFormat="YYYY/MM/DD"
timeFormat={false}
Expand All @@ -186,9 +186,9 @@ export default class Field extends React.Component<Props, State> {
renderDateTimepicker() {
return (
<Datetime
value={this.state.dateTimeValue}
defaultValue={new Date()}
viewDate={new Date()}
value={this.state.dateTimeValue}
onChange={this.onDateTimeChange}
timeFormat="HH:mm"
dateFormat="YYYY/MM/DD"
Expand Down
10 changes: 7 additions & 3 deletions widgets/client/messenger/components/MessageBot.tsx
Expand Up @@ -15,12 +15,12 @@ type Props = {
textColor?: string;
replyAutoAnswer: (message: string, payload: string, type: string) => void;
sendTypingInfo: (conversationId: string, text: string) => void;
conversationId: string;
conversationId?: string;
scrollBottom: () => void;
};

type CommonProps = {
conversationId: string;
conversationId?: string;
replyAutoAnswer: (message: string, payload: string, type: string) => void;
sendTypingInfo: (conversationId: string, text: string) => void;
};
Expand All @@ -35,12 +35,16 @@ function MessageBot(props: Props) {
scrollBottom
} = props;

if (botData.length === 0) {
return null;
}

const renderTextMessage = (message: IBotData, idx: number) => {
return (
<div
key={idx}
className="erxes-message top"
dangerouslySetInnerHTML={{ __html: xss(urlify(message.text || '')) }}
dangerouslySetInnerHTML={{ __html: xss(urlify(message.text || "")) }}
/>
);
};
Expand Down
27 changes: 21 additions & 6 deletions widgets/client/messenger/components/MessagesList.tsx
Expand Up @@ -10,7 +10,7 @@ import {
} from '../../types';
import { __, makeClickableLink, scrollTo } from '../../utils';
import { MESSAGE_TYPES } from '../containers/AppContext';
import { IMessage } from '../types';
import { IBotData, IMessage } from '../types';
import { Message } from './';
import { MessageBot } from './';
import AccquireInformation from './AccquireInformation';
Expand All @@ -35,7 +35,7 @@ type Props = {
sendTypingInfo: (conversationId: string, text: string) => void;
conversationId: string | null;
changeOperatorStatus: (_id: string, operatorStatus: string) => void;
getBotInitialMessage: () => void;
getBotInitialMessage: (callback: (bodData: any) => void) => void;
operatorStatus?: string;
sendMessage: (contentType: string, message: string) => void;
showVideoCallRequest: boolean;
Expand All @@ -44,6 +44,7 @@ type Props = {

type State = {
hideNotifyInput: boolean;
initialMessage: { bodData: IBotData } | null;
};

class MessagesList extends React.Component<Props, State> {
Expand All @@ -53,19 +54,22 @@ class MessagesList extends React.Component<Props, State> {
constructor(props: Props) {
super(props);

this.state = { hideNotifyInput: false };
this.state = { hideNotifyInput: false, initialMessage: null };
this.onNotify = this.onNotify.bind(this);
}

componentDidMount() {
const { messengerData, messages, getBotInitialMessage, conversationId } = this.props;
const { messengerData, messages, getBotInitialMessage, conversationId = "" } = this.props;

if (
messengerData.botShowInitialMessage &&
messages.length === 0 &&
!conversationId
(!conversationId ||
(conversationId || "").length === 0)
) {
getBotInitialMessage();
getBotInitialMessage((initialMessage) => {
this.setState({ initialMessage });
});
}

if (this.node) {
Expand Down Expand Up @@ -106,6 +110,16 @@ class MessagesList extends React.Component<Props, State> {
});
};

renderBotGreetingMessage(messengerData: IIntegrationMessengerData) {
const { initialMessage } = this.state;

if (!messengerData.botShowInitialMessage || !initialMessage) {
return null;
}

return this.renderSingleMessage(initialMessage);
}

renderAwayMessage(messengerData: IIntegrationMessengerData) {
const { isOnline } = this.props;
const messages =
Expand Down Expand Up @@ -326,6 +340,7 @@ class MessagesList extends React.Component<Props, State> {
return (
<div className={backgroundClass} ref={node => (this.node = node)}>
<ul id="erxes-messages" className="erxes-messages-list slide-in">
{this.renderBotGreetingMessage(messengerData)}
{this.renderWelcomeMessage(messengerData)}
{this.renderCallRequest()}
{this.renderMessages()}
Expand Down
2 changes: 1 addition & 1 deletion widgets/client/messenger/components/bot/Carousel.tsx
Expand Up @@ -18,7 +18,7 @@ export interface ICarouselItem {
}

type Props = {
conversationId: string;
conversationId?: string;
items?: ICarouselItem[];
replyAutoAnswer: (message: string, payload: string, type: string) => void;
sendTypingInfo: (conversationId: string, text: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion widgets/client/messenger/components/bot/CustomMessage.tsx
Expand Up @@ -3,7 +3,7 @@ import { IBotData } from '../../types';
import { BOT_CUSTOM_TYPES } from './constants';

type Props = {
conversationId: string;
conversationId?: string;
message: IBotData;
replyAutoAnswer: (message: string, payload: string, type: string) => void;
sendTypingInfo: (conversationId: string, text: string) => void;
Expand Down

0 comments on commit 3ee59e9

Please sign in to comment.