跳至主要内容

访客端 WebView 自行接入

App 用自己的 WebView / WKWebView 打开访客页,不接入 Visitor SDK 时按本文对接。

优先使用 访客 SDK 接入文档。本文只覆盖「自己加载页面」。


打开页面​

url 填 控制台配置的 URL 地址,必须 HTTPS。业务参数拼在 query 上,自行做 UTF-8 编码。不要把密码、Cookie、AppSecret 或长期 token 放进 URL。

App 内打开建议带 is_app=1,访客页才会显示关闭按钮。

控制台配置的 URL 地址?is_app=1&lang=zh-cn&theme=system

Android:

webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.loadUrl(buildVisitorUrl())

iOS:

let config = WKWebViewConfiguration()
config.preferences.javaScriptEnabled = true
webView.load(URLRequest(url: visitorURL))

只加载 URL 即可聊天。关闭按钮、原生下载、原生铃声、Android 录音授权需要注入 AppBridge,见下文。


query 参数​

参数必填?含义
is_appApp 内建议 11 时显示关闭按钮,并走 App 返回逻辑
lang可选,默认页面语言界面语言:en / zh-cn / zh-tw / ja / ko / de / fr / pt / ru / es / vi / th / id / ms / tl
theme可选,默认 lightlight / dark / system
direct直达会话时必填 1直达开关,没有它时 chatid 无效
chatid直达会话时必填目标会话 ID(也认 chat_id)
sbs绑用户时必填业务系统里的用户唯一 ID
sbs_mm有 sbs 就要sbs 的签名
ranstr有签名就要参与签名的随机串
name可选访客姓名
nickname可选访客昵称
email可选访客邮箱
phone可选访客手机号
customer_remark可选客户备注
ext_fk_id可选已有访客 ID,用来续历史会话
referer可选来源页 URL(也认 referer_url)
source_title可选来源页标题
new_message_sound_mode可选native:新消息由 App 响铃;不传则页面自己响
source可选webview 隐藏默认返回按钮

不要传 visitor_id。source=webview 效果等同 is_app=1,传一个即可。


WebView 要求​

  • 启用 JavaScript、DOM Storage
  • Cookie / LocalStorage 默认持久化,不要无故清掉(清掉会丢访客身份)
  • 仅加载 HTTPS;系统 ATS / Cleartext 保持默认
  • 同域麦克风、摄像头:在系统里声明权限(Android RECORD_AUDIO / CAMERA;iOS NSMicrophoneUsageDescription / NSCameraUsageDescription)
  • 附件选择走 WebView 文件选择器
  • 同域 HTTPS 留在 WebView;跨域 HTTPS 用系统浏览器

AppBridge​

页面通过 window.AppBridge.call(method, params, callback) 调 App。页面每次加载前注入下面脚本(建议 atDocumentStart,不要等 onPageFinished)。

(function () {
window.__TWT_VISITOR_BRIDGE_CONFIG__ = { newMessageSoundMode: 'web' };
window.AppBridge = {
_callbacks: {},
call: function (method, params, callback) {
var id = callback ? 'cb_' + Date.now() + '_' + Math.random().toString(16).slice(2) : null;
if (callback) this._callbacks[id] = callback;
var msg = JSON.stringify({ method: method, params: params || {}, callback: id });
if (window.AppBridgeChannel_native) {
window.AppBridgeChannel_native.postMessage(msg);
} else if (window.webkit && window.webkit.messageHandlers.AppBridgeChannel) {
window.webkit.messageHandlers.AppBridgeChannel.postMessage(msg);
}
return Promise.resolve({ status: 'sent', callbackId: id });
},
invokeCallback: function (id, result) {
var cb = this._callbacks[id];
if (cb) { cb(result); delete this._callbacks[id]; }
}
};
})();

Android 注册名为 AppBridgeChannel_native 的 JavascriptInterface(方法名 postMessage)。 iOS 注册名为 AppBridgeChannel 的 WKScriptMessageHandler。

消息 JSON:{ "method": "...", "params": {}, "callback": "cb_..." }。

页面会调用的方法​

method何时App 做什么
close用户点页面关闭按钮关闭 WebView / 退出当前页
download保存图片、视频、文件下载 params.url;完成后见下方回传
new_message收到新消息且铃声为 native播放提示音。params 可能含 messageId / chatId
android_recording_permissionAndroid 录音申请麦克风。回传 { code: 1, data: { permission: true/false } }
visitor_back_result页面应答了返回见「系统返回」

不注入 Bridge 时:关闭按钮无效果;下载走浏览器;铃声由页面自己播。

下载回传​

download 的 params:

字段含义
url文件地址
typeimage / video / 其它
fileName建议文件名
mimeTypeMIME
requestId本次下载 ID

有 callback 时,下载结束调用:

window.AppBridge.invokeCallback(callbackId, {
code: 1,
data: { requestId: '...', status: 'completed' }
})

status:completed / failed / cancelled。失败时 code 用 0。

若要把铃声交给 App,注入时把 newMessageSoundMode 设为 'native',或 URL 带 new_message_sound_mode=native。


系统返回(可选)​

用户按系统返回时,先问页面(关闭预览、从会话退回列表):

window.dispatchEvent(new CustomEvent('twt:visitor-event', {
detail: { type: 'back', payload: {} }
}))

约 300ms 内页面会调 visitor_back_result,params.consumed === true 表示已处理。未处理再关闭 WebView。

运行中切主题(仅 light / dark):

window.dispatchEvent(new CustomEvent('twt:visitor-event', {
detail: { type: 'themeChanged', payload: { theme: 'dark' } }
}))