mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-06-30 18:35:13 +08:00
feat: passing the inputs values using difyChatbotConfig
(#6376)
This commit is contained in:
parent
e493ce9981
commit
284ef52bba
@ -31,6 +31,7 @@ import type {
|
||||
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { changeLanguage } from '@/i18n/i18next-config'
|
||||
import { getProcessedInputsFromUrlParams } from '@/app/components/base/chat/utils'
|
||||
|
||||
export const useEmbeddedChatbot = () => {
|
||||
const isInstalledApp = false
|
||||
@ -109,6 +110,7 @@ export const useEmbeddedChatbot = () => {
|
||||
const { t } = useTranslation()
|
||||
const newConversationInputsRef = useRef<Record<string, any>>({})
|
||||
const [newConversationInputs, setNewConversationInputs] = useState<Record<string, any>>({})
|
||||
const [initInputs, setInitInputs] = useState<Record<string, any>>({})
|
||||
const handleNewConversationInputsChange = useCallback((newInputs: Record<string, any>) => {
|
||||
newConversationInputsRef.current = newInputs
|
||||
setNewConversationInputs(newInputs)
|
||||
@ -116,30 +118,49 @@ export const useEmbeddedChatbot = () => {
|
||||
const inputsForms = useMemo(() => {
|
||||
return (appParams?.user_input_form || []).filter((item: any) => item.paragraph || item.select || item['text-input'] || item.number).map((item: any) => {
|
||||
if (item.paragraph) {
|
||||
let value = initInputs[item.paragraph.variable]
|
||||
if (value && item.paragraph.max_length && value.length > item.paragraph.max_length)
|
||||
value = value.slice(0, item.paragraph.max_length)
|
||||
|
||||
return {
|
||||
...item.paragraph,
|
||||
default: value || item.default,
|
||||
type: 'paragraph',
|
||||
}
|
||||
}
|
||||
if (item.number) {
|
||||
const convertedNumber = Number(initInputs[item.number.variable]) ?? undefined
|
||||
return {
|
||||
...item.number,
|
||||
default: convertedNumber || item.default,
|
||||
type: 'number',
|
||||
}
|
||||
}
|
||||
if (item.select) {
|
||||
const isInputInOptions = item.select.options.includes(initInputs[item.select.variable])
|
||||
return {
|
||||
...item.select,
|
||||
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.default,
|
||||
type: 'select',
|
||||
}
|
||||
}
|
||||
|
||||
let value = initInputs[item['text-input'].variable]
|
||||
if (value && item['text-input'].max_length && value.length > item['text-input'].max_length)
|
||||
value = value.slice(0, item['text-input'].max_length)
|
||||
|
||||
return {
|
||||
...item['text-input'],
|
||||
default: value || item.default,
|
||||
type: 'text-input',
|
||||
}
|
||||
})
|
||||
}, [appParams])
|
||||
|
||||
useEffect(() => {
|
||||
// init inputs from url params
|
||||
setInitInputs(getProcessedInputsFromUrlParams())
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
const conversationInputs: Record<string, any> = {}
|
||||
|
||||
|
20
web/app/components/base/chat/utils.ts
Normal file
20
web/app/components/base/chat/utils.ts
Normal file
@ -0,0 +1,20 @@
|
||||
async function decodeBase64AndDecompress(base64String: string) {
|
||||
const binaryString = atob(base64String)
|
||||
const compressedUint8Array = Uint8Array.from(binaryString, char => char.charCodeAt(0))
|
||||
const decompressedStream = new Response(compressedUint8Array).body.pipeThrough(new DecompressionStream('gzip'))
|
||||
const decompressedArrayBuffer = await new Response(decompressedStream).arrayBuffer()
|
||||
return new TextDecoder().decode(decompressedArrayBuffer)
|
||||
}
|
||||
|
||||
function getProcessedInputsFromUrlParams(): Record<string, any> {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
const inputs: Record<string, any> = {}
|
||||
urlParams.forEach(async (value, key) => {
|
||||
inputs[key] = await decodeBase64AndDecompress(decodeURIComponent(value))
|
||||
})
|
||||
return inputs
|
||||
}
|
||||
|
||||
export {
|
||||
getProcessedInputsFromUrlParams,
|
||||
}
|
@ -24,27 +24,55 @@
|
||||
};
|
||||
|
||||
// Main function to embed the chatbot
|
||||
function embedChatbot() {
|
||||
async function embedChatbot() {
|
||||
if (!config || !config.token) {
|
||||
console.error(`${configKey} is empty or token is not provided`);
|
||||
return;
|
||||
}
|
||||
|
||||
async function compressAndEncodeBase64(input) {
|
||||
const uint8Array = new TextEncoder().encode(input);
|
||||
const compressedStream = new Response(
|
||||
new Blob([uint8Array]).stream().pipeThrough(new CompressionStream('gzip'))
|
||||
).arrayBuffer();
|
||||
const compressedUint8Array = new Uint8Array(await compressedStream);
|
||||
return btoa(String.fromCharCode(...compressedUint8Array));
|
||||
}
|
||||
|
||||
async function getCompressedInputsFromConfig() {
|
||||
const inputs = config?.inputs || {};
|
||||
const compressedInputs = {};
|
||||
await Promise.all(
|
||||
Object.entries(inputs).map(async ([key, value]) => {
|
||||
compressedInputs[key] = await compressAndEncodeBase64(value);
|
||||
})
|
||||
);
|
||||
return compressedInputs;
|
||||
}
|
||||
|
||||
const params = new URLSearchParams(await getCompressedInputsFromConfig());
|
||||
|
||||
const baseUrl =
|
||||
config.baseUrl || `https://${config.isDev ? "dev." : ""}udify.app`;
|
||||
|
||||
// pre-check the length of the URL
|
||||
const iframeUrl = `${baseUrl}/chatbot/${config.token}?${params}`;
|
||||
if(iframeUrl.length > 2048) {
|
||||
console.error("The URL is too long, please reduce the number of inputs to prevent the bot from failing to load");
|
||||
}
|
||||
|
||||
// Function to create the iframe for the chatbot
|
||||
function createIframe() {
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.allow = "fullscreen;microphone";
|
||||
iframe.title = "dify chatbot bubble window";
|
||||
iframe.id = iframeId;
|
||||
iframe.src = `${baseUrl}/chatbot/${config.token}`;
|
||||
iframe.src = iframeUrl;
|
||||
iframe.style.cssText = `
|
||||
border: none; position: fixed; flex-direction: column; justify-content: space-between;
|
||||
box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px;
|
||||
bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem;
|
||||
max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647;
|
||||
border: none; position: fixed; flex-direction: column; justify-content: space-between;
|
||||
box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px;
|
||||
bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem;
|
||||
max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647;
|
||||
overflow: hidden; left: unset; background-color: #F3F4F6;
|
||||
`;
|
||||
|
||||
@ -106,19 +134,19 @@
|
||||
document.head.appendChild(styleSheet);
|
||||
styleSheet.sheet.insertRule(`
|
||||
#${containerDiv.id} {
|
||||
position: fixed;
|
||||
position: fixed;
|
||||
bottom: var(--${containerDiv.id}-bottom, 1rem);
|
||||
right: var(--${containerDiv.id}-right, 1rem);
|
||||
left: var(--${containerDiv.id}-left, unset);
|
||||
top: var(--${containerDiv.id}-top, unset);
|
||||
width: var(--${containerDiv.id}-width, 50px);
|
||||
height: var(--${containerDiv.id}-height, 50px);
|
||||
border-radius: var(--${containerDiv.id}-border-radius, 25px);
|
||||
border-radius: var(--${containerDiv.id}-border-radius, 25px);
|
||||
background-color: var(--${containerDiv.id}-bg-color, #155EEF);
|
||||
box-shadow: var(--${containerDiv.id}-box-shadow, rgba(0, 0, 0, 0.2) 0px 4px 8px 0px);
|
||||
cursor: pointer;
|
||||
z-index: 2147483647;
|
||||
transition: all 0.2s ease-in-out 0s;
|
||||
z-index: 2147483647;
|
||||
transition: all 0.2s ease-in-out 0s;
|
||||
}
|
||||
`);
|
||||
styleSheet.sheet.insertRule(`
|
||||
@ -154,7 +182,8 @@
|
||||
} else {
|
||||
document.addEventListener('keydown', handleEscKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
resetIframePosition();
|
||||
});
|
||||
|
||||
|
32
web/public/embed.min.js
vendored
32
web/public/embed.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user