如何通过IDaaS API同步用户到腾讯会议后台

2023-07-10 11:50:40 浏览数 (1)

大部分情况下,开发者集成腾讯会议SDK会选择会前会后页面使用API自定义实现,会中使用SDK自带页面的方式接入自己的APP。因此一个典型的腾讯会议SDK项目开发对接工作主要由通讯录对接(后台开发)、登录鉴权信息生成(后台开发)、SDK接入(客户端开发)、Rest API接入(后台开发)和Webhook接入(后台开发)几部分组成。本文将讲解如何进行通讯录对接开发,也就是IDaaS API接入。

IDaaS API官网文档:IDaaS开放平台通讯录API列表

在接入IDaaS API之前开发者需要了解以下信息:

1、 所有请求都是采用Bearer Token的鉴权方式

2、 请求返回成功的错误码并不都是200,具体要看每个接口的描述部分

3、 创建用户时需要有部门字段,如果不同步组织架构到腾讯会议,需要将用户都挂在默认的root部门下

4、 如果需要同步海外用户的手机号,需要和腾讯技术人员确认areaCode字段已经配置好

本文实现获取人员列表/创建人员/删除人员三个接口,将整体实现分为以下几个模块

1、 http请求实现:实现http请求的GET、POST和DELETE方法

2、 签名实现:对所有请求进行签名

3、 用户信息类:用于封装创建人员请求的body信息

4、 接口封装:提供获取人员列表/创建人员/删除人员三个接口

5、 对接信息配置:设置IDaaS API对接信息

具体实现如下(代码仅供参考)

1、 http请求实现

1.1 GET请求

代码语言:javascript复制
    public static String  doGet(String httpUrl, String auth, int okCode) {
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15秒
            conn.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60秒
            conn.setReadTimeout(60000);
            conn.setRequestProperty("Authorization", "Bearer "   auth);
            conn.connect();
            if (conn.getResponseCode() == okCode) {
                inputStream = conn.getInputStream();
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF_8));
                StringBuilder stringBuilder = new StringBuilder();
                String tmp;
                while ((tmp = bufferedReader.readLine()) != null) {
                    stringBuilder.append(tmp);
                    stringBuilder.append("rn");
                }
                result = stringBuilder.toString();
            } else {
                System.out.println("error:"   conn.getResponseCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != conn) {
                conn.disconnect();
            }
        }

        return result;
    }

1.2 POST请求

代码语言:javascript复制
    public static String doPost(String httpUrl, String auth, int okCode, String param) {

        HttpURLConnection conn = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15秒
            conn.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60秒
            conn.setReadTimeout(60000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "Bearer "   auth);
            outputStream = conn.getOutputStream();
            outputStream.write(param.getBytes());
            if (conn.getResponseCode() == okCode) {
                inputStream = conn.getInputStream();
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF_8));

                StringBuilder stringBuilder = new StringBuilder();
                String tmp;
                while ((tmp = bufferedReader.readLine()) != null) {
                    stringBuilder.append(tmp);
                    stringBuilder.append("rn");
                }
                result = stringBuilder.toString();
            } else {
                System.out.println("error:"   conn.getResponseCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != conn) {
                conn.disconnect();
            }
        }
        return result;
    }

1.3 DELETE请求

代码语言:javascript复制
    public static String  doDelete(String httpUrl, String auth, int okCode) {
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("DELETE");
            // 设置连接主机服务器的超时时间:15秒
            conn.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60秒
            conn.setReadTimeout(60000);
            conn.setRequestProperty("Authorization", "Bearer "   auth);
            conn.connect();
            if (conn.getResponseCode() == okCode) {
                inputStream = conn.getInputStream();
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF_8));
                StringBuilder stringBuilder = new StringBuilder();
                String tmp;
                while ((tmp = bufferedReader.readLine()) != null) {
                    stringBuilder.append(tmp);
                    stringBuilder.append("rn");
                }
                result = stringBuilder.toString();
            } else {
                System.out.println("error:"   conn.getResponseCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != conn) {
                conn.disconnect();
            }
        }

        return result;
    }

2、 签名实现

