iXserverLoopEnv/db/ixserver/loop_patch.sql

122 lines
9.6 KiB
Transact-SQL
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

-- iXserverLoop 的闭环补丁:在 FeatureTest 种子(test_db_init_script.sql)之上执行。
-- loop.ps1 reset 里与建库、灌种子绑在一起执行,不提供「只建不补」的路径(方案 §8 #6):
-- 种子里是真格式的 FB token 和真实的外部 webhook,不补就起 API,消息会漏到外面。
--
-- 端口与 config\loop.psd1 一致:第三方客户端 5056。改端口要同步改这里。
-- 需要 SQL Server 2016+(JSON_MODIFY)。winbox 上是 SQL Server 2022 Express。
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRANSACTION;
DECLARE @fakeToken NVARCHAR(50) = N'loop-fake-token';
DECLARE @blackhole NVARCHAR(100) = N'http://127.0.0.1:9/loop-blackhole'; -- 9 = discard,本机没人听,立即拒绝连接
DECLARE @chatbot NVARCHAR(200) = N'http://localhost:5056/webhook?mode=ticket-with-source&service_code=epro_ig_demo';
------------------------------------------------------------------------------------------------
-- 1. 所有服务号的真凭据换成假值(列 + all_setting 里的同名字段)
------------------------------------------------------------------------------------------------
UPDATE dbo.service_account_config SET fb_token = @fakeToken WHERE fb_token IS NOT NULL AND fb_token <> N'';
UPDATE dbo.service_account_config SET wc_app_secret = @fakeToken WHERE wc_app_secret IS NOT NULL AND wc_app_secret <> N'';
UPDATE dbo.service_account_config SET wc_account_token = @fakeToken WHERE wc_account_token IS NOT NULL AND wc_account_token <> N'';
UPDATE dbo.service_account_config SET wc_api_token = @fakeToken WHERE wc_api_token IS NOT NULL AND wc_api_token <> N'';
UPDATE dbo.service_account_config SET wc_AESKey = @fakeToken WHERE wc_AESKey IS NOT NULL AND wc_AESKey <> N'';
UPDATE dbo.service_account_config SET line_channel_secret = @fakeToken WHERE line_channel_secret IS NOT NULL AND line_channel_secret <> N'';
UPDATE dbo.service_account_config SET line_long_live_access_token = @fakeToken WHERE line_long_live_access_token IS NOT NULL AND line_long_live_access_token <> N'';
UPDATE dbo.service_account_config SET emma_token = @fakeToken WHERE emma_token IS NOT NULL AND emma_token <> N'';
-- JSON_MODIFY 在 lax 模式下会给不存在的路径新建键,所以每条都先判断路径存在
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.InstagramSetting.FanPageToken', @fakeToken)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.InstagramSetting.FanPageToken') IS NOT NULL;
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.EmmaSetting.Token', @fakeToken)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.EmmaSetting.Token') IS NOT NULL;
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.LineSetting.ChannelSecret', @fakeToken)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.LineSetting.ChannelSecret') IS NOT NULL;
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.LineSetting.LongLiveAccessToken', @fakeToken)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.LineSetting.LongLiveAccessToken') IS NOT NULL;
------------------------------------------------------------------------------------------------
-- 2. 所有服务号指向外部的 chatbot 地址一律打进黑洞(api.commas.hk、hktbchatbot.com 等)
------------------------------------------------------------------------------------------------
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.AISetting.AIProviderWebhook.Webhook', @blackhole)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.AISetting.AIProviderWebhook.Webhook') IS NOT NULL;
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.AutoResponeSetting.CustomChatbotWebhook', @blackhole)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.AutoResponeSetting.CustomChatbotWebhook') IS NOT NULL;
UPDATE dbo.service_account_config SET all_setting = JSON_MODIFY(all_setting, '$.AutoResponeSetting.OfflineChatbotWebhook', @blackhole)
WHERE ISJSON(all_setting) = 1 AND JSON_VALUE(all_setting, '$.AutoResponeSetting.OfflineChatbotWebhook') IS NOT NULL;
UPDATE dbo.service_account_config SET ai_setting = JSON_MODIFY(ai_setting, '$.APIUrl', @blackhole)
WHERE ISJSON(ai_setting) = 1 AND JSON_VALUE(ai_setting, '$.APIUrl') IS NOT NULL;
-- 旧版 ai_setting.DataJson 是「字符串里套 JSON」,里面还有一份 AIProviderWebhook.Webhook。
-- DataJson 动辄超过 4000 字,JSON_VALUE 会返回 NULL,所以用 OPENJSON 取整段
UPDATE c SET ai_setting = JSON_MODIFY(c.ai_setting, '$.DataJson', JSON_MODIFY(j.DataJson, '$.AIProviderWebhook.Webhook', @blackhole))
FROM dbo.service_account_config c
CROSS APPLY OPENJSON(c.ai_setting) WITH (DataJson NVARCHAR(MAX) '$.DataJson') j
WHERE ISJSON(c.ai_setting) = 1 AND ISJSON(j.DataJson) = 1
AND JSON_VALUE(j.DataJson, '$.AIProviderWebhook.Webhook') IS NOT NULL;
------------------------------------------------------------------------------------------------
-- 3. 被测服务号 epro_ig_demo:chatbot 指向本地第三方客户端,模板走 ABP
-- 切人工、客服在线、额度池不写在这里,由 SCRM 模拟调接口完成(方案 §4)
------------------------------------------------------------------------------------------------
IF NOT EXISTS (SELECT 1 FROM dbo.service_account_config WHERE code = N'epro_ig_demo' AND ISJSON(all_setting) = 1)
THROW 50001, N'种子里找不到 epro_ig_demo 或它的 all_setting 不是 JSON', 1;
UPDATE dbo.service_account_config
SET all_setting = JSON_MODIFY(JSON_MODIFY(all_setting,
'$.AISetting.AIProviderWebhook.Webhook', @chatbot),
'$.ChatMessageSetting.CurrentProviderKey', N'AbpServiceAccountChatMessageProvider')
WHERE code = N'epro_ig_demo';
-- 客服上线转人工(IG 转人工方案 §9.1):流程开关打开。服务号开着 chatbot 时 CheckEligible 第 ④ 条不成立,
-- 所以不影响 S1;SCRM 开工(切人工 + 在线)后,遗留在机器人手里的工单下一条消息就会问要不要转人工。
-- 线上 Line 服务号的实际配置未导出,这里取方案的默认组合:问句排在第三方回复之后、No 继续机器人
UPDATE dbo.service_account_config
SET all_setting = JSON_MODIFY(all_setting, '$.DisconnectChatbotFlowSetting', JSON_QUERY(N'{
"Enable": true, "NeedNormalRespone": true, "EnableReconfirm": false, "EnableShowGoodbye": true,
"MatchCaseSensitive": false, "YesValues": ["yes", "contact agent"], "NoValues": ["no"],
"ClickNoToEndTicket": false, "ClickNoToShowMainMenu": false, "NeedInclueResponeInLastTicketInfo": true,
"NeedReactiveAfterIgnore": false, "NeedGreetingForNewTicket": false }'))
WHERE code = N'epro_ig_demo';
-- 条款同意(docs\IG 条款同意流程方案.html):存了 T_and_C_Setting 且 ABP 模板里有条款才启用,两样缺一就静默不启用。
-- 模板用本地 ABP 的 epro_ig_demo,所以这里只开设置;间隔取代码默认的 10080 分钟(7 天)。
-- 对第三方 chatbot 服务号同样生效:新用户第一句话被条款拦下,场景先调 scenarios\_lib.ps1 的 Complete-LoopTnC 走完同意。
-- staging 的条款组缺「请点 Agree」那条、没按钮可点;闭环 ABP 已补上(db\abp\loop_patch.sql 第 3 节)
UPDATE dbo.service_account_config
SET all_setting = JSON_MODIFY(all_setting, '$.T_and_C_Setting', JSON_QUERY(N'{ "NeedSendAfterMinutes": 10080 }'))
WHERE code = N'epro_ig_demo';
------------------------------------------------------------------------------------------------
-- 4. 第三方 client 登记:两张表都要有 setsail(方案 §2 链路 c)。ip_whitelist 留空 = 不限来源
------------------------------------------------------------------------------------------------
DELETE FROM dbo.third_party_chatbot_client WHERE client_id = N'setsail';
DELETE FROM dbo.oauth_client WHERE client_id = N'setsail';
INSERT INTO dbo.oauth_client (id, client_id, name, allowed_scopes, ip_whitelist, enabled, create_datetime, update_datetime)
VALUES (1001, N'setsail', N'setsail (loop)', N'ixserver_chatbot', NULL, 1, GETDATE(), GETDATE());
INSERT INTO dbo.third_party_chatbot_client (id, client_id, service_codes, create_datetime, update_datetime)
VALUES (1001, N'setsail', N'epro_ig_demo', GETDATE(), GETDATE());
------------------------------------------------------------------------------------------------
-- 5. 自检:补完之后库里不应再有任何真 token 或外部 chatbot 地址
------------------------------------------------------------------------------------------------
DECLARE @leaks INT = (
SELECT COUNT(*) FROM dbo.service_account_config
WHERE (fb_token IS NOT NULL AND fb_token NOT IN (N'', @fakeToken))
OR all_setting LIKE N'%commas.hk/%Webhook%'
OR all_setting LIKE N'%hktbchatbot.com%'
OR ai_setting LIKE N'%commas.hk/%Webhook%'
OR ai_setting LIKE N'%hktbchatbot.com%');
IF @leaks > 0
THROW 50002, N'补丁后仍有服务号带着真 token 或外部 chatbot 地址,检查种子里是否出现了新字段', 1;
COMMIT TRANSACTION;
SELECT code,
JSON_VALUE(all_setting, '$.AISetting.IsEnable') AS ai_enable,
JSON_VALUE(all_setting, '$.AISetting.AIProviderWebhook.Webhook') AS webhook,
JSON_VALUE(all_setting, '$.ChatMessageSetting.CurrentProviderKey') AS message_provider,
JSON_VALUE(all_setting, '$.InstagramSetting.InstagramAccount') AS ig_account,
JSON_VALUE(all_setting, '$.InstagramSetting.FanPageToken') AS ig_token,
JSON_VALUE(all_setting, '$.T_and_C_Setting.NeedSendAfterMinutes') AS tnc_minutes
FROM dbo.service_account_config WHERE code = N'epro_ig_demo';