透過企業微信向微信推播訊息的解決方案。包括:
優點:
PS:訊息介面無需認證即可使用,個人用微信就可以註冊
用電腦打開企業微信官網,註冊一個企業
註冊成功後,點「管理企業」進入管理介面,選擇「應用程式管理」 → “自建” → “創建應用”
應用程式名稱填入「Server醬」,應用logo到這裡下載,可見範圍選擇公司名稱。
建立完成後進入應用程式詳情頁,可以得到應用ID( agentid
)①,應用Secret( secret
)②。
注意: secret
推送到手機端時,只能在企业微信客户端
中查看。
2022年6月20日之後創建的應用,需要額外配置可信任IP。
在「套用詳情頁」的最下方,開發者介面分類中,找到「企業可信任IP」,點選「設定」,並填入伺服器IP即可。
注意,如果你使用雲端函數等公用IP的雲端服務,可能需要在(雲端函數或其他服務的)設定介面中開啟「固定公用IP」來獲得一個獨立的IP。否則有可能報「第三方服務IP」錯誤。
進入「我的企業」頁面,拉到最下邊,可以看到企業ID③,複製並填到上方。
推送UID直接填@all
,推播給公司全員。
進入「我的企業」 → 「微信外掛」,拉到下邊掃描二維碼,關注以後即可收到推播的訊息。
PS:如果出現接口请求正常,企业微信接受消息正常,个人微信无法收到消息
的情況:
進入「我的企業」 → “微信插件”,拉到最下方,勾選“允許成員在微信插件中接收和回覆聊天訊息”
在企業微信客戶端「我」 → 「設定」 → 「新訊息通知」中關閉「僅在企業微信中接受訊息」 限制條件
PS:為使用方便,以下函數沒有對access_token
進行快取。對於個人低頻呼叫已經夠用。具有快取的實作可查看index.php
中的範例程式碼(依賴Redis實作)。
PHP版:
function send_to_wecom ( $ text , $ wecom_cid , $ wecom_aid , $ wecom_secret , $ wecom_touid = ' @all ' )
{
$ info = @ json_decode ( file_get_contents ( " https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= " . urlencode ( $ wecom_cid ). " &corpsecret= " . urlencode ( $ wecom_secret )), true );
if ( $ info && isset ( $ info [ ' access_token ' ]) && strlen ( $ info [ ' access_token ' ]) > 0 ) {
$ access_token = $ info [ ' access_token ' ];
$ url = ' https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= ' . urlencode ( $ access_token );
$ data = new stdClass ();
$ data -> touser = $ wecom_touid ;
$ data -> agentid = $ wecom_aid ;
$ data -> msgtype = " text " ;
$ data -> text = [ " content " => $ text ];
$ data -> duplicate_check_interval = 600 ;
$ data_json = json_encode ( $ data );
$ ch = curl_init ();
curl_setopt ( $ ch , CURLOPT_HTTPHEADER , [ ' Content-Type: application/json ' ]);
curl_setopt ( $ ch , CURLOPT_URL , $ url );
curl_setopt ( $ ch , CURLOPT_RETURNTRANSFER , true );
@ curl_setopt ( $ ch , CURLOPT_FOLLOWLOCATION , true );
curl_setopt ( $ ch , CURLOPT_POST , true );
curl_setopt ( $ ch , CURLOPT_TIMEOUT , 5 );
curl_setopt ( $ ch , CURLOPT_POSTFIELDS , $ data_json );
curl_setopt ( $ ch , CURLOPT_SSL_VERIFYHOST , false );
curl_setopt ( $ ch , CURLOPT_SSL_VERIFYPEER , false );
$ response = curl_exec ( $ ch );
return $ response ;
}
return false ;
}
使用實例:
$ ret = send_to_wecom ( "推送测试rn测试换行" , "企业ID③ " , "应用ID① " , "应用secret② " );
print_r ( $ ret );
PYTHON版:
import json , requests , base64
def send_to_wecom ( text , wecom_cid , wecom_aid , wecom_secret , wecom_touid = '@all' ):
get_token_url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= { wecom_cid } &corpsecret= { wecom_secret } "
response = requests . get ( get_token_url ). content
access_token = json . loads ( response ). get ( 'access_token' )
if access_token and len ( access_token ) > 0 :
send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= { access_token } '
data = {
"touser" : wecom_touid ,
"agentid" : wecom_aid ,
"msgtype" : "text" ,
"text" :{
"content" : text
},
"duplicate_check_interval" : 600
}
response = requests . post ( send_msg_url , data = json . dumps ( data )). content
return response
else :
return False
def send_to_wecom_image ( base64_content , wecom_cid , wecom_aid , wecom_secret , wecom_touid = '@all' ):
get_token_url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= { wecom_cid } &corpsecret= { wecom_secret } "
response = requests . get ( get_token_url ). content
access_token = json . loads ( response ). get ( 'access_token' )
if access_token and len ( access_token ) > 0 :
upload_url = f'https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token= { access_token } &type=image'
upload_response = requests . post ( upload_url , files = {
"picture" : base64 . b64decode ( base64_content )
}). json ()
if "media_id" in upload_response :
media_id = upload_response [ 'media_id' ]
else :
return False
send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= { access_token } '
data = {
"touser" : wecom_touid ,
"agentid" : wecom_aid ,
"msgtype" : "image" ,
"image" :{
"media_id" : media_id
},
"duplicate_check_interval" : 600
}
response = requests . post ( send_msg_url , data = json . dumps ( data )). content
return response
else :
return False
def send_to_wecom_markdown ( text , wecom_cid , wecom_aid , wecom_secret , wecom_touid = '@all' ):
get_token_url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= { wecom_cid } &corpsecret= { wecom_secret } "
response = requests . get ( get_token_url ). content
access_token = json . loads ( response ). get ( 'access_token' )
if access_token and len ( access_token ) > 0 :
send_msg_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= { access_token } '
data = {
"touser" : wecom_touid ,
"agentid" : wecom_aid ,
"msgtype" : "markdown" ,
"markdown" :{
"content" : text
},
"duplicate_check_interval" : 600
}
response = requests . post ( send_msg_url , data = json . dumps ( data )). content
return response
else :
return False
使用實例:
ret = send_to_wecom ( "推送测试r n测试换行" , "企业ID③" , "应用ID①" , "应用secret②" );
print ( ret );
ret = send_to_wecom ( '<a href="https://www.github.com/">文本中支持超链接</a>' , "企业ID③" , "应用ID①" , "应用secret②" );
print ( ret );
ret = send_to_wecom_image ( "此处填写图片Base64" , "企业ID③" , "应用ID①" , "应用secret②" );
print ( ret );
ret = send_to_wecom_markdown ( "**Markdown 内容**" , "企业ID③" , "应用ID①" , "应用secret②" );
print ( ret );
TypeScript 版:
import request from 'superagent'
async function sendToWecom ( body : {
text : string
wecomCId : string
wecomSecret : string
wecomAgentId : string
wecomTouid ?: string
} ) : Promise < { errcode : number ; errmsg : string ; invaliduser : string } > {
body . wecomTouid = body . wecomTouid ?? '@all'
const getTokenUrl = `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= ${ body . wecomCId } &corpsecret= ${ body . wecomSecret } `
const getTokenRes = await request . get ( getTokenUrl )
const accessToken = getTokenRes . body . access_token
if ( accessToken ?. length <= 0 ) {
throw new Error ( '获取 accessToken 失败' )
}
const sendMsgUrl = `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= ${ accessToken } `
const sendMsgRes = await request . post ( sendMsgUrl ) . send ( {
touser : body . wecomTouid ,
agentid : body . wecomAgentId ,
msgtype : 'text' ,
text : {
content : body . text ,
} ,
duplicate_check_interval : 600 ,
} )
return sendMsgRes . body
}
使用實例:
sendToWecom ( {
text : '推送测试rn测试换行' ,
wecomAgentId : '应用ID①' ,
wecomSecret : '应用secret②' ,
wecomCId : '企业ID③' ,
} )
. then ( ( res ) => {
console . log ( res )
} )
. catch ( ( err ) => {
console . log ( err )
} )
.NET Core 版:
using System ;
using RestSharp ;
using Newtonsoft . Json ;
namespace WeCom . Demo
{
class WeCom
{
public string SendToWeCom (
string text , // 推送消息
string weComCId , // 企业Id①
string weComSecret , // 应用secret②
string weComAId , // 应用ID③
string weComTouId = "@all" )
{
// 获取Token
string getTokenUrl = $ "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid= { weComCId } &corpsecret= { weComSecret } " ;
string token = JsonConvert
. DeserializeObject < dynamic > ( new RestClient ( getTokenUrl )
. Get ( new RestRequest ( ) ) . Content ) . access_token ;
System . Console . WriteLine ( token ) ;
if ( ! String . IsNullOrWhiteSpace ( token ) )
{
var request = new RestRequest ( ) ;
var client = new RestClient ( $ "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token= { token } " ) ;
var data = new
{
touser = weComTouId ,
agentid = weComAId ,
msgtype = "text" ,
text = new
{
content = text
} ,
duplicate_check_interval = 600
} ;
string serJson = JsonConvert . SerializeObject ( data ) ;
System . Console . WriteLine ( serJson ) ;
request . Method = Method . POST ;
request . AddHeader ( "Accept" , "application/json" ) ;
request . Parameters . Clear ( ) ;
request . AddParameter ( "application/json" , serJson , ParameterType . RequestBody ) ;
return client . Execute ( request ) . Content ;
}
return "-1" ;
}
}
使用實例:
static void Main ( string [ ] args )
{ // 测试
Console . Write ( new WeCom ( ) . SendToWeCom (
"msginfo" ,
"企业Id①"
, "应用secret②" ,
"应用ID③"
) ) ;
}
}
其他版本的函數可參考上邊的邏輯自行編寫,歡迎PR。
傳送圖片、卡片、檔案或Markdown 訊息的進階用法請見企業微信API。