发送模板替换变量
parent
44b3dbd8df
commit
c5f1ba1b5e
@ -1,153 +0,0 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { Input, Button, Tabs, List, Space, Popover, Flex } from 'antd';
|
|
||||||
// import { Input } from 'react-chat-elements';
|
|
||||||
import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext';
|
|
||||||
import { sentNewMessage } from '@/actions/ConversationActions';
|
|
||||||
import { useAuthContext } from '@/stores/AuthContext';
|
|
||||||
import { LikeOutlined, MessageOutlined, StarOutlined, SendOutlined, PlusOutlined, PlusCircleOutlined } from '@ant-design/icons';
|
|
||||||
import { cloneDeep, getNestedValue, isEmpty } from '@/utils/utils';
|
|
||||||
import { v4 as uuid } from 'uuid';
|
|
||||||
import { whatsappTemplatesParamMapped, sentMsgTypeMapped, replaceTemplateString } from '@/lib/msgUtils';
|
|
||||||
|
|
||||||
const InputBox = () => {
|
|
||||||
const { loginUser } = useAuthContext();
|
|
||||||
const { userId } = loginUser;
|
|
||||||
const { websocket, currentConversation, templates } = useConversationState();
|
|
||||||
const dispatch = useConversationDispatch();
|
|
||||||
const [textContent, setTextContent] = useState('');
|
|
||||||
|
|
||||||
const talkabled = !isEmpty(currentConversation.sn);
|
|
||||||
|
|
||||||
const invokeSendMessage = (msgObj) => {
|
|
||||||
console.log('sendMessage------------------', msgObj);
|
|
||||||
const contentToSend = sentMsgTypeMapped[msgObj.type].contentToSend(msgObj);
|
|
||||||
console.log('content to send-------------------------------------', contentToSend);
|
|
||||||
websocket.sendMessage({ ...contentToSend, opi_sn: userId, coli_sn: currentConversation.coli_sn });
|
|
||||||
const contentToRender = sentMsgTypeMapped[msgObj.type].contentToRender(msgObj);
|
|
||||||
console.log(contentToRender, 'contentToRender sendMessage------------------');
|
|
||||||
dispatch(sentNewMessage(contentToRender));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSendText = () => {
|
|
||||||
if (textContent.trim() !== '') {
|
|
||||||
const msgObj = {
|
|
||||||
type: 'text',
|
|
||||||
text: textContent,
|
|
||||||
sender: 'me',
|
|
||||||
to: currentConversation.whatsapp_phone_number,
|
|
||||||
id: `${currentConversation.sn}.${uuid()}`, // Date.now().toString(16),
|
|
||||||
date: new Date(),
|
|
||||||
status: 'waiting',
|
|
||||||
};
|
|
||||||
invokeSendMessage(msgObj);
|
|
||||||
setTextContent('');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSendTemplate = (fromTemplate) => {
|
|
||||||
console.log(fromTemplate, 'fromTemplate');
|
|
||||||
const _conversation = { ...cloneDeep(currentConversation) };
|
|
||||||
const msgObj = {
|
|
||||||
type: 'whatsappTemplate',
|
|
||||||
to: currentConversation.whatsapp_phone_number,
|
|
||||||
id: `${currentConversation.sn}.${uuid()}`,
|
|
||||||
date: new Date(),
|
|
||||||
status: 'waiting',
|
|
||||||
statusTitle: 'Ready to send',
|
|
||||||
sender: 'me',
|
|
||||||
template: {
|
|
||||||
name: fromTemplate.name,
|
|
||||||
language: { code: fromTemplate.language },
|
|
||||||
components: fromTemplate.components_origin.map(citem => {
|
|
||||||
const params = whatsappTemplatesParamMapped[fromTemplate.name].map((v) => ({ type: 'text', text: getNestedValue(_conversation, v) || '' }));
|
|
||||||
const paramText = params.map((p) => p.text);
|
|
||||||
const fillTemplate = paramText.length ? replaceTemplateString(citem?.text || '', paramText) : citem?.text || '';
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: citem.type.toLowerCase(),
|
|
||||||
parameters: params,
|
|
||||||
text: fillTemplate,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
// ...(fromTemplate.components.body[0]?.example?.body_text?.[0]?.length > 0
|
|
||||||
// ? {
|
|
||||||
// components: [
|
|
||||||
// {
|
|
||||||
// 'type': 'body',
|
|
||||||
// 'text': fromTemplate.components.body[0]?.text,
|
|
||||||
// 'parameters': whatsappTemplatesParamMapped[fromTemplate.name].map((v) => ({ type: 'text', text: getNestedValue(_conversation, v) || '' })),
|
|
||||||
// // [
|
|
||||||
// // {
|
|
||||||
// // 'type': 'text',
|
|
||||||
// // 'text': getNestedValue(_conversation, whatsappTemplatesParamMapped[fromTemplate.name][0]) ,
|
|
||||||
// // },
|
|
||||||
// // { // debug:
|
|
||||||
// // 'type': 'text',
|
|
||||||
// // 'text': getNestedValue(_conversation, whatsappTemplatesParamMapped[fromTemplate.name]?.[1] || whatsappTemplatesParamMapped[fromTemplate.name][0]) ,
|
|
||||||
// // },
|
|
||||||
// // ],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// }
|
|
||||||
// : {}),
|
|
||||||
},
|
|
||||||
template_origin: fromTemplate,
|
|
||||||
};
|
|
||||||
invokeSendMessage(msgObj);
|
|
||||||
setOpenTemplates(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [openTemplates, setOpenTemplates] = useState(false);
|
|
||||||
const handleOpenChange = (newOpen) => {
|
|
||||||
setOpenTemplates(newOpen);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Flex gap={8}>
|
|
||||||
<Popover
|
|
||||||
content={
|
|
||||||
<List
|
|
||||||
className='w-96 h-4/6 overflow-y-auto text-slate-900'
|
|
||||||
itemLayout='horizontal'
|
|
||||||
dataSource={templates}
|
|
||||||
renderItem={(item, index) => (
|
|
||||||
<List.Item>
|
|
||||||
<List.Item.Meta
|
|
||||||
className=' text-neutral-800'
|
|
||||||
title={
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<>{item.components.header?.[0]?.text || item.name}</>
|
|
||||||
<Button onClick={() => handleSendTemplate(item)} size={'small'} type='link' key={'send'} icon={<SendOutlined />}>
|
|
||||||
Send
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
}
|
|
||||||
description={item.components.body?.[0]?.text}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
title='🙋打招呼'
|
|
||||||
trigger='click'
|
|
||||||
open={openTemplates}
|
|
||||||
onOpenChange={handleOpenChange}>
|
|
||||||
<Button type='primary' shape='circle' icon={<MessageOutlined />} size={'large'} disabled={!talkabled} />
|
|
||||||
</Popover>
|
|
||||||
<Input.Search
|
|
||||||
disabled={!talkabled}
|
|
||||||
placeholder='Type message here'
|
|
||||||
// enterButton={'Send'}
|
|
||||||
enterButton={<SendOutlined />}
|
|
||||||
size='large'
|
|
||||||
onSearch={handleSendText}
|
|
||||||
value={textContent}
|
|
||||||
onChange={(e) => setTextContent(e.target.value)}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<div></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default InputBox;
|
|
@ -0,0 +1,68 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Input, Flex } from 'antd';
|
||||||
|
// import { Input } from 'react-chat-elements';
|
||||||
|
import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext';
|
||||||
|
import { useAuthContext } from '@/stores/AuthContext';
|
||||||
|
import { sentNewMessage } from '@/actions/ConversationActions';
|
||||||
|
import { SendOutlined } from '@ant-design/icons';
|
||||||
|
import { isEmpty } from '@/utils/utils';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import { sentMsgTypeMapped } from '@/lib/msgUtils';
|
||||||
|
import InputTemplate from './InputTemplate';
|
||||||
|
|
||||||
|
const InputBox = () => {
|
||||||
|
const { loginUser } = useAuthContext();
|
||||||
|
const { userId } = loginUser;
|
||||||
|
const { websocket, currentConversation, } = useConversationState();
|
||||||
|
const dispatch = useConversationDispatch();
|
||||||
|
const [textContent, setTextContent] = useState('');
|
||||||
|
|
||||||
|
const talkabled = !isEmpty(currentConversation.sn);
|
||||||
|
|
||||||
|
const invokeSendMessage = (msgObj) => {
|
||||||
|
console.log('sendMessage------------------', msgObj);
|
||||||
|
const contentToSend = sentMsgTypeMapped[msgObj.type].contentToSend(msgObj);
|
||||||
|
console.log('content to send-------------------------------------', contentToSend);
|
||||||
|
websocket.sendMessage({ ...contentToSend, opi_sn: userId, coli_sn: currentConversation.coli_sn });
|
||||||
|
const contentToRender = sentMsgTypeMapped[msgObj.type].contentToRender(msgObj);
|
||||||
|
console.log(contentToRender, 'contentToRender sendMessage------------------');
|
||||||
|
dispatch(sentNewMessage(contentToRender));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSendText = () => {
|
||||||
|
if (textContent.trim() !== '') {
|
||||||
|
const msgObj = {
|
||||||
|
type: 'text',
|
||||||
|
text: textContent,
|
||||||
|
sender: 'me',
|
||||||
|
to: currentConversation.whatsapp_phone_number,
|
||||||
|
id: `${currentConversation.sn}.${uuid()}`, // Date.now().toString(16),
|
||||||
|
date: new Date(),
|
||||||
|
status: 'waiting',
|
||||||
|
};
|
||||||
|
invokeSendMessage(msgObj);
|
||||||
|
setTextContent('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Flex gap={8}>
|
||||||
|
<InputTemplate disabled={!talkabled} invokeSendMessage={invokeSendMessage} />
|
||||||
|
<Input.Search
|
||||||
|
disabled={!talkabled}
|
||||||
|
placeholder='Type message here'
|
||||||
|
// enterButton={'Send'}
|
||||||
|
enterButton={<SendOutlined />}
|
||||||
|
size='large'
|
||||||
|
onSearch={handleSendText}
|
||||||
|
value={textContent}
|
||||||
|
onChange={(e) => setTextContent(e.target.value)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InputBox;
|
@ -0,0 +1,85 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { Popover, Flex, Button, List } from 'antd';
|
||||||
|
import { MessageOutlined, SendOutlined } from '@ant-design/icons';
|
||||||
|
import { useAuthContext } from '@/stores/AuthContext';
|
||||||
|
import { useConversationState } from '@/stores/ConversationContext';
|
||||||
|
import { cloneDeep, getNestedValue, objectMapper } from '@/utils/utils';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import { whatsappTemplatesParamMapped, replaceTemplateString } from '@/lib/msgUtils';
|
||||||
|
|
||||||
|
const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
|
||||||
|
const { loginUser } = useAuthContext();
|
||||||
|
const { currentConversation, templates } = useConversationState();
|
||||||
|
|
||||||
|
const [openTemplates, setOpenTemplates] = useState(false);
|
||||||
|
const handleOpenChange = (newOpen) => {
|
||||||
|
setOpenTemplates(newOpen);
|
||||||
|
};
|
||||||
|
const handleSendTemplate = (fromTemplate) => {
|
||||||
|
// 替换变量: customer, agent
|
||||||
|
const _conversation = { ...cloneDeep(currentConversation), ...objectMapper(loginUser, { username: { key: 'agent_name' } }) };
|
||||||
|
const msgObj = {
|
||||||
|
type: 'whatsappTemplate',
|
||||||
|
to: currentConversation.whatsapp_phone_number,
|
||||||
|
id: `${currentConversation.sn}.${uuid()}`,
|
||||||
|
date: new Date(),
|
||||||
|
status: 'waiting',
|
||||||
|
// statusTitle: 'Ready to send',
|
||||||
|
sender: 'me',
|
||||||
|
template: {
|
||||||
|
name: fromTemplate.name,
|
||||||
|
language: { code: fromTemplate.language },
|
||||||
|
components: fromTemplate.components_origin.map((citem) => {
|
||||||
|
const params = whatsappTemplatesParamMapped[fromTemplate.name].map((v) => ({ type: 'text', text: getNestedValue(_conversation, v) || '' }));
|
||||||
|
const paramText = params.map((p) => p.text);
|
||||||
|
const fillTemplate = paramText.length ? replaceTemplateString(citem?.text || '', paramText) : citem?.text || '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: citem.type.toLowerCase(),
|
||||||
|
parameters: params,
|
||||||
|
text: fillTemplate,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
template_origin: fromTemplate,
|
||||||
|
};
|
||||||
|
invokeSendMessage(msgObj);
|
||||||
|
setOpenTemplates(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Popover
|
||||||
|
content={
|
||||||
|
<List
|
||||||
|
className='w-96 h-4/6 overflow-y-auto text-slate-900'
|
||||||
|
itemLayout='horizontal'
|
||||||
|
dataSource={templates}
|
||||||
|
renderItem={(item, index) => (
|
||||||
|
<List.Item>
|
||||||
|
<List.Item.Meta
|
||||||
|
className=' text-neutral-800'
|
||||||
|
title={
|
||||||
|
<Flex justify={'space-between'}>
|
||||||
|
<>{item.components.header?.[0]?.text || item.name}</>
|
||||||
|
<Button onClick={() => handleSendTemplate(item)} size={'small'} type='link' key={'send'} icon={<SendOutlined />}>
|
||||||
|
Send
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
}
|
||||||
|
description={item.components.body?.[0]?.text}
|
||||||
|
/>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
title='🙋打招呼'
|
||||||
|
trigger='click'
|
||||||
|
open={openTemplates}
|
||||||
|
onOpenChange={handleOpenChange}>
|
||||||
|
<Button type='primary' shape='circle' icon={<MessageOutlined />} size={'large'} disabled={disabled} />
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default InputTemplate;
|
Loading…
Reference in New Issue