Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Post articles and image-text content to WeChat Official Account via API or Chrome CDP, with markdown-to-WeChat HTML conversion.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/wechat-image-loader.ts
1import fs from "node:fs";2import path from "node:path";3import {4type WechatUploadAsset,5detectImageFormatFromBuffer,6} from "./wechat-image-processor.ts";78export type { WechatUploadAsset };910const MIME_TYPES_BY_EXT: Record<string, string> = {11".jpg": "image/jpeg",12".jpeg": "image/jpeg",13".png": "image/png",14".gif": "image/gif",15".webp": "image/webp",16".bmp": "image/bmp",17".tiff": "image/tiff",18".tif": "image/tiff",19".svg": "image/svg+xml",20".ico": "image/x-icon",21};2223export async function loadUploadAsset(24imagePath: string,25baseDir?: string,26): Promise<WechatUploadAsset> {27let fileBuffer: Buffer;28let filename: string;29let contentType: string;30let fileSize = 0;31let fileExt = "";3233if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) {34const response = await fetch(imagePath);35if (!response.ok) {36throw new Error(`Failed to download image: ${imagePath}`);37}38const buffer = await response.arrayBuffer();39if (buffer.byteLength === 0) {40throw new Error(`Remote image is empty: ${imagePath}`);41}42fileBuffer = Buffer.from(buffer);43fileSize = buffer.byteLength;44const urlPath = imagePath.split("?")[0]!;45filename = path.basename(urlPath) || "image.jpg";46fileExt = path.extname(filename).toLowerCase();47contentType = response.headers.get("content-type") || "image/jpeg";48} else {49const resolvedPath = path.isAbsolute(imagePath)50? imagePath51: path.resolve(baseDir || process.cwd(), imagePath);5253if (!fs.existsSync(resolvedPath)) {54throw new Error(`Image not found: ${resolvedPath}`);55}56const stats = fs.statSync(resolvedPath);57if (stats.size === 0) {58throw new Error(`Local image is empty: ${resolvedPath}`);59}60fileSize = stats.size;61fileBuffer = fs.readFileSync(resolvedPath);62filename = path.basename(resolvedPath);63fileExt = path.extname(filename).toLowerCase();64contentType = MIME_TYPES_BY_EXT[fileExt] || "image/jpeg";65}6667const detected = detectImageFormatFromBuffer(fileBuffer);68if (detected && detected.contentType !== contentType) {69console.error(`[wechat-api] Format mismatch: ${filename} declared as ${contentType}, actual ${detected.contentType}`);70contentType = detected.contentType;71fileExt = detected.fileExt;72filename = `${path.basename(filename, path.extname(filename))}${detected.fileExt}`;73}7475return {76buffer: fileBuffer,77filename,78contentType,79fileExt,80fileSize,81};82}83