可以和知你客服通信
This commit is contained in:
@@ -4,6 +4,8 @@ import android.os.Bundle;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
@@ -97,18 +99,41 @@ public class AgentChatActivity extends AppCompatActivity {
|
|||||||
appendBotMessage(reply);
|
appendBotMessage(reply);
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(AgentChatActivity.this, "请求失败: " + response.message(), Toast.LENGTH_SHORT).show();
|
String errMsg = getErrorMessage(response);
|
||||||
|
Toast.makeText(AgentChatActivity.this, errMsg, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<ApiService.AgentChatResponse> call, Throwable t) {
|
public void onFailure(Call<ApiService.AgentChatResponse> call, Throwable t) {
|
||||||
binding.btnSend.setEnabled(true);
|
binding.btnSend.setEnabled(true);
|
||||||
Toast.makeText(AgentChatActivity.this, "请求失败: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
String msg = t.getMessage();
|
||||||
|
if (msg == null || msg.isEmpty()) msg = "网络异常";
|
||||||
|
Toast.makeText(AgentChatActivity.this, "知你客服暂不可用: " + msg, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 从 502/503 等错误响应中解析后端返回的 error 文案 */
|
||||||
|
private String getErrorMessage(Response<ApiService.AgentChatResponse> response) {
|
||||||
|
try {
|
||||||
|
if (response.errorBody() != null) {
|
||||||
|
String body = response.errorBody().string();
|
||||||
|
if (!body.isEmpty()) {
|
||||||
|
JSONObject jo = new JSONObject(body);
|
||||||
|
if (jo.has("error")) {
|
||||||
|
return jo.optString("error", "知你客服暂不可用,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) { }
|
||||||
|
int code = response.code();
|
||||||
|
if (code == 502 || code == 503) {
|
||||||
|
return "知你客服暂不可用,请稍后重试";
|
||||||
|
}
|
||||||
|
return "请求失败: " + response.message();
|
||||||
|
}
|
||||||
|
|
||||||
private void appendUserMessage(String content) {
|
private void appendUserMessage(String content) {
|
||||||
ApiService.Message m = new ApiService.Message();
|
ApiService.Message m = new ApiService.Message();
|
||||||
m.id = "local_u_" + System.currentTimeMillis();
|
m.id = "local_u_" + System.currentTimeMillis();
|
||||||
|
|||||||
@@ -30,5 +30,16 @@ def agent_chat():
|
|||||||
try:
|
try:
|
||||||
reply = chat_with_agent(base_url, username, password, agent_id, message, user_id)
|
reply = chat_with_agent(base_url, username, password, agent_id, message, user_id)
|
||||||
return jsonify({"reply": reply or ""})
|
return jsonify({"reply": reply or ""})
|
||||||
|
except ValueError as e:
|
||||||
|
err = str(e)
|
||||||
|
if "401" in err or "登录失败" in err:
|
||||||
|
return jsonify({"error": err}), 503
|
||||||
|
return jsonify({"error": err}), 502
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"error": str(e)}), 502
|
err = str(e)
|
||||||
|
# 任何包含 401/Unauthorized 的异常都视为平台认证失败,返回友好提示
|
||||||
|
if "401" in err or "Unauthorized" in err:
|
||||||
|
return jsonify({
|
||||||
|
"error": "知你客服平台登录失败(401),请确认 8037 服务已启动且 PLATFORM_USERNAME/PLATFORM_PASSWORD 正确"
|
||||||
|
}), 503
|
||||||
|
return jsonify({"error": err}), 502
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ class Config:
|
|||||||
"""Base config."""
|
"""Base config."""
|
||||||
SECRET_KEY = os.getenv("SECRET_KEY", "dev-secret-change-in-production")
|
SECRET_KEY = os.getenv("SECRET_KEY", "dev-secret-change-in-production")
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||||
# 知你客服 Agent 代理(方式一):低代码平台地址与对接账号(用户名 amind,密码 123456)
|
# 知你客服 Agent 代理:与 androidExampleDemo 一致,8037 使用 admin/123456
|
||||||
PLATFORM_BASE_URL = os.getenv("PLATFORM_BASE_URL", "http://101.43.95.130:8037")
|
PLATFORM_BASE_URL = os.getenv("PLATFORM_BASE_URL", "http://101.43.95.130:8037")
|
||||||
PLATFORM_USERNAME = os.getenv("PLATFORM_USERNAME", "amind")
|
PLATFORM_USERNAME = os.getenv("PLATFORM_USERNAME", "admin")
|
||||||
PLATFORM_PASSWORD = os.getenv("PLATFORM_PASSWORD", "123456")
|
PLATFORM_PASSWORD = os.getenv("PLATFORM_PASSWORD", "123456")
|
||||||
PLATFORM_AGENT_ID = os.getenv("PLATFORM_AGENT_ID", "7332bba7-f9e7-4e10-9af6-7a0509a3ef97")
|
PLATFORM_AGENT_ID = os.getenv("PLATFORM_AGENT_ID", "7332bba7-f9e7-4e10-9af6-7a0509a3ef97")
|
||||||
JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1)
|
JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1)
|
||||||
|
|||||||
@@ -21,12 +21,26 @@ def _get_platform_token(base_url, username, password):
|
|||||||
return _platform_token
|
return _platform_token
|
||||||
url = f"{base_url.rstrip('/')}/api/v1/auth/login"
|
url = f"{base_url.rstrip('/')}/api/v1/auth/login"
|
||||||
try:
|
try:
|
||||||
|
# 8037 使用 form 登录;先 form,失败再试 JSON
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
url,
|
url,
|
||||||
data={"username": username, "password": password},
|
data={"username": username, "password": password},
|
||||||
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
if r.status_code == 422:
|
||||||
|
logger.warning("平台登录 form 返回 422,尝试 JSON: %s", r.text[:200] if r.text else "")
|
||||||
|
r = requests.post(
|
||||||
|
url,
|
||||||
|
json={"username": username, "password": password},
|
||||||
|
headers={"Content-Type": "application/json"},
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
if r.status_code == 401:
|
||||||
|
logger.warning("平台登录仍 401,请检查 PLATFORM_USERNAME/PLATFORM_PASSWORD 及平台账号: %s", r.text[:200] if r.text else "")
|
||||||
|
raise ValueError(
|
||||||
|
"知你客服平台登录失败(401),请确认 8037 服务已启动且 PLATFORM_USERNAME/PLATFORM_PASSWORD 正确"
|
||||||
|
)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
data = r.json()
|
data = r.json()
|
||||||
token = data.get("access_token")
|
token = data.get("access_token")
|
||||||
@@ -35,6 +49,15 @@ def _get_platform_token(base_url, username, password):
|
|||||||
_platform_token = token
|
_platform_token = token
|
||||||
_token_expires_at = time.time() + 3600 # 假设 1 小时有效
|
_token_expires_at = time.time() + 3600 # 假设 1 小时有效
|
||||||
return token
|
return token
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
if e.response is not None and e.response.status_code == 401:
|
||||||
|
raise ValueError(
|
||||||
|
"知你客服平台登录失败(401),请确认 8037 服务已启动且账号配置正确"
|
||||||
|
)
|
||||||
|
logger.exception("平台登录失败: %s", e)
|
||||||
|
raise
|
||||||
|
except ValueError:
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("平台登录失败: %s", e)
|
logger.exception("平台登录失败: %s", e)
|
||||||
raise
|
raise
|
||||||
|
|||||||
67
saars/backend/scripts/check_platform_login.sh
Normal file
67
saars/backend/scripts/check_platform_login.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 检查 8037 平台是否可访问,以及登录接口是否可用
|
||||||
|
# 用法: bash scripts/check_platform_login.sh
|
||||||
|
# 或指定账号: PLATFORM_USERNAME=你的账号 PLATFORM_PASSWORD=你的密码 bash scripts/check_platform_login.sh
|
||||||
|
|
||||||
|
BASE_URL="${PLATFORM_BASE_URL:-http://101.43.95.130:8037}"
|
||||||
|
USER="${PLATFORM_USERNAME:-admin}"
|
||||||
|
PASS="${PLATFORM_PASSWORD:-123456}"
|
||||||
|
|
||||||
|
echo "=== 1. 检查 8037 是否可访问 ==="
|
||||||
|
echo "GET $BASE_URL"
|
||||||
|
if curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$BASE_URL" | grep -qE '^[23]'; then
|
||||||
|
echo " 可访问"
|
||||||
|
else
|
||||||
|
echo " 无法访问或超时,请检查 8037 服务是否启动、防火墙/安全组是否放行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== 2. 尝试登录(先 form,再 JSON) ==="
|
||||||
|
|
||||||
|
# 先试 form(8037 可能只接受 form)
|
||||||
|
echo "2a. POST form: username=$USER, password=***"
|
||||||
|
RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/v1/auth/login" \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-d "username=$USER&password=$PASS" \
|
||||||
|
--connect-timeout 10)
|
||||||
|
HTTP_BODY=$(echo "$RESP" | head -n -1)
|
||||||
|
HTTP_CODE=$(echo "$RESP" | tail -n 1)
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then
|
||||||
|
echo " form 状态: $HTTP_CODE, 响应: $HTTP_BODY"
|
||||||
|
echo "2b. POST JSON: {\"username\":\"$USER\",\"password\":\"***\"}"
|
||||||
|
RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/v1/auth/login" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"$USER\",\"password\":\"$PASS\"}" \
|
||||||
|
--connect-timeout 10)
|
||||||
|
HTTP_BODY=$(echo "$RESP" | head -n -1)
|
||||||
|
HTTP_CODE=$(echo "$RESP" | tail -n 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
|
||||||
|
echo " 状态: $HTTP_CODE 成功"
|
||||||
|
if echo "$HTTP_BODY" | grep -q "access_token"; then
|
||||||
|
echo " 响应含 access_token,登录正常"
|
||||||
|
else
|
||||||
|
echo " 响应无 access_token,内容: $HTTP_BODY"
|
||||||
|
fi
|
||||||
|
elif [ "$HTTP_CODE" = "401" ]; then
|
||||||
|
echo " 状态: 401 未授权"
|
||||||
|
echo " 响应: $HTTP_BODY"
|
||||||
|
echo " -> 请确认 8037 上账号 $USER 的密码是否正确"
|
||||||
|
exit 1
|
||||||
|
elif [ "$HTTP_CODE" = "422" ]; then
|
||||||
|
echo " 状态: 422 参数错误"
|
||||||
|
echo " 响应: $HTTP_BODY"
|
||||||
|
echo " -> 8037 可能要求 form 或不同字段名,已尝试 form 与 JSON"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo " 状态: $HTTP_CODE"
|
||||||
|
echo " 响应: $HTTP_BODY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== 3. 若上面都成功,SAARS 后端应能正常代理知你客服 ==="
|
||||||
|
echo " 重启后端: cd saars && docker compose restart backend"
|
||||||
@@ -10,9 +10,9 @@ services:
|
|||||||
PORT: "8052"
|
PORT: "8052"
|
||||||
DATABASE_URL: mysql+pymysql://root:!Rjb12191@gz-cynosdbmysql-grp-d26pzce5.sql.tencentcdb.com:24936/liaotian_db?charset=utf8mb4
|
DATABASE_URL: mysql+pymysql://root:!Rjb12191@gz-cynosdbmysql-grp-d26pzce5.sql.tencentcdb.com:24936/liaotian_db?charset=utf8mb4
|
||||||
REDIS_URL: redis://redis:6379/0
|
REDIS_URL: redis://redis:6379/0
|
||||||
# 知你客服 Agent 代理(方式一):平台账号 amind/123456;Agent ID 需在平台 Agent 管理中点「知你客服」复制
|
# 知你客服 Agent 代理(与 androidExampleDemo 一致:admin/123456,8037 form 登录)
|
||||||
PLATFORM_BASE_URL: http://101.43.95.130:8037
|
PLATFORM_BASE_URL: http://101.43.95.130:8037
|
||||||
PLATFORM_USERNAME: amind
|
PLATFORM_USERNAME: admin
|
||||||
PLATFORM_PASSWORD: "123456"
|
PLATFORM_PASSWORD: "123456"
|
||||||
PLATFORM_AGENT_ID: "7332bba7-f9e7-4e10-9af6-7a0509a3ef97"
|
PLATFORM_AGENT_ID: "7332bba7-f9e7-4e10-9af6-7a0509a3ef97"
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
Reference in New Issue
Block a user