🔄 卡若AI 同步 2026-03-23 20:12 | 更新:金仓、水桥平台对接、卡木、运营中枢、运营中枢工作台 | 排除 >20MB: 11 个
This commit is contained in:
@@ -1,13 +1,37 @@
|
||||
{
|
||||
"updated": "2026-03-23T08:37:37.372613+00:00",
|
||||
"updated": "2026-03-23T12:12:36.198299+00:00",
|
||||
"conversations": [
|
||||
{
|
||||
"对话ID": "6afeb85a-5117-478f-a216-b3bfebae5b51",
|
||||
"名称": "信用卡请求",
|
||||
"项目": "卡若AI",
|
||||
"首条消息": "卡若ai把我的信用卡发给我",
|
||||
"创建时间": "2026-03-23T12:09:02.290000+00:00",
|
||||
"消息数量": 13
|
||||
},
|
||||
{
|
||||
"对话ID": "462c354b-4f31-4180-9069-aad14a8a0937",
|
||||
"名称": "卡若ai 邮箱注册",
|
||||
"项目": "卡若AI",
|
||||
"首条消息": "卡若ai 用skill注册一个邮箱",
|
||||
"创建时间": "2026-03-23T12:03:58.396000+00:00",
|
||||
"消息数量": 10
|
||||
},
|
||||
{
|
||||
"对话ID": "5d22bebc-ecf7-46b2-aede-bea3b0b14d93",
|
||||
"名称": "Rule configuration UI in admin panel",
|
||||
"项目": "Soul创业",
|
||||
"首条消息": "In the project at /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验-永平, I need to understand the rule configuration UI in the admin panel.\n\n1. Search for \"UserRule\" or \"user-rules\" or \"规则配置\" in the admin frontend (soul-admin/src/)\n2. The rules tab is in UsersPage.tsx - find the \"rules\" TabsContent section and report the full JSX for it\n3. Read the existing rules CRUD UI - how are rules listed, created, edited?\n4. Check if descriptions are currently shown inline\n\nReport all findings with exact line nu",
|
||||
"创建时间": "2026-03-23T10:14:23.470000+00:00",
|
||||
"消息数量": 18
|
||||
},
|
||||
{
|
||||
"对话ID": "4ef4d028-04ea-4ea1-b7ce-e43b353b10ca",
|
||||
"名称": "Web CLI skill integration",
|
||||
"项目": "卡若AI",
|
||||
"首条消息": "上面搜索网页cli的 skill。GitHub 上面搜索最新的网页,西游记分数最高的那个,然后帮我整合到卡罗伊的 skill 里面",
|
||||
"创建时间": "2026-03-23T08:19:23.549000+00:00",
|
||||
"消息数量": 127
|
||||
"消息数量": 129
|
||||
},
|
||||
{
|
||||
"对话ID": "f8f37966-e2ff-42a0-90bc-a28c005698c6",
|
||||
@@ -216,30 +240,6 @@
|
||||
"首条消息": "那个告诉我的注册信用卡的 skill,然后把这个我最近注册的卡发给我",
|
||||
"创建时间": "2026-03-20T23:40:45.815000+00:00",
|
||||
"消息数量": 13
|
||||
},
|
||||
{
|
||||
"对话ID": "93c2142a-5a2a-46c4-ba71-a09d3b195215",
|
||||
"名称": "AI Brain project exploration",
|
||||
"项目": "微信管理",
|
||||
"首条消息": "I need to explore the AI Brain related code and scripts in the work phone project. Please find and summarize:\n\n1. All files related to AI Brain in the project at /Users/karuo/Documents/开发/2、私域银行/工作手机/\n2. All skill files under sdk/agent/skills/ - what skills exist and their actions\n3. The ai_brain module if it exists under sdk/agent/\n4. The index.html smart engine / AI Brain section (search for \"智能引擎\" or \"AI Brain\" in the static files)\n5. Any existing scripts or automation modules\n6. The wechat_h",
|
||||
"创建时间": "2026-03-20T16:31:04.926000+00:00",
|
||||
"消息数量": 1
|
||||
},
|
||||
{
|
||||
"对话ID": "f756e455-b371-44e7-841e-ada153aefeee",
|
||||
"名称": "WeChat account and device management UI",
|
||||
"项目": "微信管理",
|
||||
"首条消息": "You need to explore the Cunkebao v3 frontend project at `/Users/karuo/Documents/开发/2、私域银行/cunkebao_v3/Cunkebao/src` to understand how they design their WeChat account management and device management UI.\n\nSpecifically, look at these areas:\n1. `pages/mobile/mine/wechat-accounts/` - WeChat accounts list and detail pages\n2. `pages/mobile/mine/workphone/` - Work phone / device management pages \n3. `pages/mobile/mine/devices/` - Device management pages\n4. `components/DeviceSelection/` - Device selec",
|
||||
"创建时间": "2026-03-20T15:18:46.161000+00:00",
|
||||
"消息数量": 1
|
||||
},
|
||||
{
|
||||
"对话ID": "1aa14661-39a1-4bb8-a189-e986cbbb233a",
|
||||
"名称": "工作手机项目文件搜索",
|
||||
"项目": "开发",
|
||||
"首条消息": "在工作手机项目中,搜索以下内容并返回关键信息:\n\n1. 找到 `机擎/阿机/SKILL.md` 文件,返回其中关于 Hook/Frida 相关的部分\n2. 找到 `sdk/app/routers/unified.py` 中关于设备管理和 hook 相关的路由定义\n3. 找到 `sdk/app/services/hook_module_service.py` 的内容摘要\n4. 找到 `开发文档/8、部署/README.md` 的内容\n5. 找到 `机擎/SKILL.md` 中 § 一 岗位职责部分\n\n搜索目录: /Users/karuo/Documents/开发/2、私域银行/工作手机\n\n返回每个文件的关键内容和路径。",
|
||||
"创建时间": "2026-03-20T14:46:24.917000+00:00",
|
||||
"消息数量": 18
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -26,10 +26,27 @@
|
||||
| 电话 | `400-9030057` 客户服务;`400-9030142` 为不良信息举报专线 |
|
||||
| 官网 | <https://www.soulapp.cn/contact> |
|
||||
|
||||
**发信**(11 位手机号为绑定号,两版话术):
|
||||
**发信**(11 位手机号为绑定号,单封大白话):
|
||||
`python3 运营中枢/scripts/send_soul_appeal_mail.py 15210897710`
|
||||
`python3 运营中枢/scripts/send_soul_appeal_mail.py 13779954946`
|
||||
|
||||
**平台短信引用条款后的「分主题补充申诉」**(每号连发 4 封不同主题至同一批邮箱,间隔约 3 秒):
|
||||
`python3 运营中枢/scripts/send_soul_appeal_mail.py 15210897710 --suite`
|
||||
`python3 运营中枢/scripts/send_soul_appeal_mail.py --all-phones --suite`(152 + 137 各 4 封,共 8 封)
|
||||
|
||||
### Soul《用户协议》被引用条款怎么理解?(辅助说明,以 App 内最新版为准)
|
||||
|
||||
官方短信常见表述:违反 **2.2.3、2.2.4、2.2.5、3.2.11(1)—(8)、3.2.12** 等。
|
||||
|
||||
| 条款 | 常见含义(概括) | 备注 |
|
||||
|:---|:---|:---|
|
||||
| **2.2.3 / 2.2.4** | 与 **2.2** 节「用户使用账号时应遵守的义务」相关,多涉及**守法、不得干扰平台秩序**等 | 公开网页难逐字核对,**务必在 Soul App → 设置 → 关于 Soul → 用户协议** 打开当前版本对照 |
|
||||
| **2.2.5** | 黑猫投诉等渠道有用户转述:不得利用账号**违法活动、捣乱、骚扰、欺骗其他用户**及**其他违反本协议的行为** | 与「骚扰/欺诈/破坏秩序」类处罚常一并出现 |
|
||||
| **3.2.11(1)—(8)** | 多为**禁止发布或传播的信息类型**的**前八项列举**(如违法有害、低俗、侵权、虚假、营销导流等方向,**具体以协议原文分项为准**) | 平台若未告知触线子项,可邮件请求**指明项号与事实概要**以便整改 |
|
||||
| **3.2.12** | 常与 3.2.11 同属**内容与行为规范**,多为**并列或递进的禁止性规定**(以原文为准) | 再申诉宜写清**整改承诺**,避免空怼 |
|
||||
|
||||
**策略**:申诉未通过后,宜 **请求具体违规事实** + **分项承诺合规** + **申请二次复核**;**不能保证**一定解封。
|
||||
|
||||
---
|
||||
|
||||
## 二、抖音
|
||||
|
||||
@@ -137,6 +137,11 @@ class EmailService:
|
||||
if self.email_type == "tempmail":
|
||||
return self._gen_tempmail()
|
||||
elif self.email_type == "mailtm":
|
||||
fixed = self._mailtm_fixed_credentials()
|
||||
if fixed:
|
||||
addr, pwd = fixed
|
||||
log.info("[邮箱] 使用固定 mail.tm(MAILTM_ADDRESS 或 config.mailtm.fixed_*)")
|
||||
return self._mailtm_login(addr, pwd)
|
||||
return self._gen_mailtm()
|
||||
elif self.email_type == "cloudflare_worker":
|
||||
return self._gen_cf_worker()
|
||||
@@ -151,29 +156,33 @@ class EmailService:
|
||||
email = f"{prefix}{random_suffix}@tempmail.plus"
|
||||
return email, {"type": "tempmail", "pin": cfg.get("pin", "")}
|
||||
|
||||
def _gen_mailtm(self) -> tuple[str, dict]:
|
||||
"""mail.tm API 创建临时邮箱,可收验证码(与 Cerebras 同源)"""
|
||||
def _mailtm_fixed_credentials(self) -> Optional[tuple[str, str]]:
|
||||
"""环境变量或 config.mailtm 固定账号,供 Cursor 等复用已创建的 mail.tm。"""
|
||||
cfg = self.config.get("mailtm") or {}
|
||||
addr = (os.environ.get("MAILTM_ADDRESS") or cfg.get("fixed_address") or "").strip()
|
||||
pwd = (os.environ.get("MAILTM_PASSWORD") or cfg.get("fixed_password") or "").strip()
|
||||
if addr and pwd:
|
||||
return addr, pwd
|
||||
return None
|
||||
|
||||
def _mailtm_login(self, address: str, password: str) -> tuple[str, dict]:
|
||||
import httpx
|
||||
api = "https://api.mail.tm"
|
||||
r = httpx.get(f"{api}/domains", timeout=10)
|
||||
domains = r.json().get("hydra:member", [])
|
||||
if not domains:
|
||||
raise RuntimeError("mail.tm 无可用域名")
|
||||
domain = domains[0]["domain"]
|
||||
prefix = "".join(random.choices(string.ascii_lowercase + string.digits, k=12))
|
||||
email = f"{prefix}@{domain}"
|
||||
password = "".join(random.choices(string.ascii_letters + string.digits, k=16))
|
||||
r = httpx.post(f"{api}/accounts", json={"address": email, "password": password}, timeout=15)
|
||||
if r.status_code not in (200, 201):
|
||||
raise RuntimeError(f"mail.tm 创建账号失败: {r.status_code} {r.text[:100]}")
|
||||
r = httpx.post(f"{api}/token", json={"address": email, "password": password}, timeout=10)
|
||||
t = 25
|
||||
r = httpx.post(
|
||||
f"{api}/token",
|
||||
json={"address": address, "password": password},
|
||||
timeout=t,
|
||||
)
|
||||
if r.status_code != 200:
|
||||
raise RuntimeError("mail.tm 获取 token 失败")
|
||||
raise RuntimeError(f"mail.tm 登录/token 失败: {r.status_code} {r.text[:120]}")
|
||||
token = r.json().get("token", "")
|
||||
return email, {"type": "mailtm", "token": token}
|
||||
if not token:
|
||||
raise RuntimeError("mail.tm 返回空 token")
|
||||
return address, {"type": "mailtm", "token": token}
|
||||
|
||||
def _gen_mailtm(self) -> tuple[str, dict]:
|
||||
"""mail.tm API 创建临时邮箱,可收 Cursor 等验证码"""
|
||||
"""mail.tm API 新建临时邮箱(Cursor / Cerebras 等同源)"""
|
||||
import httpx
|
||||
api = "https://api.mail.tm"
|
||||
t = 25
|
||||
@@ -188,38 +197,7 @@ class EmailService:
|
||||
r = httpx.post(f"{api}/accounts", json={"address": email, "password": password}, timeout=t)
|
||||
if r.status_code not in (200, 201):
|
||||
raise RuntimeError(f"mail.tm 创建失败: {r.status_code} {r.text[:80]}")
|
||||
r = httpx.post(f"{api}/token", json={"address": email, "password": password}, timeout=t)
|
||||
if r.status_code != 200:
|
||||
raise RuntimeError(f"mail.tm token 失败: {r.status_code}")
|
||||
token = r.json().get("token", "")
|
||||
return email, {"type": "mailtm", "token": token}
|
||||
|
||||
def _poll_mailtm(self, context: dict, timeout: int) -> Optional[str]:
|
||||
"""轮询 mail.tm 收件箱提取 6 位验证码"""
|
||||
import httpx
|
||||
token = context.get("token", "")
|
||||
if not token:
|
||||
return None
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
api = "https://api.mail.tm"
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
try:
|
||||
r = httpx.get(f"{api}/messages", headers=headers, timeout=10)
|
||||
for msg in r.json().get("hydra:member", []):
|
||||
mid = msg.get("id", "")
|
||||
if not mid:
|
||||
continue
|
||||
d = httpx.get(f"{api}/messages/{mid}", headers=headers, timeout=10).json()
|
||||
subject = d.get("subject", "")
|
||||
text = d.get("text", "") or (d.get("html") or [""])[0] if isinstance(d.get("html"), list) else ""
|
||||
code = self._extract_code(subject, text)
|
||||
if code:
|
||||
return code
|
||||
except Exception as e:
|
||||
log.warning(f"[邮箱] mail.tm 轮询异常: {e}")
|
||||
time.sleep(3)
|
||||
return None
|
||||
return self._mailtm_login(email, password)
|
||||
|
||||
def _gen_cf_worker(self) -> tuple[str, dict]:
|
||||
import httpx
|
||||
@@ -363,14 +341,23 @@ class EmailService:
|
||||
return None
|
||||
|
||||
def _extract_code(self, subject: str, body: str) -> Optional[str]:
|
||||
"""从邮件主题和正文中提取 6 位 OTP"""
|
||||
"""从邮件主题和正文中提取 6 位 OTP(正文可为 HTML)"""
|
||||
import re as _re
|
||||
|
||||
def _strip_html(s: str) -> str:
|
||||
return _re.sub(r"<[^>]+>", " ", s or "")
|
||||
|
||||
plain = (body or "") + "\n" + _strip_html(body or "")
|
||||
precise = self.RE_CODE_PRECISE.search(subject)
|
||||
if precise:
|
||||
return precise.group(1)
|
||||
precise = self.RE_CODE_PRECISE.search(body)
|
||||
precise = self.RE_CODE_PRECISE.search(plain)
|
||||
if precise:
|
||||
return precise.group(1)
|
||||
match = self.RE_OTP.search(subject)
|
||||
if match:
|
||||
return match.group(1)
|
||||
match = self.RE_OTP.search(plain)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
@@ -58,6 +58,13 @@ class CursorProvider(BaseProvider):
|
||||
self.provider_config = config.get("providers", {}).get("cursor", {})
|
||||
self.browser_config = config.get("browser", {})
|
||||
|
||||
def _effective_headless(self) -> bool:
|
||||
"""CURSOR_HEADLESS=0|false|no 时强制有界面,利于 Turnstile。"""
|
||||
v = os.environ.get("CURSOR_HEADLESS", "").strip().lower()
|
||||
if v in ("0", "false", "no", "off"):
|
||||
return False
|
||||
return self.browser_config.get("headless", True)
|
||||
|
||||
def _create_browser(self):
|
||||
# 参考 ddCat-main/cursor-auto-register browser_utils:auto_port() + headless()
|
||||
from DrissionPage import ChromiumPage, ChromiumOptions
|
||||
@@ -70,7 +77,7 @@ class CursorProvider(BaseProvider):
|
||||
co.set_argument("--remote-allow-origins=*")
|
||||
co.set_argument("--window-size=1920,1080")
|
||||
co.auto_port()
|
||||
use_headless = self.browser_config.get("headless", True)
|
||||
use_headless = self._effective_headless()
|
||||
if use_headless:
|
||||
co.set_argument("--headless=new")
|
||||
co.headless(use_headless)
|
||||
@@ -95,7 +102,7 @@ class CursorProvider(BaseProvider):
|
||||
return None
|
||||
signup_url = self.provider_config.get("signup_url", SIGNUP_URL)
|
||||
settings_url = self.provider_config.get("settings_url", SETTINGS_URL)
|
||||
headless = self.browser_config.get("headless", True)
|
||||
headless = self._effective_headless()
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=headless, args=["--no-sandbox"])
|
||||
try:
|
||||
@@ -103,22 +110,21 @@ class CursorProvider(BaseProvider):
|
||||
page.goto(signup_url, wait_until="domcontentloaded", timeout=45000)
|
||||
time.sleep(5)
|
||||
log.info(f" [1/6] 打开注册页面 (Playwright)")
|
||||
page.wait_for_selector('input', state="visible", timeout=25000)
|
||||
time.sleep(1)
|
||||
inputs = page.locator('input[type="text"], input[type="email"], input:not([type])')
|
||||
n = inputs.count()
|
||||
if n >= 3:
|
||||
inputs.nth(0).fill(first)
|
||||
time.sleep(0.15)
|
||||
inputs.nth(1).fill(last)
|
||||
time.sleep(0.15)
|
||||
inputs.nth(2).fill(email)
|
||||
else:
|
||||
page.locator('input[name="first_name"], input[name="firstName"]').first.fill(first)
|
||||
time.sleep(0.15)
|
||||
page.locator('input[name="last_name"], input[name="lastName"]').first.fill(last)
|
||||
time.sleep(0.15)
|
||||
page.locator('input[name="email"], input[type="email"]').first.fill(email)
|
||||
# 勿用裸 input,否则会命中 type=hidden(如 signals)
|
||||
fn = page.locator(
|
||||
'input[name="first_name"], input[name="firstName"], input[autocomplete="given-name"]'
|
||||
).first
|
||||
fn.wait_for(state="visible", timeout=45000)
|
||||
time.sleep(0.5)
|
||||
fn.fill(first)
|
||||
time.sleep(0.15)
|
||||
page.locator(
|
||||
'input[name="last_name"], input[name="lastName"], input[autocomplete="family-name"]'
|
||||
).first.fill(last)
|
||||
time.sleep(0.15)
|
||||
page.locator(
|
||||
'input[name="email"], input[type="email"], input[autocomplete="email"]'
|
||||
).first.fill(email)
|
||||
time.sleep(0.5)
|
||||
page.locator('button[type="submit"], input[type="submit"], [type="submit"]').first.click()
|
||||
time.sleep(3)
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
"""从卡若 gateway .env 读 SMTP,向 Soul 官方各邮箱发申诉邮件。
|
||||
|
||||
收件人:soul@、hr@、ad@、commercial-b@、pc@(官网公示的 5 个邮箱)。
|
||||
|
||||
用法:
|
||||
python3 send_soul_appeal_mail.py 15210897710 # 大白话 A 版
|
||||
python3 send_soul_appeal_mail.py 13779954946 # 大白话 B 版
|
||||
python3 send_soul_appeal_mail.py 15210897710 # 单封(大白话 A/B)
|
||||
python3 send_soul_appeal_mail.py 13779954946 --suite # 针对「条款引用」连发 4 封不同主题
|
||||
python3 send_soul_appeal_mail.py --all-phones --suite # 152+137 各发 4 封(共 8 封)
|
||||
|
||||
不在终端打印密码。
|
||||
"""
|
||||
@@ -13,11 +15,11 @@ from __future__ import annotations
|
||||
import os
|
||||
import smtplib
|
||||
import sys
|
||||
import time
|
||||
from email.message import EmailMessage
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_ENV = Path(__file__).resolve().parent / "karuo_ai_gateway" / ".env"
|
||||
# Soul 官网公示的官方邮箱,用户要求账号申诉一并抄送
|
||||
TO_LIST = [
|
||||
"soul@soulapp.cn",
|
||||
"hr@soulapp.cn",
|
||||
@@ -25,6 +27,7 @@ TO_LIST = [
|
||||
"commercial-b@soulapp.cn",
|
||||
"pc@soulapp.cn",
|
||||
]
|
||||
DEFAULT_PHONES = ("15210897710", "13779954946")
|
||||
|
||||
|
||||
def load_env_file(path: Path) -> None:
|
||||
@@ -43,7 +46,6 @@ def load_env_file(path: Path) -> None:
|
||||
|
||||
|
||||
def appeal_variant_a(phone: str) -> tuple[str, str]:
|
||||
"""152 绑定号:分条 + 大白话。"""
|
||||
subject = f"求助|Soul账号被限制,求人工复核(手机{phone})"
|
||||
body = f"""Soul 客服您好,
|
||||
|
||||
@@ -65,7 +67,6 @@ def appeal_variant_a(phone: str) -> tuple[str, str]:
|
||||
|
||||
|
||||
def appeal_variant_b(phone: str) -> tuple[str, str]:
|
||||
"""137 绑定号:另一套大白话(叙述流,同目的)。"""
|
||||
subject = f"想申请恢复账号|绑定手机{phone}"
|
||||
body = f"""您好,
|
||||
|
||||
@@ -90,15 +91,120 @@ def pick_variant(phone: str) -> tuple[str, str]:
|
||||
return appeal_variant_b(phone)
|
||||
|
||||
|
||||
def suite_appeals(phone: str) -> list[tuple[str, str]]:
|
||||
"""针对平台短信引用 2.2.3、2.2.4、2.2.5、3.2.11(1-8)、3.2.12 的补充申诉(分封主题,避免一封过长)。"""
|
||||
cite = "2.2.3、2.2.4、2.2.5、3.2.11(1)-(8)、3.2.12"
|
||||
return [
|
||||
(
|
||||
f"【二次申诉】绑定手机{phone}|已收贵司条款引用,恳请书面告知具体违规事实",
|
||||
f"""Soul 客服团队您好,
|
||||
|
||||
我的绑定手机号为 {phone}。此前收到贵司通知,称申诉未通过,并引用《用户协议》{cite} 等条款。
|
||||
|
||||
本人已重新阅读 App 内《用户协议》相关章节,愿意遵守平台规则。但目前仍不清楚:**具体是哪一类行为、哪一条动态/私信/场景**触发了上述条款的适用,导致封号。没有可操作的违规事实说明,我无法完成针对性整改,也难以判断是否存在误判。
|
||||
|
||||
故恳请贵司在合规前提下,通过邮件或站内途径告知:**违规内容类型、大致时间、对应功能场景**(无需泄露他人隐私即可)。本人承诺在知悉后立刻整改,并申请**二次人工复核**。
|
||||
|
||||
回复请发至本邮件发件邮箱,亦可致电我登记号码 {phone}(如可外呼)。
|
||||
|
||||
感谢。
|
||||
|
||||
账号持有人({phone})
|
||||
""",
|
||||
),
|
||||
(
|
||||
f"【分项说明】绑定手机{phone}|关于第2.2.3、2.2.4、2.2.5条之理解与承诺",
|
||||
f"""Soul 客服您好,
|
||||
|
||||
绑定手机 {phone}。现就贵司援引的协议第 2.2.3、2.2.4、2.2.5 条说明如下:
|
||||
|
||||
据公开渠道中用户对 2.2.5 条的转述,该款大意包含:**不得利用账号从事违法活动、捣乱、骚扰、欺骗其他用户及违反协议的行为**。2.2.3、2.2.4 与同节条款通常指向**守法使用账号、维护平台秩序**等义务(**具体以本人 App 内当前版本《用户协议》原文为准**)。
|
||||
|
||||
本人确认:**无故意从事违法、欺诈、恶意骚扰或破坏社区秩序的主观意图**;若曾有言行被系统判定越界,愿在贵司指出具体事实后**立即纠正**,并加强自我约束。
|
||||
|
||||
恳请结合上述说明,对账号是否具备**从轻、整改后恢复**的空间予以复核。
|
||||
|
||||
账号持有人 {phone}
|
||||
""",
|
||||
),
|
||||
(
|
||||
f"【分项说明】绑定手机{phone}|关于第3.2.11条第(1)-(8)项之合规承诺",
|
||||
f"""Soul 客服您好,
|
||||
|
||||
绑定手机 {phone}。贵司通知中援引 3.2.11 条第(1)至(8)项。该类条款在实务中一般对应**禁止发布的多类违规信息**(如违法有害、低俗、人身攻击、虚假误导、侵权、违规营销导流等,**具体子项以 App 内协议原文为准**)。
|
||||
|
||||
本人承诺:
|
||||
• 不在平台发布违反法律法规及《Soul 用户行为规范》的信息;
|
||||
• 不从事恶意营销、刷屏骚扰、诱导站外交易或欺诈等行为;
|
||||
• 对他人与平台保持尊重,不故意散布不实信息。
|
||||
|
||||
若贵司认定本人曾违反上述任一项,请**指明对应项号与事实概要**,本人愿删除相关内容、书面说明情况并申请复核。
|
||||
|
||||
账号持有人 {phone}
|
||||
""",
|
||||
),
|
||||
(
|
||||
f"【分项说明】绑定手机{phone}|关于第3.2.12条及持续合规使用承诺",
|
||||
f"""Soul 客服您好,
|
||||
|
||||
绑定手机 {phone}。就贵司一并援引的第 3.2.12 条,本人理解其通常与 3.2.11 等条款共同构成**内容与安全规范**体系(**以 App 内最新协议为准**)。
|
||||
|
||||
本人承诺后续将:
|
||||
• 发帖、聊天、匹配互动前对照《用户行为规范》自查;
|
||||
• 不参与灰产引流、不当交友诱导、违规广告等行为;
|
||||
• 配合贵司合理的内容管理与身份核验要求。
|
||||
|
||||
鉴于此前申诉未通过,本人仍恳请贵司在本人**已表态整改、愿配合说明**的前提下,考虑是否给予**观察期、限制解除或账号恢复**的机会。
|
||||
|
||||
联系:本邮件发件地址;手机 {phone}。
|
||||
|
||||
账号持有人
|
||||
""",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def send_one(
|
||||
host: str,
|
||||
port: int,
|
||||
user: str,
|
||||
password: str,
|
||||
subject: str,
|
||||
body: str,
|
||||
) -> None:
|
||||
msg = EmailMessage()
|
||||
msg["Subject"] = subject
|
||||
msg["From"] = user
|
||||
msg["To"] = ", ".join(TO_LIST)
|
||||
msg.set_content(body)
|
||||
with smtplib.SMTP_SSL(host, port, timeout=30) as smtp:
|
||||
smtp.login(user, password)
|
||||
smtp.send_message(msg)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
phone = (sys.argv[1] if len(sys.argv) > 1 else "").strip()
|
||||
if not phone:
|
||||
print("用法: python3 send_soul_appeal_mail.py <11位手机号>", file=sys.stderr)
|
||||
print("示例: … 15210897710 或 … 13779954946", file=sys.stderr)
|
||||
return 1
|
||||
if not phone.isdigit() or len(phone) != 11:
|
||||
print("手机号须为 11 位数字", file=sys.stderr)
|
||||
return 1
|
||||
args = [a for a in sys.argv[1:] if not a.startswith("--")]
|
||||
flags = {a for a in sys.argv[1:] if a.startswith("--")}
|
||||
suite = "--suite" in flags
|
||||
all_phones = "--all-phones" in flags
|
||||
|
||||
if all_phones:
|
||||
phones = list(DEFAULT_PHONES)
|
||||
else:
|
||||
phone = (args[0] if args else "").strip()
|
||||
if not phone:
|
||||
print(
|
||||
"用法:\n"
|
||||
" python3 send_soul_appeal_mail.py <11位手机号>\n"
|
||||
" python3 send_soul_appeal_mail.py <手机号> --suite\n"
|
||||
" python3 send_soul_appeal_mail.py --all-phones --suite",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
if not phone.isdigit() or len(phone) != 11:
|
||||
print("手机号须为 11 位数字", file=sys.stderr)
|
||||
return 1
|
||||
phones = [phone]
|
||||
|
||||
env_path = Path(os.environ.get("KARUO_SMTP_ENV", str(DEFAULT_ENV)))
|
||||
load_env_file(env_path)
|
||||
@@ -109,27 +215,29 @@ def main() -> int:
|
||||
port = int(os.environ.get("SMTP_PORT", "465") or "465")
|
||||
|
||||
if not user or not password:
|
||||
print("错误:未从环境或", env_path, "读取到 SMTP_USER / SMTP_PASS", file=sys.stderr)
|
||||
print("错误:未读取到 SMTP_USER / SMTP_PASS", env_path, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
subject, body = pick_variant(phone)
|
||||
|
||||
msg = EmailMessage()
|
||||
msg["Subject"] = subject
|
||||
msg["From"] = user
|
||||
msg["To"] = ", ".join(TO_LIST)
|
||||
msg.set_content(body)
|
||||
|
||||
try:
|
||||
with smtplib.SMTP_SSL(host, port, timeout=30) as smtp:
|
||||
smtp.login(user, password)
|
||||
smtp.send_message(msg)
|
||||
n_sent = 0
|
||||
for phone in phones:
|
||||
if suite:
|
||||
pairs = suite_appeals(phone)
|
||||
else:
|
||||
pairs = [pick_variant(phone)]
|
||||
|
||||
for subject, body in pairs:
|
||||
send_one(host, port, user, password, subject, body)
|
||||
n_sent += 1
|
||||
print("OK", n_sent, subject[:56] + ("…" if len(subject) > 56 else ""))
|
||||
if suite and len(pairs) > 1:
|
||||
time.sleep(3)
|
||||
|
||||
print("共发送", n_sent, "封 →", ", ".join(TO_LIST))
|
||||
except Exception as e:
|
||||
print("发送失败:", type(e).__name__, str(e), file=sys.stderr)
|
||||
return 2
|
||||
|
||||
print("已发送至", len(TO_LIST), "个邮箱:", ", ".join(TO_LIST))
|
||||
print("主题:", subject)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -430,3 +430,4 @@
|
||||
| 2026-03-23 16:22:10 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:金仓、水溪整理归档、卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
|
||||
| 2026-03-23 16:22:19 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
|
||||
| 2026-03-23 16:35:47 | 🔄 卡若AI 同步 2026-03-23 16:35 | 更新:Cursor规则、金仓、卡人、水溪整理归档、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
|
||||
| 2026-03-23 16:37:40 | 🔄 卡若AI 同步 2026-03-23 16:37 | 更新:Cursor规则、金仓、水溪整理归档、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |
|
||||
|
||||
@@ -433,3 +433,4 @@
|
||||
| 2026-03-23 16:22:10 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:金仓、水溪整理归档、卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-23 16:22:19 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:22 | 更新:总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-23 16:35:47 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:35 | 更新:Cursor规则、金仓、卡人、水溪整理归档、火炬、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-03-23 16:37:40 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-23 16:37 | 更新:Cursor规则、金仓、水溪整理归档、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
|
||||
@@ -123,4 +123,16 @@
|
||||
|
||||
---
|
||||
|
||||
## 十、卡若 AI 网站(官网)对接阿猫 OpenClaw 网关
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| **环境变量** | \`开发/3、自营项目/卡若ai网站/site/.env.local\` 已配置 \`OPENCLAW_GATEWAY_URL\`(默认 \`http://macbook.quwanzhi.com:18789\`)、\`OPENCLAW_GATEWAY_TOKEN\`(与阿猫 \`~/.openclaw/openclaw.json\` 中 \`gateway.auth.token\` 一致)、\`OPENCLAW_GATEWAY_MODEL\` 等。 |
|
||||
| **Mongo** | \`storage-mongo\` 在初始化网关后会 **upsert** \`gw-openclaw-amiao\`(展示名:OpenClaw·阿猫笔记本(龙虾))。 |
|
||||
| **路由** | 官网 \`gateway-router\` 对 \`claude*\` 模型在有该网关 Key 时 **优先** 走阿猫 OpenClaw。 |
|
||||
| **Docker** | \`卡若ai网站/docker-compose.yml\` 已传入上述变量;生产环境须保证 **容器能访问** 阿猫网关地址(非把阿猫的 127.0.0.1 当本机)。 |
|
||||
| **控制台** | 管理员 POST \`/api/gateway/sync-keys\` 时也会从环境变量合并 \`gw-openclaw-amiao\`。 |
|
||||
|
||||
---
|
||||
|
||||
*文档生成:卡若AI 工作台。*
|
||||
|
||||
Reference in New Issue
Block a user