feat: aliyun platform sync (#89)

This commit is contained in:
Neo
2026-01-11 11:55:34 +08:00
committed by GitHub
parent 03e995ec91
commit b9d3672f6f
6 changed files with 162 additions and 1 deletions
+1
View File
@@ -56,6 +56,7 @@ _**C**reate **O**nce **S**ync **E**verywhere_
- 搜狐号
- B站专栏
- 微博文章
- 阿里云社区
更多想要添加的平台欢迎提 [Issue](https://github.com/doocs/cose/issues)
+2 -1
View File
@@ -36,7 +36,8 @@
"https://*.163.com/*",
"https://*.cloud.tencent.com/*",
"https://*.medium.com/*",
"https://*.sohu.com/*"
"https://*.sohu.com/*",
"https://*.aliyun.com/*"
],
"action": {
"default_icon": {
+94
View File
@@ -407,6 +407,45 @@ async function checkLoginByCookie(platformId, config) {
}
}
// 阿里云开发者社区特殊处理:通过 API 获取用户信息
if (platformId === 'aliyun') {
try {
// 检查 login_aliyunid_ticket cookie 判断是否登录
const ticketCookie = await chrome.cookies.get({
url: 'https://developer.aliyun.com',
name: 'login_aliyunid_ticket'
})
if (!ticketCookie || !ticketCookie.value) {
console.log(`[COSE] ${platformId} 未找到 login_aliyunid_ticket cookie,未登录`)
return { loggedIn: false }
}
// 调用 API 获取用户信息
const response = await fetch('https://developer.aliyun.com/developer/api/my/user/getUser', {
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json',
}
})
const data = await response.json()
if (data.success && data.data?.nickname) {
const username = data.data.nickname
const avatar = data.data.avatar || ''
console.log(`[COSE] ${platformId} 用户信息:`, username, avatar ? '有头像' : '无头像')
return { loggedIn: true, username, avatar }
} else {
console.log(`[COSE] ${platformId} API 返回未登录状态`)
return { loggedIn: false }
}
} catch (e) {
console.log(`[COSE] ${platformId} 获取用户信息失败:`, e.message)
return { loggedIn: false }
}
}
// 少数派特殊处理:通过 /api/v1/user/info/get API 获取用户信息
// 需要从 cookie 中读取 JWT token 并添加到 Authorization header
if (platformId === 'sspai') {
@@ -1346,6 +1385,61 @@ async function syncToPlatform(platformId, content) {
return { success: true, message: '已同步到微博头条', tabId: tab.id }
}
// 阿里云开发者社区:使用 Markdown 编辑器
if (platformId === 'aliyun') {
// 等待页面完全加载
await new Promise(resolve => setTimeout(resolve, 3000))
// 阿里云使用 Markdown 编辑器
const markdownContent = content.markdown || content.body || ''
console.log('[COSE] 阿里云开发者社区 Markdown 内容长度:', markdownContent?.length || 0)
// 填充标题和内容
const fillResult = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: (title, markdown) => {
// 填充标题
const titleInput = document.querySelector('input[placeholder*="标题"]')
if (titleInput && title) {
titleInput.focus()
// 使用 native setter 来绕过 React 的受控组件
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set
nativeSetter.call(titleInput, title)
titleInput.dispatchEvent(new Event('input', { bubbles: true }))
titleInput.dispatchEvent(new Event('change', { bubbles: true }))
console.log('[COSE] 阿里云开发者社区标题填充成功')
}
// 填充内容 - 阿里云使用 textarea 作为 Markdown 编辑器
const contentTextarea = document.querySelector('textarea[class*="editor"]') ||
document.querySelector('.markdown-editor textarea') ||
document.querySelector('textarea:not([placeholder*="标题"])')
if (contentTextarea && markdown) {
contentTextarea.focus()
// 使用 native setter 来绕过 React 的受控组件
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set
nativeSetter.call(contentTextarea, markdown)
contentTextarea.dispatchEvent(new Event('input', { bubbles: true }))
contentTextarea.dispatchEvent(new Event('change', { bubbles: true }))
console.log('[COSE] 阿里云开发者社区内容填充成功')
return { success: true }
}
return { success: false, error: 'Editor not found' }
},
args: [content.title, markdownContent],
world: 'MAIN',
})
console.log('[COSE] 阿里云开发者社区填充结果:', fillResult)
// 等待内容注入完成
await new Promise(resolve => setTimeout(resolve, 1000))
return { success: true, message: '已同步到阿里云开发者社区', tabId: tab.id }
}
// 百家号:使用剪贴板 HTML 粘贴到编辑器
if (platformId === 'baijiahao') {
// 等待页面完全加载
+1
View File
@@ -82,6 +82,7 @@
{ id: 'sohu', name: 'Sohu', icon: 'https://www.google.com/s2/favicons?domain=sohu.com&sz=32', title: '搜狐号', type: 'sohu', url: 'https://mp.sohu.com' },
{ id: 'bilibili', name: 'Bilibili', icon: 'https://www.bilibili.com/favicon.ico', title: 'B站专栏', type: 'bilibili', url: 'https://member.bilibili.com/article-text/home?newEditor=-1' },
{ id: 'weibo', name: 'Weibo', icon: 'https://weibo.com/favicon.ico', title: '微博头条', type: 'weibo', url: 'https://card.weibo.com/article/v5/editor#/draft' },
{ id: 'aliyun', name: 'Aliyun', icon: 'https://img.alicdn.com/tfs/TB1_ZXuNcfpK1RjSZFOXXa6nFXa-32-32.ico', title: '阿里云开发者社区', type: 'aliyun', url: 'https://developer.aliyun.com/article/new#/' },
]
// 暴露 $cose 全局对象
+60
View File
@@ -0,0 +1,60 @@
// 阿里云开发者社区平台配置
const AliyunPlatform = {
id: 'aliyun',
name: 'Aliyun',
icon: 'https://img.alicdn.com/tfs/TB1_ZXuNcfpK1RjSZFOXXa6nFXa-32-32.ico',
url: 'https://developer.aliyun.com/',
publishUrl: 'https://developer.aliyun.com/article/new#/',
title: '阿里云开发者社区',
type: 'aliyun',
}
// 阿里云开发者社区登录检测配置
const AliyunLoginConfig = {
useCookie: true,
cookieUrl: 'https://developer.aliyun.com',
cookieNames: ['login_aliyunid_ticket', 'login_aliyunid_csrf'],
// 通过 API 获取用户信息
}
// 阿里云开发者社区内容填充函数
async function fillAliyunContent(content) {
const { title, markdown } = content
console.log('[COSE] 阿里云开发者社区:开始填充内容')
// 等待页面加载
await new Promise(resolve => setTimeout(resolve, 2000))
// 填充标题
const titleInput = document.querySelector('input[placeholder*="标题"]')
if (titleInput && title) {
titleInput.focus()
titleInput.value = title
titleInput.dispatchEvent(new Event('input', { bubbles: true }))
titleInput.dispatchEvent(new Event('change', { bubbles: true }))
console.log('[COSE] 阿里云开发者社区:标题已填充')
}
// 等待一下再填充正文
await new Promise(resolve => setTimeout(resolve, 500))
// 填充正文(markdown 编辑器)
// 阿里云开发者社区使用的是 markdown 编辑器,textarea 是主要输入区域
const contentTextarea = document.querySelector('textarea[class*="editor"]') ||
document.querySelector('.markdown-editor textarea') ||
document.querySelector('textarea')
if (contentTextarea && markdown) {
contentTextarea.focus()
contentTextarea.value = markdown
contentTextarea.dispatchEvent(new Event('input', { bubbles: true }))
contentTextarea.dispatchEvent(new Event('change', { bubbles: true }))
console.log('[COSE] 阿里云开发者社区:正文已填充')
}
console.log('[COSE] 阿里云开发者社区:内容填充完成')
}
// 导出
export { AliyunPlatform, AliyunLoginConfig, fillAliyunContent }
+4
View File
@@ -18,6 +18,7 @@ import { SspaiPlatform, SspaiLoginConfig } from './sspai.js'
import { SohuPlatform, SohuLoginConfig } from './sohu.js'
import { BilibiliPlatform, BilibiliLoginConfig } from './bilibili.js'
import { WeiboPlatform, WeiboLoginConfig } from './weibo.js'
import { AliyunPlatform, AliyunLoginConfig } from './aliyun.js'
// 合并平台配置
const PLATFORMS = [
@@ -40,6 +41,7 @@ const PLATFORMS = [
SohuPlatform,
BilibiliPlatform,
WeiboPlatform,
AliyunPlatform,
]
// 合并登录检测配置
@@ -63,6 +65,7 @@ const LOGIN_CHECK_CONFIG = {
[SohuPlatform.id]: SohuLoginConfig,
[BilibiliPlatform.id]: BilibiliLoginConfig,
[WeiboPlatform.id]: WeiboLoginConfig,
[AliyunPlatform.id]: AliyunLoginConfig,
}
// 根据 hostname 获取平台填充函数
@@ -86,6 +89,7 @@ function getPlatformFiller(hostname) {
if (hostname.includes('mp.sohu.com')) return 'sohu'
if (hostname.includes('member.bilibili.com')) return 'bilibili'
if (hostname.includes('card.weibo.com')) return 'weibo'
if (hostname.includes('developer.aliyun.com')) return 'aliyun'
return 'generic'
}