b2b網(wǎng)站平臺大全微信指數(shù)查詢
說明
企業(yè)微信官方提供的均為API接口,沒有提供集成SDK。因此無需引入Maven依賴,直接以Https
方式請求即可。
有些第三方提供了集成的Java SDK,可根據(jù)需求自行選用。
本文采用直接調(diào)用官方API的方式。
基礎(chǔ)配置
企業(yè)微信注冊后,可得到corpId
、agentId
、corpSecret
的信息。
而企業(yè)微信的所有接口均以https://qyapi.weixin.qq.com/cgi-bin
開頭。
綜上,在yml中定義配置:
qywx:endpoint: https://qyapi.weixin.qq.com/cgi-bincorpId: wx00000000000000baagentId: 1000000corpSecret: V0000000000_00000000000000000000000000000wc
然后定義一個配置類:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;@Component
@Configuration
@ConfigurationProperties(prefix = QywxConfig.prefix)
@Data
public class QywxConfig {public final static String prefix = "qywx";/*** 企業(yè)微信請求地址*/private String endpoint;/*** 企業(yè)id*/private String corpId;private String agentId;private String corpSecret;
}
這樣即可在容器類中引用配置。
發(fā)送請求
服務(wù)端需要向企業(yè)微信發(fā)送請求。這里使用Forest
來進(jìn)行請求。
首先引入依賴:
<!-- forest -->
<dependency><groupId>com.dtflys.forest</groupId><artifactId>forest-spring-boot-starter</artifactId><version>1.5.32</version>
</dependency>
考慮到所有的請求都需拼接共同的企業(yè)微信請求地址,因此為Forest
添加攔截器來統(tǒng)一處理:
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.interceptor.Interceptor;
import com.dtflys.forest.reflection.ForestMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class QywxForestInterceptor implements Interceptor<String> {@Autowiredprivate QywxConfig qywxConfig;@Overridepublic void onInvokeMethod(ForestRequest req, ForestMethod method, Object[] args) {req.setBasePath(qywxConfig.getEndpoint());}
}
然后定義請求的接口類:
import com.cosmoplat.hyida.core.result.Result;
import com.cosmoplat.qingyin.safety.qywx.controller.model.dto.MessageTextDto;
import com.cosmoplat.qingyin.safety.qywx.controller.model.dto.QyWxUserDetailDto;
import com.cosmoplat.qingyin.safety.qywx.inteceptor.SafetyForestInterceptor;
import com.dtflys.forest.annotation.*;import java.util.Map;@BaseRequest(interceptor = QywxForestInterceptor.class, headers = {"Accept: */*", "Content-Type: application/json"})
public interface QywxForestClient {/*** 獲取access_token* @param corpId* @param corpSecret* @return*/@Get(url = "/gettoken?corpid={corpId}&corpsecret={corpSecret}")Map<String,Object> getToken(@Var("corpId") String corpId, @Var("corpSecret") String corpSecret);}
當(dāng)調(diào)用時,引入QywxConfig
和QywxForestClient
:
@Resource
private QywxConfig qywxConfig;@Resource
private QywxForestClient qywxForestClient;private String getAccessToken() {// 根據(jù)corpId和corpSecret獲取 access_tokenString corpId = qywxConfig.getCorpId();String corpSecret = qywxConfig.getCorpSecret();Map<String, Object> tokenResult = qywxForestClient.getToken(corpId, corpSecret);if (!result.get("errcode").equals(0) || StringUtils.isEmpty(result.get("access_token"))) {System.out.println("獲取企業(yè)微信access_token失敗!" + result.get("errmsg")); }return String.valueOf(result.get("access_token"));
}
關(guān)于access_token
access_token
的官方文檔地址:
https://developer.work.weixin.qq.com/document/path/91039
里面明確提到了3個注意事項(xiàng):
- 為了安全考慮,開發(fā)者 請勿 將 access_token 返回給前端,需要開發(fā)者保存在后臺,所有訪問企業(yè)微信api的請求由后臺發(fā)起。
- 開發(fā)者需要緩存access_token,用于后續(xù)接口的調(diào)用(注意:不能頻繁調(diào)用gettoken接口,否則會受到頻率攔截)。當(dāng)access_token失效或過期時,需要重新獲取。
- access_token的有效期通過返回的expires_in來傳達(dá),正常情況下為7200秒(2小時),有效期內(nèi)重復(fù)獲取返回相同結(jié)果,過期后獲取會返回新的access_token。
因此,最佳實(shí)踐應(yīng)使用Redis緩存access_token
。當(dāng)獲取access_token
時先從Redis中取。若取不到,則向企業(yè)微信發(fā)起請求獲取,并寫入到Redis中。
攜帶參數(shù)
以發(fā)送應(yīng)用消息為例,現(xiàn)在要發(fā)送一個文本消息。
參考官方文檔:
請求方式:POST(HTTPS)
請求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN
參數(shù)示例為:
{"touser" : "UserID1|UserID2|UserID3","toparty" : "PartyID1|PartyID2","totag" : "TagID1 | TagID2","msgtype" : "text","agentid" : 1,"text" : {"content" : "你的快遞已到,請攜帶工卡前往郵件中心領(lǐng)取。\n出發(fā)前可查看<a href=\"http://work.weixin.qq.com\">郵件中心視頻實(shí)況</a>,聰明避開排隊(duì)。"},"safe":0,"enable_id_trans": 0,"enable_duplicate_check": 0,"duplicate_check_interval": 1800
}
返回示例為:
{"errcode" : 0,"errmsg" : "ok","invaliduser" : "userid1|userid2","invalidparty" : "partyid1|partyid2","invalidtag": "tagid1|tagid2","unlicenseduser" : "userid3|userid4","msgid": "xxxx","response_code": "xyzxyz"
}
現(xiàn)在根據(jù)文檔的信息來添加接口。
首先定義一個MessageTextDto
對象來承載發(fā)送時的參數(shù)。其中text
屬性又是一個對象。
import io.swagger.annotations.ApiModel;
import lombok.Data;@Data
public class MessageTextDto {/*** 指定接收消息的成員,成員ID列表(多個接收者用‘|’分隔,最多支持1000個)。* 特殊情況:指定為"@all",則向該企業(yè)應(yīng)用的全部成員發(fā)送*/private String touser;/*** 指定接收消息的部門,部門ID列表,多個接收者用‘|’分隔,最多支持100個。* 當(dāng)touser為"@all"時忽略本參數(shù)*/private String toparty;/*** 指定接收消息的標(biāo)簽,標(biāo)簽ID列表,多個接收者用‘|’分隔,最多支持100個。* 當(dāng)touser為"@all"時忽略本參數(shù)*/private String totag;/*** 消息類型,此時固定為:text* 必填*/private String msgtype = "text";/*** 企業(yè)應(yīng)用的id,整型。企業(yè)內(nèi)部開發(fā),可在應(yīng)用的設(shè)置頁面查看;第三方服務(wù)商,可通過接口 獲取企業(yè)授權(quán)信息 獲取該參數(shù)值* 必填*/private String agentid;/*** 消息內(nèi)容,最長不超過2048個字節(jié),超過將截斷(支持id轉(zhuǎn)譯)* 必填*/private MessageText text = new MessageText();/*** 表示是否是保密消息,0表示可對外分享,1表示不能分享且內(nèi)容顯示水印,默認(rèn)為0*/private String safe;/*** 表示是否開啟id轉(zhuǎn)譯,0表示否,1表示是,默認(rèn)0。僅第三方應(yīng)用需要用到,企業(yè)自建應(yīng)用可以忽略。*/private String enable_id_trans;/*** 表示是否開啟重復(fù)消息檢查,0表示否,1表示是,默認(rèn)0*/private String enable_duplicate_check;/*** 表示是否重復(fù)消息檢查的時間間隔,默認(rèn)1800s,最大不超過4小時*/private String duplicate_check_interval;
}
MessageText
對象:
import lombok.Data;@Data
public class MessageText {/*** 消息內(nèi)容,最長不超過2048個字節(jié),超過將截斷(支持id轉(zhuǎn)譯)* 必填*/private String content;
}
然后在QywxForestClient
中添加接口:
@BaseRequest(interceptor = QywxForestInterceptor.class, headers = {"Accept: */*", "Content-Type: application/json"})
public interface QywxForestClient {/*** 獲取訪問用戶敏感信息* @param messageTextDto* @param accessToken* @return*/@Post(url = "/message/send?access_token={accessToken}")Map<String, Object> messageSend(@Body MessageTextDto messageTextDto, @Var("accessToken") String accessToken);
}
這樣即可進(jìn)行調(diào)用:
private Map<String, Object> sendMessage(String touser, String content) {if (StrUtil.isEmpty(touser)) {// 消息接收者為空return Maps.newHashMap();}MessageTextDto messageTextDto = new MessageTextDto();messageTextDto.setAgentid(safetyConfig.getAgentId());messageTextDto.setTouser(touser);messageTextDto.getText().setContent(content);String accessToken = getAccessToken();Map<String, Object> result = qywxForestClient.messageSend(messageTextDto, accessToken);return result;
}
其中getAccessToken()
調(diào)用了前面封裝的getAccessToken
方法。