application embedded add chrome && ChatBot Chrome plugin update v1.5 (#1480)
Co-authored-by: luowei <glpat-EjySCyNjWiLqAED-YmwM> Co-authored-by: crazywoola <427733928@qq.com>
10
third-party/chrome plug-in/README_CN.md
vendored
|
@ -20,16 +20,14 @@
|
|||
- options.js 插件配置JS脚本
|
||||
|
||||
### 插件导入完成后,后续配置无差异
|
||||
- 初始化设置Dify 应用配置,分别输入Dify根域名和应用Token,Token可以在Dify应用嵌入中获取,如图:
|
||||
- 创建Dify应用配置,在应用概览中点击嵌入,切换到安装Chrome浏览器扩展视图,点击copy按钮获取ChatBot Url,如图:
|
||||
|
||||
![img-2.png](images/img-2.png)
|
||||
![img-3.png](images/img-3.png)
|
||||
|
||||
- 点击保存,确认提示配置成功即可
|
||||
|
||||
![img-4.png](images/img-4.png)
|
||||
![img-3.png](images/img-3.png)
|
||||
|
||||
- 保险起见重启浏览器确保所有分页刷新成功
|
||||
- Chrome打开任意页面均可正常加载DIfy机器人浮动栏,后续如需更换机器人只需要变更Token即可
|
||||
- Chrome打开任意页面均可正常加载DIfy机器人浮动栏,后续如需更换机器人只需要变更ChatBot Url即可
|
||||
|
||||
![img-5.png](images/img-5.png)
|
||||
![img-4.png](images/img-4.png)
|
6
third-party/chrome plug-in/README_CN.txt
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
## Chrome Dify ChatBot插件
|
||||
|
||||
1、初始化设置Dify 应用配置,分别输入Dify根域名和应用Token,Token可以在Dify应用嵌入中获取;
|
||||
2、点击保存,确认提示配置成功即可;
|
||||
3、保险起见重启浏览器确保所有分页刷新成功;
|
||||
4、Chrome打开任意页面均可正常加载DIfy机器人浮动栏,后续如需更换机器人只需要变更Token即可;
|
14
third-party/chrome plug-in/content.js
vendored
|
@ -1,8 +1,7 @@
|
|||
var storage = chrome.storage.sync;
|
||||
chrome.storage.sync.get(['baseUrl', 'token'], function(result) {
|
||||
const storage = chrome.storage.sync;
|
||||
chrome.storage.sync.get(['chatbotUrl'], function(result) {
|
||||
window.difyChatbotConfig = {
|
||||
baseUrl: result.baseUrl,
|
||||
token: result.token
|
||||
chatbotUrl: result.chatbotUrl,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -10,11 +9,10 @@ document.body.onload = embedChatbot;
|
|||
|
||||
async function embedChatbot() {
|
||||
const difyChatbotConfig = window.difyChatbotConfig;
|
||||
if (!difyChatbotConfig || !difyChatbotConfig.token) {
|
||||
console.warn('difyChatbotConfig is empty or token is not provided');
|
||||
if (!difyChatbotConfig) {
|
||||
console.warn('Dify Chatbot Url is empty or is not provided');
|
||||
return;
|
||||
}
|
||||
const baseUrl = difyChatbotConfig.baseUrl
|
||||
const openIcon = `<svg
|
||||
id="openIcon"
|
||||
width="24"
|
||||
|
@ -53,7 +51,7 @@ async function embedChatbot() {
|
|||
iframe.allow = "fullscreen;microphone"
|
||||
iframe.title = "dify chatbot bubble window"
|
||||
iframe.id = 'dify-chatbot-bubble-window'
|
||||
iframe.src = `${baseUrl}/chat/${difyChatbotConfig.token}`
|
||||
iframe.src = difyChatbotConfig.chatbotUrl
|
||||
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: 6.7rem; right: 1rem; width: 30rem; height: 48rem; border-radius: 0.75rem; display: flex; z-index: 2147483647; overflow: hidden; left: unset; background-color: #F3F4F6;'
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
|
BIN
third-party/chrome plug-in/favicon.png
vendored
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
third-party/chrome plug-in/images/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
third-party/chrome plug-in/images/img-2.png
vendored
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 124 KiB |
BIN
third-party/chrome plug-in/images/img-3.png
vendored
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 85 KiB |
BIN
third-party/chrome plug-in/images/img-4.png
vendored
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 85 KiB |
BIN
third-party/chrome plug-in/images/img-5.png
vendored
Before Width: | Height: | Size: 85 KiB |
4
third-party/chrome plug-in/manifest.json
vendored
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Dify Chatbot",
|
||||
"version": "1.3",
|
||||
"version": "1.5",
|
||||
"description": "This is a chrome extension to inject a dify chatbot on any pages",
|
||||
"content_scripts": [
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
|||
"32": "images/32.png",
|
||||
"48": "images/48.png",
|
||||
"128": "images/128.png"
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
|
|
19
third-party/chrome plug-in/options.css
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
body {
|
||||
background-color: #f2f2f2;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 280px;
|
||||
padding: 6px;
|
||||
}
|
21
third-party/chrome plug-in/options.html
vendored
|
@ -4,32 +4,21 @@
|
|||
<head>
|
||||
<title>Dify Chatbot Extension</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link href="./tailwind.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="bg-gray-100 py-8 px-4 w-96">
|
||||
<body class="bg-gray-100 py-4 px-4 w-128">
|
||||
<div class="max-w-md mx-auto bg-white shadow-md rounded-lg p-4">
|
||||
<h2 class="text-2xl font-semibold mb-4">Dify Chatbot Extension</h2>
|
||||
<form>
|
||||
<div class="mb-4 flex items-center">
|
||||
<div class="w-1/4">
|
||||
<label for="base-url" class="block font-semibold text-gray-700">Base URL</label>
|
||||
<label for="chatbot-url" class="block font-semibold text-gray-700">ChatBot URL</label>
|
||||
</div>
|
||||
<div class="w-3/4">
|
||||
<input type="text" id="base-url" name="base-url" value=""
|
||||
<input type="text" id="chatbot-url" name="base-url" value=""
|
||||
class="w-full border border-gray-300 rounded px-3 py-2 focus:outline-none focus:border-blue-400"
|
||||
placeholder="https://udify.app">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 flex items-center">
|
||||
<div class="w-1/4">
|
||||
<label for="token" class="block font-semibold text-gray-700">Token</label>
|
||||
</div>
|
||||
<div class="w-3/4">
|
||||
<input type="text" id="token" name="token" value=""
|
||||
class="w-full border border-gray-300 rounded px-3 py-2 focus:outline-none focus:border-blue-400"
|
||||
placeholder="Application Embedded Token">
|
||||
placeholder="https://udify.app/chatbot/7CQBa5yyvYLSkZtx">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
29
third-party/chrome plug-in/options.js
vendored
|
@ -1,39 +1,28 @@
|
|||
|
||||
document.getElementById('save-button').addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
var baseUrl = document.getElementById('base-url').value;
|
||||
var token = document.getElementById('token').value;
|
||||
var errorTip = document.getElementById('error-tip');
|
||||
const chatbotUrl = document.getElementById('chatbot-url').value;
|
||||
const errorTip = document.getElementById('error-tip');
|
||||
|
||||
if (baseUrl.trim() === "" || token.trim() === "") {
|
||||
if (baseUrl.trim() === "") {
|
||||
errorTip.textContent = "Base URL cannot be empty.";
|
||||
} else {
|
||||
errorTip.textContent = "Token cannot be empty.";
|
||||
}
|
||||
if (chatbotUrl.trim() === "") {
|
||||
errorTip.textContent = "Dify ChatBot URL cannot be empty.";
|
||||
} else {
|
||||
errorTip.textContent = "";
|
||||
|
||||
chrome.storage.sync.set({
|
||||
'baseUrl': baseUrl,
|
||||
'token': token
|
||||
'chatbotUrl': chatbotUrl,
|
||||
}, function () {
|
||||
alert('Save Success!');
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Load parameters from chrome.storage when the page loads
|
||||
chrome.storage.sync.get(['baseUrl', 'token'], function (result) {
|
||||
const baseUrlInput = document.getElementById('base-url');
|
||||
const tokenInput = document.getElementById('token');
|
||||
chrome.storage.sync.get(['chatbotUrl'], function (result) {
|
||||
const chatbotUrlInput = document.getElementById('chatbot-url');
|
||||
|
||||
if (result.baseUrl) {
|
||||
baseUrlInput.value = result.baseUrl;
|
||||
if (result.chatbotUrl) {
|
||||
chatbotUrlInput.value = result.chatbotUrl;
|
||||
}
|
||||
|
||||
if (result.token) {
|
||||
tokenInput.value = result.token;
|
||||
}
|
||||
});
|
176015
third-party/chrome plug-in/tailwind.css
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.91722 6.7298L3.08403 3.65525C2.93723 3.40905 2.86384 3.28596 2.84729 3.14436C2.83386 3.02937 2.85797 2.8842 2.90785 2.77973C2.96928 2.65108 3.06488 2.5699 3.2561 2.40754C4.53491 1.32168 6.19097 0.666626 8.00002 0.666626C10.5383 0.666626 12.7753 1.95619 14.0918 3.91589C14.2371 4.13226 14.3098 4.24045 14.3034 4.35234C14.2981 4.44429 14.2454 4.54327 14.172 4.59892C14.0827 4.66663 13.9425 4.66663 13.6621 4.66663H8.00002C6.60882 4.66663 5.41668 5.51889 4.91722 6.7298Z" fill="white"/>
|
||||
<path d="M0.666687 7.99996C0.666687 6.87421 0.92035 5.80771 1.37364 4.85449C1.48535 4.61957 1.5412 4.50211 1.64056 4.45053C1.72221 4.40813 1.83412 4.40288 1.91938 4.43744C2.02313 4.4795 2.0948 4.5997 2.23814 4.8401L5.06356 9.57876C5.62637 10.6234 6.73029 11.3333 8.00002 11.3333C8.13686 11.3333 8.27178 11.325 8.4043 11.309L6.62101 14.4166C6.4785 14.665 6.40724 14.7891 6.29186 14.873C6.19827 14.941 6.05961 14.9912 5.94418 14.9988C5.80188 15.0083 5.68457 14.9648 5.44995 14.8778C2.65701 13.8418 0.666687 11.1533 0.666687 7.99996Z" fill="white"/>
|
||||
<path d="M7.81791 15.0098C7.73532 15.1537 7.83408 15.3333 8.00002 15.3333C12.0501 15.3333 15.3334 12.05 15.3334 7.99996C15.3334 7.58673 15.2992 7.18148 15.2335 6.78688C15.1924 6.53989 15.1718 6.41639 15.0928 6.29755C15.0287 6.20113 14.9162 6.10577 14.8105 6.05838C14.6803 5.99996 14.5371 5.99996 14.2505 5.99996H10.6669C11.0854 6.55707 11.3334 7.24956 11.3334 7.99996C11.3334 8.65299 11.1456 9.26216 10.821 9.77642L7.81791 15.0098Z" fill="white"/>
|
||||
<path d="M10 7.99996C10 9.10453 9.10459 9.99996 8.00002 9.99996C6.89545 9.99996 6.00002 9.10453 6.00002 7.99996C6.00002 6.89539 6.89545 5.99996 8.00002 5.99996C9.10459 5.99996 10 6.89539 10 7.99996Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
159
web/app/components/app/overview/assets/chromeplugin-option.svg
Normal file
After Width: | Height: | Size: 51 KiB |
|
@ -9,8 +9,6 @@ import Tooltip from '@/app/components/base/tooltip'
|
|||
import { useAppContext } from '@/context/app-context'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
|
||||
// const isDevelopment = process.env.NODE_ENV === 'development'
|
||||
|
||||
type Props = {
|
||||
isShow: boolean
|
||||
onClose: () => void
|
||||
|
@ -47,6 +45,9 @@ const OPTION_MAP = {
|
|||
defer>
|
||||
</script>`,
|
||||
},
|
||||
chromePlugin: {
|
||||
getContent: (url: string, token: string) => `ChatBot URL: ${url}/chatbot/${token}`,
|
||||
},
|
||||
}
|
||||
const prefixEmbedded = 'appOverview.overview.appInfo.embedded'
|
||||
|
||||
|
@ -55,17 +56,25 @@ type Option = keyof typeof OPTION_MAP
|
|||
type OptionStatus = {
|
||||
iframe: boolean
|
||||
scripts: boolean
|
||||
chromePlugin: boolean
|
||||
}
|
||||
|
||||
const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
const [option, setOption] = useState<Option>('iframe')
|
||||
const [isCopied, setIsCopied] = useState<OptionStatus>({ iframe: false, scripts: false })
|
||||
const [isCopied, setIsCopied] = useState<OptionStatus>({ iframe: false, scripts: false, chromePlugin: false })
|
||||
|
||||
const { langeniusVersionInfo } = useAppContext()
|
||||
const isTestEnv = langeniusVersionInfo.current_env === 'TESTING' || langeniusVersionInfo.current_env === 'DEVELOPMENT'
|
||||
const onClickCopy = () => {
|
||||
copy(OPTION_MAP[option].getContent(appBaseUrl, accessToken, isTestEnv))
|
||||
if (option === 'chromePlugin') {
|
||||
const splitUrl = OPTION_MAP[option].getContent(appBaseUrl, accessToken).split(': ')
|
||||
if (splitUrl.length > 1)
|
||||
copy(splitUrl[1])
|
||||
}
|
||||
else {
|
||||
copy(OPTION_MAP[option].getContent(appBaseUrl, accessToken, isTestEnv))
|
||||
}
|
||||
setIsCopied({ ...isCopied, [option]: true })
|
||||
}
|
||||
|
||||
|
@ -78,6 +87,10 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
|
|||
setIsCopied(cache)
|
||||
}
|
||||
|
||||
const navigateToChromeUrl = () => {
|
||||
window.open('https://chrome.google.com/webstore/detail/dify-chatbot/ceehdapohffmjmkdcifjofadiaoeggaf/related', '_blank')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
resetCopyStatus()
|
||||
}, [isShow])
|
||||
|
@ -93,7 +106,7 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
|
|||
<div className="mb-4 mt-8 text-gray-900 text-[14px] font-medium leading-tight">
|
||||
{t(`${prefixEmbedded}.explanation`)}
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<div className="flex items-center justify-between">
|
||||
{Object.keys(OPTION_MAP).map((v, index) => {
|
||||
return (
|
||||
<div
|
||||
|
@ -111,7 +124,17 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
|
|||
)
|
||||
})}
|
||||
</div>
|
||||
<div className="mt-6 w-full bg-gray-100 rounded-lg flex-col justify-start items-start inline-flex">
|
||||
{option === 'chromePlugin' && (
|
||||
<div className="mt-6 w-full">
|
||||
<div className={cn('gap-2 py-3 justify-center items-center inline-flex w-full rounded-lg',
|
||||
'bg-primary-600 hover:bg-primary-600/75 hover:shadow-md cursor-pointer text-white hover:shadow-sm flex-shrink-0')}>
|
||||
<div className={`w-4 h-4 relative ${style.pluginInstallIcon}`}></div>
|
||||
<div className="text-white text-sm font-medium font-['Inter'] leading-tight" onClick={navigateToChromeUrl}>{t(`${prefixEmbedded}.chromePlugin`)}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={cn('w-full bg-gray-100 rounded-lg flex-col justify-start items-start inline-flex',
|
||||
'mt-6')}>
|
||||
<div className="self-stretch pl-3 pr-1 py-1 bg-gray-50 rounded-tl-lg rounded-tr-lg border border-black border-opacity-5 justify-start items-center gap-2 inline-flex">
|
||||
<div className="grow shrink basis-0 text-slate-700 text-[13px] font-medium leading-none">
|
||||
{t(`${prefixEmbedded}.${option}`)}
|
||||
|
|
|
@ -12,3 +12,9 @@
|
|||
.scriptsIcon {
|
||||
background-image: url(../assets/scripts-option.svg);
|
||||
}
|
||||
.chromePluginIcon {
|
||||
background-image: url(../assets/chromeplugin-option.svg);
|
||||
}
|
||||
.pluginInstallIcon {
|
||||
background-image: url(../assets/chromeplugin-install.svg);
|
||||
}
|
|
@ -58,6 +58,7 @@ const translation = {
|
|||
explanation: 'Choose the way to embed chat app to your website',
|
||||
iframe: 'To add the chat app any where on your website, add this iframe to your html code.',
|
||||
scripts: 'To add a chat app to the bottom right of your website add this code to your html.',
|
||||
chromePlugin: 'Install Dify Chatbot Chrome Extension',
|
||||
copied: 'Copied',
|
||||
copy: 'Copy',
|
||||
},
|
||||
|
|
|
@ -58,6 +58,7 @@ const translation = {
|
|||
explanation: '选择一种方式将聊天应用嵌入到你的网站中',
|
||||
iframe: '将以下 iframe 嵌入到你的网站中的目标位置',
|
||||
scripts: '将以下代码嵌入到你的网站中',
|
||||
chromePlugin: '安装 Dify Chrome 浏览器扩展',
|
||||
copied: '已复制',
|
||||
copy: '复制',
|
||||
},
|
||||
|
|