事倍功半是蠢蛋 31 微信公众号上传草稿 40007

image

接口文档:
https://developers.weixin.qq.com/doc/subscription/api/draftbox/draftmanage/api_draft_add.html
官方文档有错误?是我理解错了吗 图文消息必填为‘否’ 但是事实上他的必填为‘是’ 否则就会报40007缺乏media_id的错误
如果图片消息跟图文消息都必须要资源的话,那他不应该是必填吗

错误:

demo:

cursor生成的demo代码 亲测可以使用。

import requests
import os
import json
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 配置信息把这改了 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
APP_ID = ""
APP_SECRET = ""
IMAGE_PATH = "cover.png"  # 本地图片路径
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


def get_access_token(app_id: str, app_secret: str) -> str:
    """获取access_token"""
    token_url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={app_id}&secret={app_secret}"
    try:
        token_res = requests.get(token_url).json()
        access_token = token_res.get("access_token")
        if not access_token:
            logger.error(f"获取access_token失败: {token_res}")
            raise Exception(f"获取access_token失败: {token_res.get('errmsg', '未知错误')}")
        logger.info(f"获取access_token成功: {access_token[:20]}...")
        return access_token
    except requests.RequestException as e:
        logger.error(f"网络请求失败: {str(e)}")
        raise
    except json.JSONDecodeError as e:
        logger.error(f"JSON解析失败: {str(e)}")
        raise
    except Exception as e:
        logger.error(f"获取access_token异常: {str(e)}")
        raise


def upload_image(access_token: str, image_path: str) -> str:
    """使用永久素材接口上传图片并返回media_id"""
    upload_url = f"https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={access_token}&type=image"
    try:
        with open(image_path, 'rb') as file:
            files = {'media': file}
            response = requests.post(upload_url, files=files)
            result = response.json()

        # 检查返回结果
        if 'errcode' in result and result['errcode'] != 0:
            logger.error(f"上传永久图片失败: {result}")
            raise Exception(f"上传永久图片失败: {result.get('errmsg', '未知错误')}")

        media_id = result.get('media_id')
        if not media_id:
            logger.error(f"获取media_id失败: {result}")
            raise Exception("上传成功但未返回有效的media_id")

        logger.info(f"永久图片上传成功! media_id: {media_id}")
        # 如果是图片类型,返回的url也可以记录(可选)
        if 'url' in result:
            logger.info(f"图片URL: {result['url']}")

        return media_id
    except FileNotFoundError:
        logger.error(f"图片文件不存在: {image_path}")
        raise
    except requests.RequestException as e:
        logger.error(f"永久图片上传网络请求失败: {str(e)}")
        raise
    except json.JSONDecodeError as e:
        logger.error(f"永久图片上传响应解析失败: {str(e)}")
        raise
    except Exception as e:
        logger.error(f"永久图片上传异常: {str(e)}")
        raise


def create_draft(access_token: str, draft_data: dict) -> str:
    """创建草稿并返回media_id"""
    draft_url = f"https://api.weixin.qq.com/cgi-bin/draft/add?access_token={access_token}"
    headers = {"Content-Type": "application/json"}
    try:
        draft_res = requests.post(draft_url, headers=headers, data=json.dumps(draft_data, ensure_ascii=False)).json()
        media_id = draft_res.get("media_id")
        if not media_id:
            logger.error(f"草稿创建失败: {draft_res}")
            raise Exception(f"草稿创建失败: {draft_res.get('errmsg', '未知错误')}")
        logger.info(f"草稿创建成功! media_id: {media_id}")
        return media_id
    except requests.RequestException as e:
        logger.error(f"创建草稿时网络请求失败: {str(e)}")
        raise
    except json.JSONDecodeError as e:
        logger.error(f"解析创建响应失败: {str(e)}")
        raise
    except Exception as e:
        logger.error(f"创建草稿异常: {str(e)}")
        raise


def main():
    """主函数"""
    try:
        # 1. 获取access_token
        access_token = get_access_token(APP_ID, APP_SECRET)

        # 2. 上传封面图片
        thumb_media_id = upload_image(access_token, IMAGE_PATH)

        # 3. 准备草稿数据(包含有效的thumb_media_id)
        draft_data = {
            "articles": [
                {
                    "title": "测试文章标题123",
                    "author": "作者名称321",
                    "digest": "这里是文章摘要1234567",
                    "content": "<p>文章正文内容999</p>",
                    "thumb_media_id": thumb_media_id,  # 使用上传获取的有效ID
                    "content_source_url": "https://example.com",  # 原文链接
                    "need_open_comment": 1,  # 开启评论
                    "only_fans_can_comment": 0  # 所有人可评论
                }
            ]
        }

        # 4. 创建草稿
        draft_media_id = create_draft(access_token, draft_data)
        print(f"🎉 操作成功!草稿ID: {draft_media_id}")

    except Exception as e:
        logger.exception("操作失败")
        print(f"❌ 操作失败: {str(e)}")


if __name__ == "__main__":
    main()
posted @ 2025-07-01 17:54  空心橙子  阅读(62)  评论(0)    收藏  举报