mirror of
https://fastgit.cc/github.com/hicccc77/WeFlow
synced 2026-04-20 12:51:02 +08:00
Merge pull request #26 from Jasonzhu1207/fix/insight-social-context-runtime-and-cookie-optional
fix: no-cookie Weibo context + social prompt copy refinements
This commit is contained in:
@@ -809,7 +809,7 @@ ${topMentionText}
|
||||
if (!allowSocialContext) return ''
|
||||
|
||||
const rawCookie = String(this.config.get('aiInsightWeiboCookie') || '').trim()
|
||||
if (!rawCookie) return ''
|
||||
const hasCookie = rawCookie.length > 0
|
||||
|
||||
const bindings =
|
||||
(this.config.get('aiInsightWeiboBindings') as Record<string, { uid?: string; screenName?: string }> | undefined) || {}
|
||||
@@ -830,7 +830,10 @@ ${topMentionText}
|
||||
return `[微博 ${time}] ${text}`
|
||||
})
|
||||
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) {
|
||||
insightLog('WARN', `拉取微博公开内容失败 (uid=${uid}): ${(error as Error).message}`)
|
||||
return ''
|
||||
|
||||
@@ -7,6 +7,8 @@ const WEIBO_MAX_POSTS = 5
|
||||
const WEIBO_CACHE_TTL_MS = 30 * 60 * 1000
|
||||
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'
|
||||
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 {
|
||||
domain?: string
|
||||
@@ -48,6 +50,18 @@ interface WeiboStatusShowResponse {
|
||||
retweeted_status?: WeiboWaterFallItem
|
||||
}
|
||||
|
||||
interface MWeiboCard {
|
||||
mblog?: WeiboWaterFallItem
|
||||
card_group?: MWeiboCard[]
|
||||
}
|
||||
|
||||
interface MWeiboContainerResponse {
|
||||
ok?: number
|
||||
data?: {
|
||||
cards?: MWeiboCard[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface WeiboRecentPost {
|
||||
id: string
|
||||
createdAt: string
|
||||
@@ -61,7 +75,7 @@ interface CachedRecentPosts {
|
||||
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) => {
|
||||
let urlObj: URL
|
||||
try {
|
||||
@@ -71,19 +85,23 @@ function requestJson<T>(url: string, options: { cookie: string; referer?: string
|
||||
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(
|
||||
{
|
||||
hostname: urlObj.hostname,
|
||||
port: urlObj.port || 443,
|
||||
path: urlObj.pathname + urlObj.search,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
Referer: options.referer || 'https://weibo.com',
|
||||
'User-Agent': WEIBO_USER_AGENT,
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
Cookie: options.cookie
|
||||
}
|
||||
headers
|
||||
},
|
||||
(res) => {
|
||||
let raw = ''
|
||||
@@ -232,10 +250,10 @@ class WeiboService {
|
||||
): Promise<WeiboRecentPost[]> {
|
||||
const uid = normalizeWeiboUid(uidInput)
|
||||
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 cacheKey = buildCacheKey(uid, count, cookie)
|
||||
const cacheKey = buildCacheKey(uid, count, hasCookie ? cookie : '__no_cookie_mobile__')
|
||||
const cached = this.recentPostsCache.get(cacheKey)
|
||||
const now = Date.now()
|
||||
|
||||
@@ -243,8 +261,9 @@ class WeiboService {
|
||||
return cached.posts
|
||||
}
|
||||
|
||||
const timeline = await this.fetchTimeline(uid, cookie)
|
||||
const rawItems = Array.isArray(timeline.data?.list) ? timeline.data.list : []
|
||||
const rawItems = hasCookie
|
||||
? (await this.fetchTimeline(uid, cookie)).data?.list || []
|
||||
: await this.fetchMobileTimeline(uid)
|
||||
const posts: WeiboRecentPost[] = []
|
||||
|
||||
for (const item of rawItems) {
|
||||
@@ -254,7 +273,7 @@ class WeiboService {
|
||||
if (!id) continue
|
||||
|
||||
let text = mergeRetweetText(item)
|
||||
if (item.isLongText) {
|
||||
if (item.isLongText && hasCookie) {
|
||||
try {
|
||||
const detail = await this.fetchDetail(id, cookie)
|
||||
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> {
|
||||
return requestJson<WeiboStatusShowResponse>(
|
||||
`https://weibo.com/ajax/statuses/show?id=${encodeURIComponent(id)}&isGetLongText=true`,
|
||||
|
||||
@@ -3220,7 +3220,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
</div>
|
||||
{!hasWeiboCookieConfigured && (
|
||||
<span className="form-hint" style={{ marginTop: 8, display: 'block' }}>
|
||||
未配置微博 Cookie 时,开启后也不会发送社交平台内容。
|
||||
未配置微博 Cookie 时,也会尝试抓取微博公开内容;但可能因平台风控导致获取失败或内容较少。
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -4625,7 +4625,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
清空
|
||||
</button>
|
||||
<button className="btn btn-primary" onClick={() => { void handleCloseWeiboCookieModal() }} disabled={isSavingWeiboCookie}>
|
||||
{isSavingWeiboCookie ? '保存中...' : '关闭'}
|
||||
{isSavingWeiboCookie ? '保存中...' : '关闭并保存'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user