代码语言:javascript复制
public class SignUtil {
    public static String generateJWT(String kid, String serviceAccount) {
        try {
            //注意:这里获取到的时间戳需要是东8区的当前时间。
            long now = System.currentTimeMillis();
            JSONObject jwkJsonObj = JSON.parseObject(serviceAccount);
            String clientId = jwkJsonObj.getString("clientId");
            RSAPrivateKey privateKey = getPrivateKey(jwkJsonObj.getString("privateKey"));
            if (null == privateKey) {
                return null;
            }

            JWTClaimsSet.Builder claimsBuilder = new JWTClaimsSet.Builder()
                    .audience("contacts")
                    .expirationTime(new Date(now   600000))  //Token的过期时间,此处为10分钟。
                    .issueTime(new Date(now))
                    .issuer(clientId)
                    .claim("account_type","serviceAccount");
            JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.parse("RS256"))
                    .keyID(kid)
                    .type(JOSEObjectType.JWT)
                    .build();
            SignedJWT signedJWT = new SignedJWT(header, claimsBuilder.build());
            signedJWT.sign(new RSASSASigner(privateKey));
            return signedJWT.serialize();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {
        Object privateKeyObj = new JSONParser(JSONParser.USE_HI_PRECISION_FLOAT | JSONParser.ACCEPT_TAILLING_SPACE).parse(privateKey);
        if (privateKeyObj instanceof com.nimbusds.jose.shaded.json.JSONObject) {
            com.nimbusds.jose.shaded.json.JSONObject jwtObject = (com.nimbusds.jose.shaded.json.JSONObject) privateKeyObj;
            // Find the RSA signing key
            if (jwtObject.get("use").equals("sig") && jwtObject.get("kty").equals("RSA")) {
                return RSAKey.parse(jwtObject).toRSAPrivateKey();
            }
        }
        return null;
    }
}

3、 用户信息类

3.1 UserInfo.java

代码语言:javascript复制
public class UserInfo {
    @Expose
    @SerializedName("username")
    String username;

    @Expose
    @SerializedName("displayName")
    String displayName;

    @Expose
    @SerializedName("primaryMail")
    String primaryMail;

    @Expose
    @SerializedName("secondaryMail")
    String secondaryMail;

    @Expose
    @SerializedName("deptId")
    String deptId;

    @Expose
    @SerializedName("phoneNum")
    String phoneNum;

    @Expose
    @SerializedName("employeeNumber")
    String employeeNumber;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public void setPrimaryMail(String primaryMail) {
        this.primaryMail = primaryMail;
    }

    public void setSecondaryMail(String secondaryMail) {
        this.secondaryMail = secondaryMail;
    }

    public void setDeptId(String deptId) {
        this.deptId = deptId;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public void setEmployeeNumber(String employeeNumber) {
        this.employeeNumber = employeeNumber;
    }

}

3.2 CreateUserRequest.java

代码语言:javascript复制
public class CreateUserRequest {

    @Expose
    @SerializedName("values")
    UserInfo values;

    public CreateUserRequest() {
        values = new UserInfo();
    }

    public void setUsername(String username) {
        this.values.username = username;
    }

    public void setDisplayName(String displayName) {
        this.values.displayName = displayName;
    }

    public void setPrimaryMail(String primaryMail) {
        this.values.primaryMail = primaryMail;
    }

    public void setSecondaryMail(String secondaryMail) {
        this.values.secondaryMail = secondaryMail;
    }

    public void setDeptId(String deptId) {
        this.values.deptId = deptId;
    }

    public void setPhoneNum(String phoneNum) {
        this.values.phoneNum = phoneNum;
    }

    public void setEmployeeNumber(String employeeNumber) {
        this.values.employeeNumber = employeeNumber;
    }

}

4、 接口封装

代码语言:javascript复制
public class IdaasApi {

    public static void main(String[] args) {
        String result;

        //获取人员列表
        result = getUserList();
        System.out.println(result);

        //创建人员
		CreateUserRequest user = new CreateUserRequest();
		user.setUsername("");
		user.setDisplayName("");
		user.setPrimaryMail("");
		user.setDeptId("");
		result = createUser(user);
		System.out.println(result);

        //删除人员
        result = deleteUser("");
        System.out.println(result);

    }

    public static String getUserList() {
        String jwtToken = generateJWT(IdaasApiConfig.kid, IdaasApiConfig.serviceAccount);
        String result;

        //获取人员列表
        result = HttpClient.doGet(IdaasApiConfig.httpUrl   "/api/v1/users", jwtToken, 200);
        return result;
    }

    public static String deleteUser(String userId) {
        String jwtToken = generateJWT(IdaasApiConfig.kid, IdaasApiConfig.serviceAccount);
        String result = HttpClient.doDelete(IdaasApiConfig.httpUrl   "/api/v1/users/"   userId, jwtToken, 204);
        return result;
    }

    public static String createUser(CreateUserRequest request) {
        String jwtToken = generateJWT(IdaasApiConfig.kid, IdaasApiConfig.serviceAccount);
        String body = JSON.toJSONString(request);
        //System.out.println(body);
        String result = HttpClient.doPost(IdaasApiConfig.httpUrl   "/api/v1/users", jwtToken, 201, body);
        return result;
    }
}

5、 对接信息配置

代码语言:javascript复制
public class IdaasApiConfig {
    public static final String httpUrl = "https://test-admin.id.meeting.qq.com/contacts";
    //获取kid方式:ServiceAccount中的privateKey的kid
    public static final String kid = "";
    public static final String serviceAccount = "";
}

本文源码下载:

idaasapi.zip

0 人点赞