@lightcone-ai/daemon 0.9.55 → 0.9.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -35,11 +35,11 @@ export class XhsAdapter {
|
|
|
35
35
|
async checkLoginStatus() {
|
|
36
36
|
const profileDir = process.env.XHS_PROFILE_DIR ?? '(not set)';
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// Navigate to www to establish session context and check __INITIAL_STATE__
|
|
39
|
+
// Do NOT navigate to creator here — the 401 redirect can clear cookies
|
|
39
40
|
await this._cdp.send('Page.navigate', { url: 'https://www.xiaohongshu.com' });
|
|
40
41
|
await sleep(4000);
|
|
41
42
|
|
|
42
|
-
// Step 2: check login via window.__INITIAL_STATE__ (auto-agent approach — more reliable than URL check)
|
|
43
43
|
const stateResult = await this._cdp.send('Runtime.evaluate', {
|
|
44
44
|
expression: `(function() {
|
|
45
45
|
try {
|
|
@@ -56,30 +56,22 @@ export class XhsAdapter {
|
|
|
56
56
|
let stateData = {};
|
|
57
57
|
try { stateData = JSON.parse(stateStr); } catch {}
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
console.error(`[XhsAdapter]
|
|
61
|
-
|
|
62
|
-
// Step 3: if logged in via state, also verify creator access
|
|
63
|
-
let creatorUrl = '';
|
|
64
|
-
if (loggedInViaState) {
|
|
65
|
-
await this._cdp.send('Page.navigate', { url: 'https://creator.xiaohongshu.com/publish/publish' });
|
|
66
|
-
await sleep(5000);
|
|
67
|
-
const urlResult = await this._cdp.send('Runtime.evaluate', { expression: 'window.location.href', returnByValue: true });
|
|
68
|
-
creatorUrl = urlResult.result?.value ?? '';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const loggedIn = loggedInViaState;
|
|
72
|
-
const url = creatorUrl || 'www check only';
|
|
73
|
-
console.error(`[XhsAdapter] checkLoginStatus: loggedIn=${loggedIn} creatorUrl=${creatorUrl} profileDir=${profileDir}`);
|
|
74
|
-
return { loggedIn, url, profileDir, userId: stateData.userId, nickname: stateData.nickname };
|
|
59
|
+
const loggedIn = !!(stateData.userId || stateData.nickname);
|
|
60
|
+
console.error(`[XhsAdapter] checkLoginStatus: loggedIn=${loggedIn} state=${stateStr}`);
|
|
61
|
+
return { loggedIn, url: 'www.xiaohongshu.com', profileDir, userId: stateData.userId, nickname: stateData.nickname };
|
|
75
62
|
}
|
|
76
63
|
|
|
77
64
|
async publishImageText({ title, text, tags = [], images = [] }) {
|
|
78
65
|
const cdp = this._cdp;
|
|
79
66
|
|
|
67
|
+
// Warm up session on www first — ensures session context is established
|
|
68
|
+
// before accessing creator subdomain (same flow as a real browser user)
|
|
69
|
+
await cdp.send('Page.navigate', { url: 'https://www.xiaohongshu.com' });
|
|
70
|
+
await sleep(3000);
|
|
71
|
+
|
|
80
72
|
// Navigate to publish page
|
|
81
73
|
await cdp.send('Page.navigate', { url: 'https://creator.xiaohongshu.com/publish/publish' });
|
|
82
|
-
await sleep(
|
|
74
|
+
await sleep(4000);
|
|
83
75
|
|
|
84
76
|
// Check if we got redirected away (login expired)
|
|
85
77
|
const urlAfterNav = await this._getUrl();
|
|
@@ -146,9 +138,12 @@ export class XhsAdapter {
|
|
|
146
138
|
async publishShortVideo({ title, text, tags = [], video, cover }) {
|
|
147
139
|
const cdp = this._cdp;
|
|
148
140
|
|
|
149
|
-
await cdp.send('Page.navigate', { url: 'https://
|
|
141
|
+
await cdp.send('Page.navigate', { url: 'https://www.xiaohongshu.com' });
|
|
150
142
|
await sleep(3000);
|
|
151
143
|
|
|
144
|
+
await cdp.send('Page.navigate', { url: 'https://creator.xiaohongshu.com/publish/publish?source=video' });
|
|
145
|
+
await sleep(4000);
|
|
146
|
+
|
|
152
147
|
const urlAfterNav = await this._getUrl();
|
|
153
148
|
if (!urlAfterNav.includes('creator.xiaohongshu.com/publish/publish')) {
|
|
154
149
|
throw new Error(`LOGIN_EXPIRED: 跳转到了 ${urlAfterNav},请重新扫码连接小红书`);
|
package/package.json
CHANGED
package/src/browser-login.js
CHANGED
|
@@ -256,9 +256,16 @@ export class BrowserLoginSession {
|
|
|
256
256
|
// Export decrypted cookies to cookies.json so chrome-pool can inject them
|
|
257
257
|
// without relying on platform-specific keychain encryption (fixes macOS cross-process issue)
|
|
258
258
|
try {
|
|
259
|
+
// For XHS: also visit creator subdomain so it sets its own session tokens
|
|
260
|
+
// before we snapshot cookies — otherwise creator.xiaohongshu.com rejects the session
|
|
261
|
+
if (this._platform === 'xhs') {
|
|
262
|
+
await this.send('Page.navigate', { url: 'https://creator.xiaohongshu.com' });
|
|
263
|
+
await sleep(4000);
|
|
264
|
+
}
|
|
259
265
|
const cookieResult = await this.send('Network.getAllCookies', {});
|
|
266
|
+
const baseDomain = new URL(this._config.loginUrl).hostname.split('.').slice(-2).join('.');
|
|
260
267
|
const cookies = (cookieResult.cookies ?? []).filter(c =>
|
|
261
|
-
c.domain.includes(
|
|
268
|
+
c.domain.includes(baseDomain)
|
|
262
269
|
);
|
|
263
270
|
writeFileSync(path.join(this._profileDir, 'cookies.json'), JSON.stringify(cookies));
|
|
264
271
|
console.log(`[BrowserLogin][${this._platform}] Saved ${cookies.length} cookies to cookies.json`);
|