Files
memind/wechat-egress-fetch.mjs
john e5cbe80644 feat(wechat): widen 105 egress proxy to /cgi-bin/* and add egress fetch helper
The proxy now forwards any api.weixin.qq.com/cgi-bin/* path (drafts, material
upload, etc.), binds to the 10.10.0.1 tunnel address, and uses a 120s timeout.
wechat-egress-fetch.mjs rewrites WeChat API URLs to the egress base when
MEMIND_WECHAT_EGRESS_BASE_URL is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 10:07:32 +08:00

50 lines
1.4 KiB
JavaScript

import { fetch as undiciFetch } from 'undici';
const WECHAT_API_HOST = 'api.weixin.qq.com';
/**
* 105 固定 IP 出站代理基址,例如 http://10.10.0.1:19090
* 未配置时直连 api.weixin.qq.com(开发环境)。
*/
export function resolveWechatEgressBaseUrl(env = process.env) {
return String(
env.MEMIND_WECHAT_EGRESS_BASE_URL
?? env.WECHAT_EGRESS_BASE_URL
?? '',
).trim().replace(/\/$/, '');
}
/** 把微信 API URL 改写到 105 egress proxy。 */
export function rewriteWechatApiUrl(url, egressBase) {
const raw = String(url ?? '').trim();
if (!raw || !egressBase) return raw;
let parsed;
try {
parsed = new URL(raw);
} catch {
return raw;
}
if (parsed.hostname !== WECHAT_API_HOST) return raw;
return `${egressBase}${parsed.pathname}${parsed.search}`;
}
/**
* 返回 wechatFetch:请求 api.weixin.qq.com 时改走 egress proxy,其余 URL 不变。
*/
export function createWechatEgressFetch(egressBase, { fetchImpl = undiciFetch } = {}) {
const base = String(egressBase ?? '').trim().replace(/\/$/, '');
if (!base) return fetchImpl;
return async (input, init) => {
const url = typeof input === 'string'
? input
: input instanceof URL
? input.href
: input.url;
return fetchImpl(rewriteWechatApiUrl(url, base), init);
};
}
export function resolveWechatFetch(env = process.env) {
return createWechatEgressFetch(resolveWechatEgressBaseUrl(env));
}