Documento de interfaz oficial->
El lenguaje Go implementa el SDK WeChat empresarial, un SDK práctico de Work Weixin para Go.
El SDK está organizado desde la perspectiva de proveedores de servicios externos, integrando SDK de aplicaciones de terceros y SDK desarrollados por aplicaciones de creación propia. Admite la generación de nuevos códigos SDK con un solo clic, es fácil de usar y flexible para expandirse. .
Haga clic para ver la publicación del blog sobre desarrollo de aplicaciones de terceros de Enterprise WeChat
go get github.com/zsmhub/workweixin
需手动格式化代码;企微页面调整后一键生成代码可能失效
)Generar código de evento de devolución de llamada de Qiwei
make callback doc=企微文档链接 [prefix =生成文件名前缀]
# example
make callback doc=https://developer.work.weixin.qq.com/document/path/92277 prefix=客户联系
Consejo: si encuentra que callbacks/callback_constant.go no tiene una definición constante para este evento de devolución de llamada, debe completarla manualmente.
Generar código API de Qiwei
make api doc=企微文档链接 [prefix =生成文件名前缀]
# example
make api doc=https://developer.work.weixin.qq.com/document/path/90600 prefix=应用授权
consejo:
- Genere una interfaz GET. El tipo de datos de los parámetros de solicitud debe ajustarse manualmente.
- Ejemplo json de solicitud/respuesta de algunos documentos de interfaz. Si faltan algunos campos, deben completarse manualmente.
- Algunas páginas complejas requieren la organización manual del SDK, como la interfaz de mensaje push > enviar mensaje de la aplicación.
¡Se recomienda encarecidamente ir a la carpeta ./demo para ver el ejemplo completo!
Haga clic para ver la demostración completa
// 企微回调设置初始化
func InitCallbackHandler () error {
// 服务商回调解析
if err := workweixin . Sdk . NewProviderCallbackHandler ( config . CorpCallbackToken , config . CorpCallbackEncodingAESKey ); err != nil {
return err
}
// 第三方应用回调解析【可选】
if err := workweixin . Sdk . NewThirdAppCallbackHandler ( config . AppSuiteCallbackToken , config . AppSuiteCallbackEncodingAESKey ); err != nil {
return err
}
// 第三方小程序回调解析【可选】
if err := workweixin . Sdk . NewMiniSuiteCaNewThirdMiniCallbackHandlerllbackHandler ( config . MiniSuiteCallbackToken , config . MiniSuiteCallbackEncodingAESKey ); err != nil {
return err
}
// 自建应用代开发回调解析【可选】
if err := workweixin . Sdk . NewCustomizedTemplateCallbackHandler ( config . CustomizedCallbackToken , config . CustomizedCallbackEncodingAESKey ); err != nil {
return err
}
return nil
}
// 服务商-解析并获取回调信息
workweixin . Sdk . ProviderCallback . GetCallBackMsg ( r * http . Request )
// 第三方应用-解析并获取回调信息
workweixin . Sdk . ThirdAppCallback . GetCallBackMsg ( r * http . Request )
// 第三方小程序-解析并获取回调信息
workweixin . Sdk . ThirdMiniCallback . GetCallBackMsg ( r * http . Request )
// 自建应用代开发--解析并获取回调信息
workweixin . Sdk . CustomizedTemplateCallback . GetCallBackMsg ( r * http . Request )
// 第三方应用回调完整示例
func HandleAppPostRequest ( c echo. Context ) error {
msg , err := workweixin . Sdk . ThirdAppCallback . GetCallBackMsg ( c . Request ())
if err != nil {
return err
}
switch msg . MsgType {
case callbacks . MessageTypeThird : // 第三方应用回调
switch msg . EventType {
// 推送suite_ticket,每十分钟推送一次suite_ticket
case callbacks . InfoTypeSuiteTicket :
extras , ok := msg . Extras .(callbacks. ThirdSuiteTicket )
if ! ok {
return errors . New ( "suite_ticket get failed" )
}
ticket := extras . SuiteTicket . Text
workweixin . Sdk . ThirdAppClient . RefreshSuiteTicket ( ticket , time . Hour )
// todo: 此处可将 suite_ticket 保存进数据库
// 企业取消授权通知
case callbacks . InfoTypeCancelAuth :
workweixin . Sdk . RemoveThirdAuthCorp ( corpId )
}
}
return nil
}
import "xxx/workweixin/demo"
// 企微API客户端初始化
func InitApiHandler () error {
// 初始化企微sdk参数
workweixin . Sdk . InitOptions (apis. Options {
DcsToken : demo. DcsTokenByRedis {},
DcsAppSuiteTicket : demo. DcsAppSuiteTicketByRedis {},
GetThirdAppAuthCorpFunc : demo . GetThirdAppAuthCorpToSdk ,
GetCustomizedAppAuthCorpFunc : demo . GetCustomizedAppAuthCorpToSdk ,
Logger : demo. Logger {},
})
// 服务商API客户端初始化
workweixin . Sdk . NewProviderApiClient ( config . CorpId , config . CorpProviderSecret )
// 第三方应用API客户端初始化【可选】
suiteTicket := dao . ConfigDao . GetByUniqueIndex ( global . ConfigKeySuiteTicket )
workweixin . Sdk . NewThirdAppApiClient ( config . CorpId , config . AppSuiteId , config . AppSuiteSecret , suiteTicket . V )
// 自建应用代开发API客户端初始化【可选】
customizedTicket := dao . ConfigDao . GetByUniqueIndex ( global . ConfigKeyCustomizedTicket )
workweixin . Sdk . NewCustomizedApiClient ( config . CorpId , config . CustomizedAppSuiteId , config . CustomizedAppSuiteSecret , customizedTicket . V )
// 由于本地开发环境和预发布无法接收企微回调事件,故需定时刷新suite_ticket
if config . IsLocal () || config . IsUat () {
go func ( suiteTicket , customizedTicket model. Config ) {
defer recover ()
ticker := time . NewTicker ( 10 * time . Minute )
defer ticker . Stop ()
for {
// 更新第三方应用ticket
_ = suiteTicket . DelCache () // 清除本地缓存
suiteTicket = dao . ConfigDao . GetByUniqueIndex ( global . ConfigKeySuiteTicket )
workweixin . Sdk . ThirdAppClient . RefreshSuiteTicket ( suiteTicket . V , 30 * time . Minute )
// 更新自建应用代开发ticket
_ = customizedTicket . DelCache () // 清除本地缓存
customizedTicket = dao . ConfigDao . GetByUniqueIndex ( global . ConfigKeyCustomizedTicket )
workweixin . Sdk . CustomizedAppClient . RefreshSuiteTicket ( customizedTicket . V , 30 * time . Minute )
<- ticker . C
}
}( suiteTicket , customizedTicket )
}
return nil
}
// 服务商级别API调用接口示例:获取接口调用许可订单详情
orderDetail , err := workweixin . Sdk . ProviderClient . ExecGetOrderLicense (apis. ReqGetOrderLicense { OrderID : orderId })
// 应用级别API调用接口示例:获取企业永久授权码
resp , err := workweixin . Sdk . ThirdAppClient . ExecGetPermanentCodeService (apis. ReqGetPermanentCodeService { AuthCode : authCode })
// 授权企业级别API调用接口示例:获取部门列表
apiClient , err := workweixin . Sdk . GetThirdAuthCorpApiClient ( v . CorpId )
if err != nil {
fmt . Println ( err )
}
department , err := apiClient . ExecListDepartment (apis. ReqListDepartment {})
// 获取provider_access_token
accessToken , err := workweixin . Sdk . ProviderClient . GetToken ()
// 获取suite_access_token
accessToken , err := workweixin . Sdk . ThirdAppClient . GetToken ()
// 获取授权企业access_token
accessToken , err := apiClient . GetToken ()
// 构造oauth2链接
oauthUrl := workweixin . Sdk . ThirdAppClient . GetThirdOauthUrl (apis. GetThirdOauthUrlReq {
RedirectUri : "xxx" ,
Scope : "xx" ,
State : "xx" ,
})
// 企微 error code 类型强制转换
if err != nil {
if apiError , ok := err .( * apis. ClientError ); ok && apiError . Code == apis . ErrCode60011 {
return errors . New ( "无权限访问" )
}
return nil , err
}
// 推送消息到第三方应用
reqSentMessageCard := apis. ReqSentMessageCard {
ToUser : v . InstallUserId ,
MsgType : "news" ,
AgentId : v . AgentId ,
News : apis. ReqSentMessageCardNewsBody {
Articles : []apis. ReqSentMessageCardNewsArticleBody {
{
Title : "新模块【xxx】已上线" ,
Description : "快进入【管理后台】把它配置到你的【侧边栏】中!" ,
Url : "https://xxx" ,
UrlImg : "https://xxx/workbench-config.jpg" ,
},
},
},
}
if _ , err = apiClient . ExecSentMessageCard ( reqSentMessageCard ); err != nil {
fmt . Println ( err )
}
// 帮前端获取 wx.config/wx.agentConfig 的签名配置
// 步骤1:获取授权企业的jsapi_ticket,wx.config注入的是企业的身份与权限,而wx.agentConfig注入的是应用的身份与权限
// 步骤2:JS-SDK使用权限签名算法
type QyapiGetJssdkConfigResp struct {
CorpJsapiTicket apis. GetJsSdkSignResp `json:"corp_jsapi_ticket"`
AppJsapiTicket apis. GetJsSdkSignResp `json:"app_jsapi_ticket"`
}
func ( qyapiRepo ) GetJssdkConfig ( req form. QyapiGetJssdkConfigReq ) ( * QyapiGetJssdkConfigResp , error ) {
apiClient , err := workweixin . Sdk . GetThirdAuthCorpApiClient ( req . CorpId )
if err != nil {
return nil , err
}
corpTicket , err := apiClient . GetJSAPITicket ()
if err != nil {
return nil , err
}
appTicket , err := apiClient . GetJSAPITicketAgentConfig ()
if err != nil {
return nil , err
}
agentId := apiClient . AgentId
return & QyapiGetJssdkConfigResp {
CorpJsapiTicket : apiClient . GetJsSdkSign ( req . CorpId , req . Url , corpTicket , 0 ),
AppJsapiTicket : apiClient . GetJsSdkSign ( req . CorpId , req . Url , appTicket , agentId ),
}, nil
}
.
├── api_generate 一键生成企微API代码
├── apis 企业微信API整合
│ └── api.error.go 全局错误码
├── callback_generate 一键生成企微回调事件代码
├── callbacks 企业微信回调事件整合
│ └── callback_constant.go 回调事件常量定义
├── demo sdk调用示例
├── docs 企业微信相关文档
├── internal 消息加解密库
└── main.go 入口文件