mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-04-22 15:09:04 +00:00
fix: allow no-cookie weibo context and adjust insight copy
This commit is contained in:
@@ -809,7 +809,7 @@ ${topMentionText}
|
|||||||
if (!allowSocialContext) return ''
|
if (!allowSocialContext) return ''
|
||||||
|
|
||||||
const rawCookie = String(this.config.get('aiInsightWeiboCookie') || '').trim()
|
const rawCookie = String(this.config.get('aiInsightWeiboCookie') || '').trim()
|
||||||
if (!rawCookie) return ''
|
const hasCookie = rawCookie.length > 0
|
||||||
|
|
||||||
const bindings =
|
const bindings =
|
||||||
(this.config.get('aiInsightWeiboBindings') as Record<string, { uid?: string; screenName?: string }> | undefined) || {}
|
(this.config.get('aiInsightWeiboBindings') as Record<string, { uid?: string; screenName?: string }> | undefined) || {}
|
||||||
@@ -830,7 +830,10 @@ ${topMentionText}
|
|||||||
return `[微博 ${time}] ${text}`
|
return `[微博 ${time}] ${text}`
|
||||||
})
|
})
|
||||||
insightLog('INFO', `已加载 ${lines.length} 条微博公开内容 (uid=${uid})`)
|
insightLog('INFO', `已加载 ${lines.length} 条微博公开内容 (uid=${uid})`)
|
||||||
return `近期公开社交平台内容(实验性,来源:微博,最近 ${lines.length} 条):\n${lines.join('\n')}`
|
const riskHint = hasCookie
|
||||||
|
? ''
|
||||||
|
: '\n提示:未配置微博 Cookie,使用移动端公开接口抓取,可能因平台风控导致获取失败或内容较少。'
|
||||||
|
return `近期公开社交平台内容(来源:微博,最近 ${lines.length} 条):\n${lines.join('\n')}${riskHint}`
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
insightLog('WARN', `拉取微博公开内容失败 (uid=${uid}): ${(error as Error).message}`)
|
insightLog('WARN', `拉取微博公开内容失败 (uid=${uid}): ${(error as Error).message}`)
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const WEIBO_MAX_POSTS = 5
|
|||||||
const WEIBO_CACHE_TTL_MS = 30 * 60 * 1000
|
const WEIBO_CACHE_TTL_MS = 30 * 60 * 1000
|
||||||
const WEIBO_USER_AGENT =
|
const WEIBO_USER_AGENT =
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36'
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36'
|
||||||
|
const WEIBO_MOBILE_USER_AGENT =
|
||||||
|
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1'
|
||||||
|
|
||||||
interface BrowserCookieEntry {
|
interface BrowserCookieEntry {
|
||||||
domain?: string
|
domain?: string
|
||||||
@@ -48,6 +50,18 @@ interface WeiboStatusShowResponse {
|
|||||||
retweeted_status?: WeiboWaterFallItem
|
retweeted_status?: WeiboWaterFallItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MWeiboCard {
|
||||||
|
mblog?: WeiboWaterFallItem
|
||||||
|
card_group?: MWeiboCard[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MWeiboContainerResponse {
|
||||||
|
ok?: number
|
||||||
|
data?: {
|
||||||
|
cards?: MWeiboCard[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface WeiboRecentPost {
|
export interface WeiboRecentPost {
|
||||||
id: string
|
id: string
|
||||||
createdAt: string
|
createdAt: string
|
||||||
@@ -61,7 +75,7 @@ interface CachedRecentPosts {
|
|||||||
posts: WeiboRecentPost[]
|
posts: WeiboRecentPost[]
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestJson<T>(url: string, options: { cookie: string; referer?: string }): Promise<T> {
|
function requestJson<T>(url: string, options: { cookie?: string; referer?: string; userAgent?: string }): Promise<T> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let urlObj: URL
|
let urlObj: URL
|
||||||
try {
|
try {
|
||||||
@@ -71,19 +85,23 @@ function requestJson<T>(url: string, options: { cookie: string; referer?: string
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
Accept: 'application/json, text/plain, */*',
|
||||||
|
Referer: options.referer || 'https://weibo.com',
|
||||||
|
'User-Agent': options.userAgent || WEIBO_USER_AGENT,
|
||||||
|
'X-Requested-With': 'XMLHttpRequest'
|
||||||
|
}
|
||||||
|
if (options.cookie) {
|
||||||
|
headers.Cookie = options.cookie
|
||||||
|
}
|
||||||
|
|
||||||
const req = https.request(
|
const req = https.request(
|
||||||
{
|
{
|
||||||
hostname: urlObj.hostname,
|
hostname: urlObj.hostname,
|
||||||
port: urlObj.port || 443,
|
port: urlObj.port || 443,
|
||||||
path: urlObj.pathname + urlObj.search,
|
path: urlObj.pathname + urlObj.search,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers
|
||||||
Accept: 'application/json, text/plain, */*',
|
|
||||||
Referer: options.referer || 'https://weibo.com',
|
|
||||||
'User-Agent': WEIBO_USER_AGENT,
|
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
|
||||||
Cookie: options.cookie
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
(res) => {
|
(res) => {
|
||||||
let raw = ''
|
let raw = ''
|
||||||
@@ -232,10 +250,10 @@ class WeiboService {
|
|||||||
): Promise<WeiboRecentPost[]> {
|
): Promise<WeiboRecentPost[]> {
|
||||||
const uid = normalizeWeiboUid(uidInput)
|
const uid = normalizeWeiboUid(uidInput)
|
||||||
const cookie = normalizeWeiboCookieInput(cookieInput)
|
const cookie = normalizeWeiboCookieInput(cookieInput)
|
||||||
if (!cookie) return []
|
const hasCookie = Boolean(cookie)
|
||||||
|
|
||||||
const count = Math.max(1, Math.min(WEIBO_MAX_POSTS, Math.floor(Number(requestedCount) || 0)))
|
const count = Math.max(1, Math.min(WEIBO_MAX_POSTS, Math.floor(Number(requestedCount) || 0)))
|
||||||
const cacheKey = buildCacheKey(uid, count, cookie)
|
const cacheKey = buildCacheKey(uid, count, hasCookie ? cookie : '__no_cookie_mobile__')
|
||||||
const cached = this.recentPostsCache.get(cacheKey)
|
const cached = this.recentPostsCache.get(cacheKey)
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
|
||||||
@@ -243,8 +261,9 @@ class WeiboService {
|
|||||||
return cached.posts
|
return cached.posts
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeline = await this.fetchTimeline(uid, cookie)
|
const rawItems = hasCookie
|
||||||
const rawItems = Array.isArray(timeline.data?.list) ? timeline.data.list : []
|
? (await this.fetchTimeline(uid, cookie)).data?.list || []
|
||||||
|
: await this.fetchMobileTimeline(uid)
|
||||||
const posts: WeiboRecentPost[] = []
|
const posts: WeiboRecentPost[] = []
|
||||||
|
|
||||||
for (const item of rawItems) {
|
for (const item of rawItems) {
|
||||||
@@ -254,7 +273,7 @@ class WeiboService {
|
|||||||
if (!id) continue
|
if (!id) continue
|
||||||
|
|
||||||
let text = mergeRetweetText(item)
|
let text = mergeRetweetText(item)
|
||||||
if (item.isLongText) {
|
if (item.isLongText && hasCookie) {
|
||||||
try {
|
try {
|
||||||
const detail = await this.fetchDetail(id, cookie)
|
const detail = await this.fetchDetail(id, cookie)
|
||||||
text = mergeRetweetText(detail)
|
text = mergeRetweetText(detail)
|
||||||
@@ -298,6 +317,37 @@ class WeiboService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fetchMobileTimeline(uid: string): Promise<WeiboWaterFallItem[]> {
|
||||||
|
const containerid = `107603${uid}`
|
||||||
|
return requestJson<MWeiboContainerResponse>(
|
||||||
|
`https://m.weibo.cn/api/container/getIndex?type=uid&value=${encodeURIComponent(uid)}&containerid=${encodeURIComponent(containerid)}`,
|
||||||
|
{
|
||||||
|
referer: `https://m.weibo.cn/u/${encodeURIComponent(uid)}`,
|
||||||
|
userAgent: WEIBO_MOBILE_USER_AGENT
|
||||||
|
}
|
||||||
|
).then((response) => {
|
||||||
|
if (response.ok !== 1 || !Array.isArray(response.data?.cards)) {
|
||||||
|
throw new Error('微博时间线获取失败,请稍后重试')
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows: WeiboWaterFallItem[] = []
|
||||||
|
for (const card of response.data.cards) {
|
||||||
|
if (card?.mblog) rows.push(card.mblog)
|
||||||
|
if (Array.isArray(card?.card_group)) {
|
||||||
|
for (const subCard of card.card_group) {
|
||||||
|
if (subCard?.mblog) rows.push(subCard.mblog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.length === 0) {
|
||||||
|
throw new Error('该微博账号暂无可读取的近期公开内容')
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fetchDetail(id: string, cookie: string): Promise<WeiboStatusShowResponse> {
|
private fetchDetail(id: string, cookie: string): Promise<WeiboStatusShowResponse> {
|
||||||
return requestJson<WeiboStatusShowResponse>(
|
return requestJson<WeiboStatusShowResponse>(
|
||||||
`https://weibo.com/ajax/statuses/show?id=${encodeURIComponent(id)}&isGetLongText=true`,
|
`https://weibo.com/ajax/statuses/show?id=${encodeURIComponent(id)}&isGetLongText=true`,
|
||||||
|
|||||||
@@ -3220,7 +3220,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
|||||||
</div>
|
</div>
|
||||||
{!hasWeiboCookieConfigured && (
|
{!hasWeiboCookieConfigured && (
|
||||||
<span className="form-hint" style={{ marginTop: 8, display: 'block' }}>
|
<span className="form-hint" style={{ marginTop: 8, display: 'block' }}>
|
||||||
未配置微博 Cookie 时,开启后也不会发送社交平台内容。
|
未配置微博 Cookie 时,也会尝试抓取微博公开内容;但可能因平台风控导致获取失败或内容较少。
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -4625,7 +4625,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
|||||||
清空
|
清空
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-primary" onClick={() => { void handleCloseWeiboCookieModal() }} disabled={isSavingWeiboCookie}>
|
<button className="btn btn-primary" onClick={() => { void handleCloseWeiboCookieModal() }} disabled={isSavingWeiboCookie}>
|
||||||
{isSavingWeiboCookie ? '保存中...' : '关闭'}
|
{isSavingWeiboCookie ? '保存中...' : '关闭并保存'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user