{"id":13459316,"url":"https://github.com/easychen/wecomchan","last_synced_at":"2025-10-08T22:08:08.632Z","repository":{"id":37385266,"uuid":"372153422","full_name":"easychen/wecomchan","owner":"easychen","description":"微信推送服务Server酱的开源替代。通过企业微信向微信推送消息的配置文档、直推函数和可自行搭建的在线服务代码。 ","archived":false,"fork":false,"pushed_at":"2024-07-30T02:57:52.000Z","size":1755,"stargazers_count":1513,"open_issues_count":24,"forks_count":271,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-15T02:11:40.657Z","etag":null,"topics":["push-notifications","serverchan","wechat","weixin"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easychen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-30T07:41:41.000Z","updated_at":"2025-04-13T13:21:00.000Z","dependencies_parsed_at":"2024-07-30T06:58:07.182Z","dependency_job_id":"d534924a-0ad0-40f6-a751-3f9483fa95a1","html_url":"https://github.com/easychen/wecomchan","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fwecomchan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fwecomchan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fwecomchan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fwecomchan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easychen","download_url":"https://codeload.github.com/easychen/wecomchan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254346624,"owners_count":22055808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["push-notifications","serverchan","wechat","weixin"],"created_at":"2024-07-31T09:01:15.727Z","updated_at":"2025-10-08T22:08:03.604Z","avatar_url":"https://github.com/easychen.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Wecom酱\n\n通过企业微信向微信推送消息的解决方案。包括：\n\n1. 配置说明（本页下方）\n2. 推送函数（支持多种语言，见本页下方）\n3. 自行搭建的在线服务源码 \n   1. [PHP版搭建说明](ONLINE.md) \n   2. [Go版说明](go-wecomchan/README.md)\n   3. [Go适配华为函数工作流版本](https://github.com/Colo-Thor/wecomchan/releases/tag/2.2)\n   4. [腾讯云云函数搭建说明](go-scf/) ⚠️ 2022年5月起的最低月消费[已经取消了](https://cloud.tencent.com/document/product/583/104909)\n   5. [阿里云云函数搭建说明](python-aliyunfc/) \n   6. [百度智能云函数搭建说明](python-baiduCFC/)\n   7. [Python版华为函数工作流搭建说明](python-huaweiFG/)\n\n## 🎈 本项目属于方糖推送生态。该生态包含项目如下：\n\n- [Server酱Turbo](https://sct.ftqq.com)：支持企业微信、微信服务号、钉钉、飞书群机器人等多通道的在线服务，无需搭建直接使用，每天有免费额度\n- [Wecom酱](https://github.com/easychen/wecomchan)：通过企业微信推送消息到微信的消息推送函数和在线服务方案，开源免费，可自己搭建。支持多语言。\n- [PushDeer](https://github.com/easychen/pushdeer)：可自行搭建的、无需安装APP的开源推送方案。同时也提供安装APP的降级方案给低版本/没有快应用的系统。支持作为Server酱的通道进行推送，所有支持Server酱的软件和插件都能直接整合PushDeer。\n\n## 企业微信应用消息配置说明\n\n优点：\n\n1. 一次配置，持续使用\n1. 配置好以后，只需要微信就能收消息，不再需要安装企业微信客户端\n\nPS：消息接口无需认证即可使用，个人用微信就可以注册\n\n### 具体操作\n\n#### 第一步，注册企业\n\n用电脑打开[企业微信官网](https://work.weixin.qq.com/)，注册一个企业\n\n#### 第二步，创建应用\n\n注册成功后，点「管理企业」进入管理界面，选择「应用管理」 → 「自建」 →  「创建应用」\n\n![](https://theseven.ftqq.com/20210208143228.png)\n\n应用名称填入「Server酱」，应用logo到[这里](./20210208142819.png)下载，可见范围选择公司名。\n\n\n![](https://theseven.ftqq.com/20210208143327.png)\n\n创建完成后进入应用详情页，可以得到应用ID( `agentid` )①，应用Secret( `secret` )②。\n\n注意：`secret`推送到手机端时，只能在`企业微信客户端`中查看。\n\n#### 第三步，添加可信IP\n\n\u003e 2022年6月20日之后创建的应用，需要额外配置可信IP。\n\n在「应用详情页」的最下方，开发者接口分类中，找到「企业可信IP」，点击「配置」，并填入服务器IP即可。\n\n注意，如果你使用云函数等公用IP的云服务，可能需要在（云函数或其他服务的）设置界面中打开「固定公网IP」来获得一个独立的IP。否则有可能报「第三方服务IP」错误。\n\n#### 第四步，获取企业ID\n\n进入「[我的企业](https://work.weixin.qq.com/wework_admin/frame#profile)」页面，拉到最下边，可以看到企业ID③，复制并填到上方。\n\n推送UID直接填 `@all` ，推送给公司全员。\n\n#### 第五步，推送消息到微信\n\n进入「我的企业」 → 「[微信插件](https://work.weixin.qq.com/wework_admin/frame#profile/wxPlugin)」，拉到下边扫描二维码，关注以后即可收到推送的消息。\n\n![](https://theseven.ftqq.com/20210208144808.png)\n\nPS：如果出现`接口请求正常，企业微信接受消息正常，个人微信无法收到消息`的情况：\n\n1. 进入「我的企业」 → 「[微信插件](https://work.weixin.qq.com/wework_admin/frame#profile/wxPlugin)」，拉到最下方，勾选 “允许成员在微信插件中接收和回复聊天消息”\n![](https://img.ams1.imgbed.xyz/2021/06/01/HPIRU.jpg)\n\n2. 在企业微信客户端 「我」 → 「设置」  → 「新消息通知」中关闭 “仅在企业微信中接受消息” 限制条件\n![](https://img.ams1.imgbed.xyz/2021/06/01/HPKPX.jpg)\n\n#### 第六步，通过以下函数发送消息：\n\nPS：为使用方便，以下函数没有对 `access_token` 进行缓存。对于个人低频调用已经够用。带缓存的实现可查看 `index.php` 中的示例代码（依赖Redis实现）。\n\nPHP版：\n\n```php\nfunction send_to_wecom($text, $wecom_cid, $wecom_aid, $wecom_secret,  $wecom_touid = '@all')\n{\n    $info = @json_decode(file_get_contents(\"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=\".urlencode($wecom_cid).\"\u0026corpsecret=\".urlencode($wecom_secret)), true);\n                \n    if ($info \u0026\u0026 isset($info['access_token']) \u0026\u0026 strlen($info['access_token']) \u003e 0) {\n        $access_token = $info['access_token'];\n        $url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token='.urlencode($access_token);\n        $data = new \\stdClass();\n        $data-\u003etouser = $wecom_touid;\n        $data-\u003eagentid = $wecom_aid;\n        $data-\u003emsgtype = \"text\";\n        $data-\u003etext = [\"content\"=\u003e $text];\n        $data-\u003eduplicate_check_interval = 600;\n\n        $data_json = json_encode($data);\n        $ch = curl_init();\n        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);\n        curl_setopt($ch, CURLOPT_URL, $url);\n        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n        @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);\n        curl_setopt($ch, CURLOPT_POST, true);\n        curl_setopt($ch, CURLOPT_TIMEOUT, 5);\n        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);\n\n        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);\n        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\n        \n        $response = curl_exec($ch);\n        return $response;\n    }\n    return false;\n}\n\n```\n\n使用实例：\n\n```php\n$ret = send_to_wecom(\"推送测试\\r\\n测试换行\", \"企业ID③\", \"应用ID①\", \"应用secret②\");\nprint_r( $ret );\n```\n\nPYTHON版:\n\n```python\nimport json,requests,base64\ndef send_to_wecom(text,wecom_cid,wecom_aid,wecom_secret,wecom_touid='@all'):\n    get_token_url = f\"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={wecom_cid}\u0026corpsecret={wecom_secret}\"\n    response = requests.get(get_token_url).content\n    access_token = json.loads(response).get('access_token')\n    if access_token and len(access_token) \u003e 0:\n        send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={access_token}'\n        data = {\n            \"touser\":wecom_touid,\n            \"agentid\":wecom_aid,\n            \"msgtype\":\"text\",\n            \"text\":{\n                \"content\":text\n            },\n            \"duplicate_check_interval\":600\n        }\n        response = requests.post(send_msg_url,data=json.dumps(data)).content\n        return response\n    else:\n        return False\n\ndef send_to_wecom_image(base64_content,wecom_cid,wecom_aid,wecom_secret,wecom_touid='@all'):\n    get_token_url = f\"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={wecom_cid}\u0026corpsecret={wecom_secret}\"\n    response = requests.get(get_token_url).content\n    access_token = json.loads(response).get('access_token')\n    if access_token and len(access_token) \u003e 0:\n        upload_url = f'https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}\u0026type=image'\n        upload_response = requests.post(upload_url, files={\n            \"picture\": base64.b64decode(base64_content)\n        }).json()\n        if \"media_id\" in upload_response:\n            media_id = upload_response['media_id']\n        else:\n            return False\n\n        send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={access_token}'\n        data = {\n            \"touser\":wecom_touid,\n            \"agentid\":wecom_aid,\n            \"msgtype\":\"image\",\n            \"image\":{\n                \"media_id\": media_id\n            },\n            \"duplicate_check_interval\":600\n        }\n        response = requests.post(send_msg_url,data=json.dumps(data)).content\n        return response\n    else:\n        return False\n\ndef send_to_wecom_markdown(text,wecom_cid,wecom_aid,wecom_secret,wecom_touid='@all'):\n    get_token_url = f\"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={wecom_cid}\u0026corpsecret={wecom_secret}\"\n    response = requests.get(get_token_url).content\n    access_token = json.loads(response).get('access_token')\n    if access_token and len(access_token) \u003e 0:\n        send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={access_token}'\n        data = {\n            \"touser\":wecom_touid,\n            \"agentid\":wecom_aid,\n            \"msgtype\":\"markdown\",\n            \"markdown\":{\n                \"content\":text\n            },\n            \"duplicate_check_interval\":600\n        }\n        response = requests.post(send_msg_url,data=json.dumps(data)).content\n        return response\n    else:\n        return False\n```\n\n使用实例：\n\n```python\nret = send_to_wecom(\"推送测试\\r\\n测试换行\", \"企业ID③\", \"应用ID①\", \"应用secret②\");\nprint( ret );\nret = send_to_wecom('\u003ca href=\"https://www.github.com/\"\u003e文本中支持超链接\u003c/a\u003e', \"企业ID③\", \"应用ID①\", \"应用secret②\");\nprint( ret );\nret = send_to_wecom_image(\"此处填写图片Base64\", \"企业ID③\", \"应用ID①\", \"应用secret②\");\nprint( ret );\nret = send_to_wecom_markdown(\"**Markdown 内容**\", \"企业ID③\", \"应用ID①\", \"应用secret②\");\nprint( ret );\n```\n\nTypeScript 版:\n\n```typescript\nimport request from 'superagent'\n\nasync function sendToWecom(body: {\n  text: string\n  wecomCId: string\n  wecomSecret: string\n  wecomAgentId: string\n  wecomTouid?: string\n}): Promise\u003c{ errcode: number; errmsg: string; invaliduser: string }\u003e {\n  body.wecomTouid = body.wecomTouid ?? '@all'\n  const getTokenUrl = `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${body.wecomCId}\u0026corpsecret=${body.wecomSecret}`\n  const getTokenRes = await request.get(getTokenUrl)\n  const accessToken = getTokenRes.body.access_token\n  if (accessToken?.length \u003c= 0) {\n    throw new Error('获取 accessToken 失败')\n  }\n  const sendMsgUrl = `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accessToken}`\n  const sendMsgRes = await request.post(sendMsgUrl).send({\n    touser: body.wecomTouid,\n    agentid: body.wecomAgentId,\n    msgtype: 'text',\n    text: {\n      content: body.text,\n    },\n    duplicate_check_interval: 600,\n  })\n  return sendMsgRes.body\n}\n```\n\n使用实例：\n\n```typescript\nsendToWecom({\n  text: '推送测试\\r\\n测试换行',\n  wecomAgentId: '应用ID①',\n  wecomSecret: '应用secret②',\n  wecomCId: '企业ID③',\n})\n  .then((res) =\u003e {\n    console.log(res)\n  })\n  .catch((err) =\u003e {\n    console.log(err)\n  })\n```\n\n.NET Core 版:\n\n```C#\nusing System;\nusing RestSharp;\nusing Newtonsoft.Json;\nnamespace WeCom.Demo\n{\n    class WeCom\n    {   \n        public  string SendToWeCom(\n            string text,// 推送消息\n            string weComCId,// 企业Id①\n            string weComSecret,// 应用secret②\n            string weComAId,// 应用ID③\n            string weComTouId = \"@all\")\n        {\n            // 获取Token\n            string getTokenUrl = $\"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={weComCId}\u0026corpsecret={weComSecret}\";\n            string token = JsonConvert\n            .DeserializeObject\u003cdynamic\u003e(new RestClient(getTokenUrl)\n            .Get(new RestRequest()).Content).access_token;\n            System.Console.WriteLine(token);\n            if (!String.IsNullOrWhiteSpace(token))\n            {\n                var request = new RestRequest();\n                var client = new RestClient($\"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}\");\n                var data = new\n                {\n                    touser = weComTouId,\n                    agentid = weComAId,\n                    msgtype = \"text\",\n                    text = new\n                    {\n                        content = text\n                    },\n                    duplicate_check_interval = 600\n                };\n                string serJson = JsonConvert.SerializeObject(data);\n                System.Console.WriteLine(serJson);\n                request.Method = Method.POST;\n                request.AddHeader(\"Accept\", \"application/json\");\n                request.Parameters.Clear();\n                request.AddParameter(\"application/json\", serJson, ParameterType.RequestBody);\n                return client.Execute(request).Content;\n            }\n            return \"-1\";\n        }\n}\n\n\n```\n使用实例:\n```C#\n   static void Main(string[] args)\n        {   // 测试\n            Console.Write(new WeCom().SendToWeCom(\n            \"msginfo\",\n            \"企业Id①\"\n            , \"应用secret②\",\n            \"应用ID③\"\n            ));\n        }\n\n    }\n```\n\n- [纯Bash版本参考](https://gitee.com/Hemingway2003/pushservice/blob/master/wecom.sh)\n\n其他版本的函数可参照上边的逻辑自行编写，欢迎PR。\n\n发送图片、卡片、文件或 Markdown 消息的高级用法见 [企业微信API](https://work.weixin.qq.com/api/doc/90000/90135/90236)。\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fwecomchan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasychen%2Fwecomchan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fwecomchan/lists"}