springboot集成微軟teams的實(shí)例代碼
前言
最近做了一個有關(guān)微軟的平臺teams開發(fā),在國內(nèi)用微軟teams聊天工具的少之又少,整個亞洲也沒什么開發(fā)的實(shí)例,官方文檔寫的有點(diǎn)亂,在沒有第三方支持下開發(fā)有點(diǎn)頭疼。需求是做一個管理后臺跟teams打通,支持各種通告發(fā)送,以及撤回。沒時間具體些,用的東西丟在上面用上的可以參考。
添加依賴
<dependency> <groupId>com.microsoft.graph</groupId> <artifactId>microsoft-graph</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>com.microsoft.graph</groupId> <artifactId>microsoft-graph-core</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>com.microsoft.graph</groupId> <artifactId>microsoft-graph-auth</artifactId> <version>0.3.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>msal4j</artifactId> <version>1.0.0</version> </dependency>
業(yè)務(wù)邏輯層
package com.tg.admin.service; import com.tg.admin.utils.CommonResult; import java.util.Map; /** * 用戶信息 * * @author summer.chou * @date 2020/11/26 */ public interface SplGraphService { /** * 獲取token(自動刷新) * * @return token */ String getToken(); * 獲取用戶所屬團(tuán)隊(duì) * @return 結(jié)果 CommonResult<Map<String, Object>> getTeamsInfo(); * 獲取用戶所屬渠道 * @param teamsId 團(tuán)隊(duì)ID CommonResult<Map<String, Object>> getChannel(String teamsId); * 根據(jù)teamsId、channelId獲取用戶信息 * @param teamsId 團(tuán)隊(duì)ID * @param channelId 渠道ID CommonResult<Map<String, Object>> getMember(String teamsId, String channelId); * 發(fā)送消息 * @param content 消息內(nèi)容 * @param teamId 團(tuán)隊(duì)ID CommonResult<Map<String, Object>> sendMs(String content, String teamId, String channelId); * 添加渠道 * @param displayName 渠道名稱 * @param description 渠道備注 * @param teamId 渠道ID * @return 渠道ID CommonResult<Map<String, Object>> addChannel(String displayName, String description, String teamId); * 添加成員 * @param userNum 用戶名稱 CommonResult<Map<String, Object>> addMembers(String teamId, String channelId, String userNum); }
業(yè)務(wù)邏輯實(shí)現(xiàn)
package com.tg.admin.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.microsoft.graph.models.extensions.IGraphServiceClient; import com.microsoft.graph.requests.extensions.GraphServiceClient; import com.tg.admin.service.ChannelUserLogService; import com.tg.admin.service.SplGraphService; import com.tg.admin.utils.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.List; import java.util.Map; /** * teams Graph模塊 第三方接口調(diào)用封裝 * * @author summer.chou * @date 2020/12/30 */ @Service @Slf4j public class SplGraphServiceImpl implements SplGraphService { @Value("#{'${teams.graph.scopes}'.split(',')}") private List<String> scopes; @Value("${teams.graph.clientId}") private String clientId; @Value("${teams.graph.team.url}") private String teamsUrl; @Value("${teams.graph.channel.url}") private String channelUrl; @Value("${teams.graph.add.channel.url}") private String addChannelUrl; @Value("${teams.graph.ms.url}") private String msUrl; @Value("${teams.graph.member.url}") private String memberUrl; @Value("${teams.graph.add.channel.members.url}") private String addChannelMembersUrl; @Value("${teams.graph.account}") private String account; @Value("${teams.graph.password}") private String password; private RedisUtil redisUtil; private RestTemplate restTemplate; private ChannelUserLogService channelUserLogService; public SplGraphServiceImpl(RestTemplate restTemplate, RedisUtil redisUtil, @Lazy ChannelUserLogService channelUserLogService) { this.restTemplate = restTemplate; this.redisUtil = redisUtil; this.channelUserLogService = channelUserLogService; } @Override public String getToken() { Object token = redisUtil.get(Constants.ADMIN_TOKEN_KEY + account); try { if (token == null) { MyAuthenticationProvider authProvider = new MyAuthenticationProvider(clientId, scopes, account, password); IGraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient(); graphClient.me().buildRequest().get(); token = authProvider.getToken(); redisUtil.set(Constants.ADMIN_TOKEN_KEY + account, token, Constants.TOKEN_EXPIRES_TIME); } } catch (Exception e) { log.info("獲取teams-graph,獲取token接口異常", e); } return token.toString(); public CommonResult<Map<String, Object>> getTeamsInfo() { JSONArray value = null; Map<String, Object> result = new HashMap<>(); JSONObject jsonObject = new JSONObject(); log.info("調(diào)用temas獲取團(tuán)隊(duì)信息:teamsUrl{}", teamsUrl); //設(shè)置請求頭 HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", getToken()); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); jsonObject = RestTemplateUtils.requestByGet(teamsUrl, null, restTemplate, headers); log.info("返回值:jsonObject:{}", jsonObject.toJSONString()); value = jsonObject.getJSONArray("value"); result.put("value", value); e.printStackTrace(); return CommonResult.ok(result); public CommonResult<Map<String, Object>> getChannel(String teamId) { JSONArray array = null; String url = channelUrl.replace("{team-id}", teamId); log.info("調(diào)用teams獲取用戶渠道url:{}", url); jsonObject = RestTemplateUtils.requestByGet(url, null, restTemplate, headers); log.info("返回結(jié)果:jsonObject:{}", jsonObject.toJSONString()); array = jsonObject.getJSONArray("value"); result.put("value", array); public CommonResult<Map<String, Object>> getMember(String teamsId, String channelId) { String url = memberUrl.replace("{team-id}", teamsId).replace("{channel-id}", channelId); log.info("調(diào)用teams獲取渠道成員:url:{}", url); public CommonResult<Map<String, Object>> sendMs(String content, String teamId, String channelId) { String url = msUrl.replace("{team-id}", teamId).replace("{channel-id}", channelId); log.info("調(diào)用teams發(fā)送消息:url:{}", url); Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<>(); map.put("content", content); map.put("contentType", "html"); body.put("body", map); jsonObject = RestTemplateUtils.requestByPost(url, body, restTemplate, headers); log.info("返回結(jié)果:jsonObject:{}", jsonObject.toJSONString()); return CommonResult.ok(); public CommonResult<Map<String, Object>> addChannel(String displayName, String description, String teamId) { String url = addChannelUrl.replace("{id}", teamId); log.info("調(diào)用teams添加渠道:url:{}", url); map.put("displayName", displayName); map.put("description", description); jsonObject = RestTemplateUtils.requestByPost(url, map, restTemplate, headers); if (jsonObject != null) { result.put("id", jsonObject.getString("id")); public CommonResult<Map<String, Object>> addMembers(String teamId, String channelId, String userNum) { String url = addChannelMembersUrl.replace("{team-id}", teamId).replace("{channel-id}", channelId); log.info("調(diào)用teams添加成員:url:{}", url); map.put("@odata.type", "#microsoft.graph.aadUserConversationMember"); JSONArray roles = new JSONArray(); roles.add("owner"); map.put("roles", roles); }
RestTemplateUtils 工具類
package com.tg.admin.utils; import com.alibaba.fastjson.JSONObject; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.HashMap; import java.util.Map; /** * RestTemplateUtils工具類 * * @author summer.chou * @date 2020/11/26 */ @Component public class RestTemplateUtils { /** * 根據(jù)get方式請求接口(復(fù)合類型get請求,支持所有g(shù)et請求) * * @param url 請求路勁 * @param map 請求參數(shù) 無傳null * @param restTemplate restTemplate對象 * @return json */ public static JSONObject requestByGet(String url, HashMap<String, Object> map, RestTemplate restTemplate, HttpHeaders headers) { // header填充 HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity(null, headers); UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); //ResponseEntity responseEntity; ResponseEntity<JSONObject> responseEntity; //如果存在參數(shù) if (map != null) { for (Map.Entry<String, Object> e : map.entrySet()) { //構(gòu)建查詢參數(shù) builder.queryParam(e.getKey(), e.getValue()); } //拼接好參數(shù)后的URl//test.com/url?param1={param1}¶m2={param2}; String reallyUrl = builder.build().toString(); responseEntity = restTemplate.exchange(reallyUrl, HttpMethod.GET, request, JSONObject.class); } else { responseEntity = restTemplate.exchange(url, HttpMethod.GET, request, JSONObject.class); } return responseEntity.getBody(); } /** * 根據(jù)Post方式請求接口(復(fù)合類型,post支持所有json格式傳參請求post請求) * * @param url 請求路徑 * @param map 請求參數(shù)(無參數(shù)傳null) * @param restTemplate restTemplate對象 * @return json */ public static JSONObject requestByPost(String url, Map<String, Object> map, RestTemplate restTemplate, HttpHeaders headers) { // header填充,map填充 HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map, headers); ResponseEntity<JSONObject> entity = restTemplate.postForEntity(url, request, JSONObject.class); return entity.getBody(); } }
測試接口
package com.tg.admin.controller; import com.tg.admin.service.SplGraphService; import com.tg.admin.utils.CommonResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; @Api(description = "teams-graph模塊(第三方測試接口)") @RestController @RequestMapping("/graph") @RefreshScope @Slf4j @Deprecated //添加過期注解,接口保留方便后期異常排查 public class GraphController { private SplGraphService tgService; public GraphController(SplGraphService tgService) { this.tgService = tgService; } @ApiOperation("獲取所屬團(tuán)隊(duì)信息") @GetMapping("/getTeamsInfo") public CommonResult getTeamsInfo() { return tgService.getTeamsInfo(); @ApiOperation("獲取token") @GetMapping("/getToken") public CommonResult getToken() { return CommonResult.ok(tgService.getToken()); @ApiOperation("獲取用戶所屬渠道") @ApiImplicitParams({ @ApiImplicitParam(name = "teamId", value = "團(tuán)隊(duì)Id", dataType = "string", required = true) }) @GetMapping("/getChannel") public CommonResult getChannel(@RequestParam(value = "teamId") String teamId) { return tgService.getChannel(teamId); @ApiOperation("獲取渠道下的成員") @ApiImplicitParam(name = "teamId", value = "團(tuán)隊(duì)Id", dataType = "string", required = true), @ApiImplicitParam(name = "channelId", value = "渠道Id", dataType = "string", required = true) @GetMapping("/getMember") public CommonResult getMember(@RequestParam(value = "teamId") String teamId, @RequestParam(value = "channelId") String channelId) { return tgService.getMember(teamId, channelId); @ApiOperation("創(chuàng)建團(tuán)隊(duì)下的渠道(備用接口)") @ApiImplicitParam(name = "displayName", value = "渠道名稱", dataType = "string", required = true), @ApiImplicitParam(name = "description", value = "渠道備注", dataType = "string", required = true) @PostMapping("/addChannel") public CommonResult addChannel(@RequestParam(value = "teamId") String teamId, @RequestParam(value = "displayName") String displayName, @RequestParam(value = "description") String description ) { return tgService.addChannel(displayName, description, teamId); @ApiOperation("向渠道里面添加成員(備用接口)") @ApiImplicitParam(name = "channelId", value = "渠道ID", dataType = "string", required = true), @ApiImplicitParam(name = "userNum", value = "用戶Id", dataType = "string", required = true) @PostMapping("/addMembers") public CommonResult addMembers(@RequestParam(value = "teamId") String teamId, @RequestParam(value = "channelId") String channelId, @RequestParam(value = "userNum") String userNum return tgService.addMembers(teamId, channelId, userNum); @ApiOperation("通過teamId,channelId發(fā)送消息") @PostMapping("/sendMs") @ApiImplicitParam(name = "content", value = "內(nèi)容", dataType = "string", required = true), public CommonResult sendMs(@RequestParam(value = "teamId") String teamId, @RequestParam(value = "content") String content, @RequestParam(value = "channelId") String channelId) { return tgService.sendMs(content, teamId, channelId); }
yml 配置
teams: graph: #微軟master賬號,密碼 account: 管理員賬號 password: 管理員密碼 add: channel: members: url: https://graph.microsoft.com/v1.0/teams/{team-id}/channels/{channel-id}/members url: https://graph.microsoft.com/v1.0/teams/{id}/channels channel: url: https://graph.microsoft.com/v1.0/teams/{team-id}/channels clientId: e730901a-8bf3-472b-93dd-afe79713bc5b member: url: https://graph.microsoft.com/v1.0/teams/{team-id}/channels/{channel-id}/members ms: url: https://graph.microsoft.com/v1.0/teams/{team-id}/channels/{channel-id}/messages scopes: Group.Read.All,User.Read team: url: https://graph.microsoft.com/v1.0/me/joinedTeams
到此這篇關(guān)于springboot集成微軟teams的文章就介紹到這了,更多相關(guān)springboot集成微軟teams內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
windows系統(tǒng)使用mvn命令打包并指定jdk路徑方式
這篇文章主要介紹了windows系統(tǒng)使用mvn命令打包并指定jdk路徑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04詳細(xì)總結(jié)Java for循環(huán)的那些坑
在平常寫代碼的過程中循環(huán)是不可避免的,雖然for的語法并不復(fù)雜,但是在開發(fā)中還是會遇到一些坑,雖然大部分的坑都是自己的騷操作導(dǎo)致的.今天來總結(jié)一下for循環(huán)在開發(fā)中可能遇到的坑,不要在同樣的問題上再次犯錯.需要的朋友可以參考下2021-05-05SpringBoot 如何實(shí)現(xiàn)異步編程
在SpringBoot的日常開發(fā)中,一般都是同步調(diào)用的,但實(shí)際中有很多場景非常適合使用異步來處理,本文就詳細(xì)的介紹一下SpringBoot 如何實(shí)現(xiàn)異步編程 ,具有一定的參考價值,感興趣的可以了解一下2021-12-12在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法
緩存是HTTP協(xié)議的一個強(qiáng)大功能,但由于某些原因,它主要用于靜態(tài)資源,如圖像,CSS樣式表或JavaScript文件。本文重點(diǎn)給大家介紹在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法,感興趣的朋友跟隨小編一起看看吧2018-10-10Java Spring動態(tài)生成Mysql存儲過程詳解
這篇文章主要介紹了Java Spring動態(tài)生成Mysql存儲過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06