From b11aec93c5d47fb0d5b77d1f4dd5f07395808f76 Mon Sep 17 00:00:00 2001 From: arch3rPro <30855883+arch3rPro@users.noreply.github.com> Date: Sat, 26 Jul 2025 23:51:38 +0800 Subject: [PATCH] feat: add app WeWe-RSS --- README.md | 25 +++++- apps/wewe-rss/2.6.1-sqlite/.env.sample | 9 +++ apps/wewe-rss/2.6.1-sqlite/data.yml | 62 +++++++++++++++ apps/wewe-rss/2.6.1-sqlite/docker-compose.yml | 24 ++++++ apps/wewe-rss/2.6.1/.env.sample | 14 ++++ apps/wewe-rss/2.6.1/data.yml | 64 +++++++++++++++ apps/wewe-rss/2.6.1/docker-compose.yml | 45 +++++++++++ apps/wewe-rss/README.md | 73 ++++++++++++++++++ apps/wewe-rss/data.yml | 26 +++++++ apps/wewe-rss/latest/.env.sample | 14 ++++ apps/wewe-rss/latest/data.yml | 64 +++++++++++++++ apps/wewe-rss/latest/docker-compose.yml | 45 +++++++++++ apps/wewe-rss/logo.png | Bin 0 -> 3646 bytes 13 files changed, 464 insertions(+), 1 deletion(-) create mode 100644 apps/wewe-rss/2.6.1-sqlite/.env.sample create mode 100644 apps/wewe-rss/2.6.1-sqlite/data.yml create mode 100644 apps/wewe-rss/2.6.1-sqlite/docker-compose.yml create mode 100644 apps/wewe-rss/2.6.1/.env.sample create mode 100644 apps/wewe-rss/2.6.1/data.yml create mode 100644 apps/wewe-rss/2.6.1/docker-compose.yml create mode 100644 apps/wewe-rss/README.md create mode 100644 apps/wewe-rss/data.yml create mode 100644 apps/wewe-rss/latest/.env.sample create mode 100644 apps/wewe-rss/latest/data.yml create mode 100644 apps/wewe-rss/latest/docker-compose.yml create mode 100644 apps/wewe-rss/logo.png diff --git a/README.md b/README.md index b0e77be..6549c6d 100644 --- a/README.md +++ b/README.md @@ -287,6 +287,29 @@ AI驱动的开源代码知识库与文档协作平台,支持多模型、多数 + + + + + + +
+ + +WeWe RSS +
WeWe RSS +
+ +更优雅的微信公众号订阅方式,支持RSS输出和全文内容 + +2.6.1 • [官网链接](https://github.com/cooderl/wewe-rss) + +
+ + + +
+ #### 🔒 安全与网络工具 @@ -416,7 +439,7 @@ AI驱动的开源代码知识库与文档协作平台,支持多模型、多数
-
+ New-API diff --git a/apps/wewe-rss/2.6.1-sqlite/.env.sample b/apps/wewe-rss/2.6.1-sqlite/.env.sample new file mode 100644 index 0000000..54b5a84 --- /dev/null +++ b/apps/wewe-rss/2.6.1-sqlite/.env.sample @@ -0,0 +1,9 @@ +AUTH_CODE="password" +CONTAINER_NAME="wewe-rss" +CRON_EXPRESSION="35 5,17 * * *" +DATABASE_TYPE="sqlite" +DATA_PATH="./data" +FEED_MODE="fulltext" +MAX_REQUEST_PER_MINUTE=60 +PANEL_APP_PORT_HTTP=40332 +SERVER_ORIGIN_URL="http://1.2.3.4:40332" diff --git a/apps/wewe-rss/2.6.1-sqlite/data.yml b/apps/wewe-rss/2.6.1-sqlite/data.yml new file mode 100644 index 0000000..7b58cc3 --- /dev/null +++ b/apps/wewe-rss/2.6.1-sqlite/data.yml @@ -0,0 +1,62 @@ +additionalProperties: + formFields: + - default: "40332" + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "./data" + edit: true + envKey: DATA_PATH + labelEn: Data Path + labelZh: 数据路径 + required: true + type: text + - default: "sqlite" + disabled: true + envKey: DATABASE_TYPE + labelEn: Database Type + labelZh: 数据库类型 + required: true + type: text + - default: "password" + edit: true + envKey: AUTH_CODE + labelEn: Auth Code + labelZh: 授权码 + random: true + required: true + rule: paramComplexity + type: password + - default: "http://1.2.3.4:40332" + edit: true + envKey: SERVER_ORIGIN_URL + labelEn: External URL + labelZh: 外部访问地址 + required: true + rule: paramExtUrl + type: text + - default: "fulltext" + edit: true + envKey: FEED_MODE + labelEn: Feed Mode + labelZh: 提取模式 + required: false + type: text + - default: "35 5,17 * * *" + edit: true + envKey: CRON_EXPRESSION + labelEn: Cron Expression + labelZh: 定时更新表达式 + required: false + type: text + - default: "60" + edit: true + envKey: MAX_REQUEST_PER_MINUTE + labelEn: Max Requests Per Minute + labelZh: 每分钟最大请求次数 + required: false + type: number diff --git a/apps/wewe-rss/2.6.1-sqlite/docker-compose.yml b/apps/wewe-rss/2.6.1-sqlite/docker-compose.yml new file mode 100644 index 0000000..c0490f9 --- /dev/null +++ b/apps/wewe-rss/2.6.1-sqlite/docker-compose.yml @@ -0,0 +1,24 @@ +services: + wewe-rss: + image: "cooderl/wewe-rss-sqlite:v2.6.1" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:4000" + environment: + - DATABASE_TYPE=${DATABASE_TYPE} + - AUTH_CODE=${AUTH_CODE} + - FEED_MODE=${FEED_MODE} + - CRON_EXPRESSION=${CRON_EXPRESSION} + - MAX_REQUEST_PER_MINUTE=${MAX_REQUEST_PER_MINUTE} + - SERVER_ORIGIN_URL=${SERVER_ORIGIN_URL} + volumes: + - ${DATA_PATH}:/app/data + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/wewe-rss/2.6.1/.env.sample b/apps/wewe-rss/2.6.1/.env.sample new file mode 100644 index 0000000..341e006 --- /dev/null +++ b/apps/wewe-rss/2.6.1/.env.sample @@ -0,0 +1,14 @@ +AUTH_CODE="password" +CONTAINER_NAME="wewe-rss" +CRON_EXPRESSION="35 5,17 * * *" +FEED_MODE="fulltext" +MAX_REQUEST_PER_MINUTE=60 +PANEL_APP_PORT_HTTP=40332 +PANEL_DB_HOST="mysql" +PANEL_DB_HOST_NAME="mysql" +PANEL_DB_NAME="wewe-rss" +PANEL_DB_PORT=3306 +PANEL_DB_TYPE="mysql" +PANEL_DB_USER="wewe-rss" +PANEL_DB_USER_PASSWORD="wewe-rss" +SERVER_ORIGIN_URL="http://1.2.3.4:40332" diff --git a/apps/wewe-rss/2.6.1/data.yml b/apps/wewe-rss/2.6.1/data.yml new file mode 100644 index 0000000..02e5ff9 --- /dev/null +++ b/apps/wewe-rss/2.6.1/data.yml @@ -0,0 +1,64 @@ +additionalProperties: + formFields: + - default: "wewe-rss" + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: "wewe-rss" + envKey: PANEL_DB_ROOT_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: "4000" + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "password" + edit: true + envKey: AUTH_CODE + labelEn: Auth Code + labelZh: 授权码 + random: true + required: true + rule: paramComplexity + type: password + - default: "http://1.2.3.4:4000" + edit: true + envKey: SERVER_ORIGIN_URL + labelEn: External URL + labelZh: 外部访问地址 + required: true + rule: paramExtUrl + type: text + - default: "fulltext" + edit: true + envKey: FEED_MODE + labelEn: Feed Mode + labelZh: 提取模式 + required: false + type: text + - default: "35 5,17 * * *" + edit: true + envKey: CRON_EXPRESSION + labelEn: Cron Expression + labelZh: 定时更新表达式 + required: false + type: text + - default: "60" + edit: true + envKey: MAX_REQUEST_PER_MINUTE + labelEn: Max Requests Per Minute + labelZh: 每分钟最大请求次数 + required: false + type: number diff --git a/apps/wewe-rss/2.6.1/docker-compose.yml b/apps/wewe-rss/2.6.1/docker-compose.yml new file mode 100644 index 0000000..c189e27 --- /dev/null +++ b/apps/wewe-rss/2.6.1/docker-compose.yml @@ -0,0 +1,45 @@ +services: + wewe-rss: + image: "cooderl/wewe-rss:v2.6.1" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:4000" + environment: + - DATABASE_URL=mysql://root:${PANEL_DB_ROOT_PASSWORD}@${CONTAINER_NAME}-mysql:3306/${PANEL_DB_NAME}?schema=public&connect_timeout=30&pool_timeout=30&socket_timeout=30 + - AUTH_CODE=${AUTH_CODE} + - FEED_MODE=${FEED_MODE} + - CRON_EXPRESSION=${CRON_EXPRESSION} + - MAX_REQUEST_PER_MINUTE=${MAX_REQUEST_PER_MINUTE} + - SERVER_ORIGIN_URL=${SERVER_ORIGIN_URL} + depends_on: + - mysql + labels: + createdBy: "Apps" + + mysql: + image: mysql:8.3.0 + container_name: ${CONTAINER_NAME}-mysql + command: --mysql-native-password=ON + environment: + - MYSQL_ROOT_PASSWORD=${PANEL_DB_ROOT_PASSWORD} + - TZ=Asia/Shanghai + - MYSQL_DATABASE=${PANEL_DB_NAME} + volumes: + - mysql_data:/var/lib/mysql + networks: + - 1panel-network + healthcheck: + test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost'] + timeout: 45s + interval: 10s + retries: 10 + +networks: + 1panel-network: + external: true + +volumes: + mysql_data: diff --git a/apps/wewe-rss/README.md b/apps/wewe-rss/README.md new file mode 100644 index 0000000..b7037bf --- /dev/null +++ b/apps/wewe-rss/README.md @@ -0,0 +1,73 @@ +# [WeWe RSS](https://github.com/cooderl/wewe-rss) + +更优雅的微信公众号订阅方式。 + +![](https://cdn.jsdelivr.net/gh/xiaoY233/PicList@main/public/assets/wewe-rss.png) + +![](https://img.shields.io/badge/Copyright-arch3rPro-ff9800?style=flat&logo=github&logoColor=white) + +## ✨ 功能 + +- v2.x版本使用全新接口,更加稳定 +- 支持微信公众号订阅(基于微信读书) +- 获取公众号历史发布文章 +- 后台自动定时更新内容 +- 微信公众号RSS生成(支持`.atom`、`.rss`、`.json`格式) +- 支持全文内容输出,让阅读无障碍 +- 所有订阅源导出OPML + +### 高级功能 + +- **标题过滤**:支持通过`/feeds/all.(json|rss|atom)`接口和`/feeds/:feed`对标题进行过滤 + ``` + {{ORIGIN_URL}}/feeds/all.atom?title_include=张三 + {{ORIGIN_URL}}/feeds/MP_WXS_123.json?limit=30&title_include=张三|李四|王五&title_exclude=张三丰|赵六 + ``` + +- **手动更新**:支持通过`/feeds/:feed`接口触发单个feedid更新 + ``` + {{ORIGIN_URL}}/feeds/MP_WXS_123.rss?update=true + ``` + +## ⚙️ 环境变量 + +| 变量名 | 说明 | 默认值 | +| ------------------------ | ----------------------------------------------------------------------- | --------------------------- | +| `DATABASE_URL` | **必填** 数据库地址,例如 `mysql://root:123456@127.0.0.1:3306/wewe-rss` | - | +| `DATABASE_TYPE` | 数据库类型,使用 SQLite 时需填写 `sqlite` | - | +| `AUTH_CODE` | 服务端接口请求授权码,空字符或不设置将不启用 (`/feeds`路径不需要) | - | +| `SERVER_ORIGIN_URL` | 服务端访问地址,用于生成RSS完整路径 | - | +| `MAX_REQUEST_PER_MINUTE` | 每分钟最大请求次数 | 60 | +| `FEED_MODE` | 输出模式,可选值 `fulltext` (会使接口响应变慢,占用更多内存) | - | +| `CRON_EXPRESSION` | 定时更新订阅源Cron表达式 | `35 5,17 * * *` | +| `UPDATE_DELAY_TIME` | 连续更新延迟时间,减少被关小黑屋 | `60s` | +| `ENABLE_CLEAN_HTML` | 是否开启正文html清理 | `false` | +| `PLATFORM_URL` | 基础服务URL | `https://weread.111965.xyz` | + +> **注意**: 国内DNS解析问题可使用 `https://weread.965111.xyz` 加速访问 + +## 🔔 钉钉通知 + +进入 wewe-rss-dingtalk 目录按照 README.md 指引部署 + +## 📱 使用方式 + +1. 进入账号管理,点击添加账号,微信扫码登录微信读书账号。 + + **注意不要勾选24小时后自动退出** + + + + +2. 进入公众号源,点击添加,通过提交微信公众号分享链接,订阅微信公众号。 + **添加频率过高容易被封控,等24小时解封** + + + +## 🔑 账号状态说明 + +| 状态 | 说明 | +| ---------- | ------------------------------------------------------------------- | +| 今日小黑屋 | 账号被封控,等一天恢复。账号正常时可通过重启服务/容器清除小黑屋记录 | +| 禁用 | 不使用该账号 | +| 失效 | 账号登录状态失效,需要重新登录 | \ No newline at end of file diff --git a/apps/wewe-rss/data.yml b/apps/wewe-rss/data.yml new file mode 100644 index 0000000..db427b5 --- /dev/null +++ b/apps/wewe-rss/data.yml @@ -0,0 +1,26 @@ +name: WeWe RSS +tags: + - 实用工具 +title: 更优雅的微信公众号订阅方式 +description: WeWe RSS 是一个优雅的微信公众号订阅工具,支持RSS输出和文章存档 +additionalProperties: + key: wewe-rss + name: WeWe RSS + tags: + - Tool + shortDescZh: 更优雅的微信公众号订阅方式 + shortDescEn: A more elegant way to subscribe to WeChat Official Accounts + description: + en: WeWe RSS is an elegant tool for subscribing to WeChat Official Accounts with RSS output and article archiving + zh-Hant: WeWe RSS 是一個優雅的微信公眾號訂閱工具,支持RSS輸出和文章存檔 + zh: WeWe RSS 是一个优雅的微信公众号订阅工具,支持RSS输出和文章存档 + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/cooderl/wewe-rss + github: https://github.com/cooderl/wewe-rss + document: https://github.com/cooderl/wewe-rss + architectures: + - amd64 + - arm64 diff --git a/apps/wewe-rss/latest/.env.sample b/apps/wewe-rss/latest/.env.sample new file mode 100644 index 0000000..341e006 --- /dev/null +++ b/apps/wewe-rss/latest/.env.sample @@ -0,0 +1,14 @@ +AUTH_CODE="password" +CONTAINER_NAME="wewe-rss" +CRON_EXPRESSION="35 5,17 * * *" +FEED_MODE="fulltext" +MAX_REQUEST_PER_MINUTE=60 +PANEL_APP_PORT_HTTP=40332 +PANEL_DB_HOST="mysql" +PANEL_DB_HOST_NAME="mysql" +PANEL_DB_NAME="wewe-rss" +PANEL_DB_PORT=3306 +PANEL_DB_TYPE="mysql" +PANEL_DB_USER="wewe-rss" +PANEL_DB_USER_PASSWORD="wewe-rss" +SERVER_ORIGIN_URL="http://1.2.3.4:40332" diff --git a/apps/wewe-rss/latest/data.yml b/apps/wewe-rss/latest/data.yml new file mode 100644 index 0000000..02e5ff9 --- /dev/null +++ b/apps/wewe-rss/latest/data.yml @@ -0,0 +1,64 @@ +additionalProperties: + formFields: + - default: "wewe-rss" + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: "wewe-rss" + envKey: PANEL_DB_ROOT_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: "4000" + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "password" + edit: true + envKey: AUTH_CODE + labelEn: Auth Code + labelZh: 授权码 + random: true + required: true + rule: paramComplexity + type: password + - default: "http://1.2.3.4:4000" + edit: true + envKey: SERVER_ORIGIN_URL + labelEn: External URL + labelZh: 外部访问地址 + required: true + rule: paramExtUrl + type: text + - default: "fulltext" + edit: true + envKey: FEED_MODE + labelEn: Feed Mode + labelZh: 提取模式 + required: false + type: text + - default: "35 5,17 * * *" + edit: true + envKey: CRON_EXPRESSION + labelEn: Cron Expression + labelZh: 定时更新表达式 + required: false + type: text + - default: "60" + edit: true + envKey: MAX_REQUEST_PER_MINUTE + labelEn: Max Requests Per Minute + labelZh: 每分钟最大请求次数 + required: false + type: number diff --git a/apps/wewe-rss/latest/docker-compose.yml b/apps/wewe-rss/latest/docker-compose.yml new file mode 100644 index 0000000..0e3ae76 --- /dev/null +++ b/apps/wewe-rss/latest/docker-compose.yml @@ -0,0 +1,45 @@ +services: + wewe-rss: + image: "cooderl/wewe-rss:latest" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:4000" + environment: + - DATABASE_URL=mysql://root:${PANEL_DB_ROOT_PASSWORD}@${CONTAINER_NAME}-mysql:3306/${PANEL_DB_NAME}?schema=public&connect_timeout=30&pool_timeout=30&socket_timeout=30 + - AUTH_CODE=${AUTH_CODE} + - FEED_MODE=${FEED_MODE} + - CRON_EXPRESSION=${CRON_EXPRESSION} + - MAX_REQUEST_PER_MINUTE=${MAX_REQUEST_PER_MINUTE} + - SERVER_ORIGIN_URL=${SERVER_ORIGIN_URL} + depends_on: + - mysql + labels: + createdBy: "Apps" + + mysql: + image: mysql:8.3.0 + container_name: ${CONTAINER_NAME}-mysql + command: --mysql-native-password=ON + environment: + - MYSQL_ROOT_PASSWORD=${PANEL_DB_ROOT_PASSWORD} + - TZ=Asia/Shanghai + - MYSQL_DATABASE=${PANEL_DB_NAME} + volumes: + - mysql_data:/var/lib/mysql + networks: + - 1panel-network + healthcheck: + test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost'] + timeout: 45s + interval: 10s + retries: 10 + +networks: + 1panel-network: + external: true + +volumes: + mysql_data: diff --git a/apps/wewe-rss/logo.png b/apps/wewe-rss/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..812ceb92929a16a1b51f4866a288ed2de1840acb GIT binary patch literal 3646 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 QcmMzZ07*qoM6N<$g1?SETL1t6 literal 0 HcmV?d00001