diff --git a/integrations/pom.xml b/integrations/pom.xml
index 84c30ba..b9ef8bd 100644
--- a/integrations/pom.xml
+++ b/integrations/pom.xml
@@ -39,6 +39,7 @@
sample-integrations
ping
msc-integration
+ wp-integration
diff --git a/integrations/wp-integration/pom.xml b/integrations/wp-integration/pom.xml
new file mode 100644
index 0000000..42f0ee0
--- /dev/null
+++ b/integrations/wp-integration/pom.xml
@@ -0,0 +1,53 @@
+
+
+
+ beaver-iot-integrations
+ com.milesight.beaveriot
+ 1.0.0
+ ../../pom.xml
+
+ 4.0.0
+
+ wp-integration
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.milesight.beaveriot
+ context
+ ${project.version}
+ provided
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+ cn.hutool
+ hutool-all
+ 5.8.20
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+ org.springframework.boot
+ spring-boot-actuator
+ 3.3.4
+ compile
+
+
+ com.milesight.beaveriot
+ entity-service
+
+
+
\ No newline at end of file
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/WpIntegrationBootstrap.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/WpIntegrationBootstrap.java
new file mode 100644
index 0000000..eb6d409
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/WpIntegrationBootstrap.java
@@ -0,0 +1,33 @@
+package com.milesight.beaveriot.integration.wp;
+
+import com.milesight.beaveriot.context.integration.bootstrap.IntegrationBootstrap;
+import com.milesight.beaveriot.context.integration.model.Integration;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.camel.CamelContext;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class WpIntegrationBootstrap implements IntegrationBootstrap {
+
+
+ @Override
+ public void onPrepared(Integration integrationConfig) {
+
+ }
+
+ @Override
+ public void onStarted(Integration integrationConfig) {
+ log.info("WP integration started");
+ }
+
+ @Override
+ public void onDestroy(Integration integrationConfig) {
+ log.info("WP integration stopping");
+ }
+
+ @Override
+ public void customizeRoute(CamelContext context) throws Exception {
+ IntegrationBootstrap.super.customizeRoute(context);
+ }
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/constant/WpIntegrationConstants.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/constant/WpIntegrationConstants.java
new file mode 100644
index 0000000..9e79dbb
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/constant/WpIntegrationConstants.java
@@ -0,0 +1,39 @@
+package com.milesight.beaveriot.integration.wp.constant;
+
+import com.milesight.beaveriot.base.utils.StringUtils;
+
+public interface WpIntegrationConstants {
+
+ String INTEGRATION_IDENTIFIER = "wp-integration";
+
+ public static String getKey(String propertyKey) {
+ return WpIntegrationConstants.INTEGRATION_IDENTIFIER + ".integration." + StringUtils.toSnakeCase(propertyKey);
+ }
+
+ interface DeviceAdditionalDataName {
+
+ String DEVICE_ID = "id";
+
+ }
+
+ interface InternalPropertyIdentifier {
+
+ interface Pattern {
+ String PREFIX = "_#";
+ String SUFFIX = "#_";
+ String TEMPLATE = "_#%s#_";
+
+ static boolean match(String key) {
+ return key.startsWith(PREFIX) && key.endsWith(SUFFIX);
+ }
+ }
+
+ String LAST_SYNC_TIME = "_#last_sync_time#_";
+
+ static String getLastSyncTimeKey(String deviceKey) {
+ return String.format("%s.%s", deviceKey, LAST_SYNC_TIME);
+ }
+
+ }
+
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/controller/WpController.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/controller/WpController.java
new file mode 100644
index 0000000..54bede3
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/controller/WpController.java
@@ -0,0 +1,32 @@
+package com.milesight.beaveriot.integration.wp.controller;
+
+import com.milesight.beaveriot.base.response.ResponseBody;
+import com.milesight.beaveriot.base.response.ResponseBuilder;
+import com.milesight.beaveriot.integration.wp.model.WpMeetingRequest;
+import com.milesight.beaveriot.integration.wp.model.WpMeetingResponse;
+import com.milesight.beaveriot.integration.wp.service.WpMeetingRoomService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ */
+@Slf4j
+@RestController
+@RequestMapping("/meeting")
+public class WpController {
+
+
+ @Autowired
+ private WpMeetingRoomService wpMeetingRoomService;
+
+ @PostMapping
+ public ResponseBody addMeeting(@RequestBody WpMeetingRequest wpMeetingRequest) {
+ return ResponseBuilder.success(wpMeetingRoomService.addMeetingRoom(wpMeetingRequest, null));
+ }
+
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/entity/WpIntegrationEntities.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/entity/WpIntegrationEntities.java
new file mode 100644
index 0000000..be1266a
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/entity/WpIntegrationEntities.java
@@ -0,0 +1,92 @@
+package com.milesight.beaveriot.integration.wp.entity;
+
+import com.milesight.beaveriot.context.integration.context.AddDeviceAware;
+import com.milesight.beaveriot.context.integration.context.DeleteDeviceAware;
+import com.milesight.beaveriot.context.integration.entity.annotation.Attribute;
+import com.milesight.beaveriot.context.integration.entity.annotation.Entities;
+import com.milesight.beaveriot.context.integration.entity.annotation.Entity;
+import com.milesight.beaveriot.context.integration.entity.annotation.IntegrationEntities;
+import com.milesight.beaveriot.context.integration.enums.EntityType;
+import com.milesight.beaveriot.context.integration.model.ExchangePayload;
+import lombok.*;
+import lombok.experimental.FieldNameConstants;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@IntegrationEntities
+public class WpIntegrationEntities extends ExchangePayload {
+
+ @Entity(type = EntityType.SERVICE, identifier = "add_device")
+ private AddDevice addDevice;
+
+ @Entity(type = EntityType.SERVICE)
+ private SyncDevice syncDevice;
+
+ @Entity(type = EntityType.SERVICE, identifier = "delete_device")
+ private DeleteDevice deleteDevice;
+
+
+ @Entity
+ private Openapi openapi;
+
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ @Entities
+ public static class DetectReport extends ExchangePayload {
+ // Entity type inherits from parent entity (DetectReport)
+ @Entity
+ private Long consumedTime;
+
+ @Entity
+ private Long onlineCount;
+
+ @Entity
+ private Long offlineCount;
+ }
+
+ @FieldNameConstants
+ @EqualsAndHashCode(callSuper = true)
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @Entities
+ public static class Openapi extends ExchangePayload {
+
+ @Entity(attributes = {@Attribute(minLength = 1)})
+ private String username;
+
+ @Entity(attributes = {@Attribute(minLength = 1)})
+ private String password;
+
+ }
+
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ @Entities
+ public static class AddDevice extends ExchangePayload implements AddDeviceAware {
+
+ @Entity(attributes = {@Attribute(min = 1, max = 999)})
+ private Integer memberCapacity;
+
+ }
+
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ @Entities
+ public static class DeleteDevice extends ExchangePayload implements DeleteDeviceAware {
+ }
+
+ public enum DetectStatus {
+ STANDBY, DETECTING;
+ }
+
+ @EqualsAndHashCode(callSuper = true)
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @Entities
+ public static class SyncDevice extends ExchangePayload {
+
+ }
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeeting.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeeting.java
new file mode 100644
index 0000000..04b4162
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeeting.java
@@ -0,0 +1,60 @@
+package com.milesight.beaveriot.integration.wp.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WpMeeting {
+// "schedule": {
+// "conferenceRecordId": 245698,
+// "startTime": 1732710600,
+// "endTime": 1732716000,
+// "originalStartTime": 1732710600,
+// "originalEndTime": 1732716000,
+// "allowCheckIn": false,
+// "shouldCheckIn": false,
+// "allowCheckOut": false,
+// "status": "NOT_STARTED",
+// "subject": "图像会议室的预约",
+// "meetingRoomName": "图像会议室",
+// "meetingRoomId": 2551,
+// "meetingRoomType": "common",
+// "buildingId": 1300,
+// "floorId": 2210,
+// "conferenceId": 249275,
+// "host": {
+// "memberId": 73825,
+// "name": "test",
+// "email": "linzy@milesight.com",
+// "role": "HOST",
+// "isResource": false,
+// "accessibleRealSchedule": false,
+// "userId": 78902,
+// "hasCheckined": false
+// },
+// "notificationTime": 15,
+// "willStartReminderMinutes": [
+// 15
+// ],
+// "scheduleType": "CONFERENCE",
+// "canBeExtended": false,
+// "roomExpired": false,
+// "checkInStatistics": false
+// },
+
+ private Integer conferenceRecordId;
+ private String subject;
+ private String meetingRoomName;
+ private String meetingRoomId;
+ private String meetingId;
+ private String firstStartTime;
+ private String lastEndTime;
+ private Long createTime;
+ private String startDate;
+ private String startTime;
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingRequest.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingRequest.java
new file mode 100644
index 0000000..f533b54
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingRequest.java
@@ -0,0 +1,59 @@
+package com.milesight.beaveriot.integration.wp.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WpMeetingRequest {
+// "schedule": {
+// "conferenceRecordId": 245698,
+// "startTime": 1732710600,
+// "endTime": 1732716000,
+// "originalStartTime": 1732710600,
+// "originalEndTime": 1732716000,
+// "allowCheckIn": false,
+// "shouldCheckIn": false,
+// "allowCheckOut": false,
+// "status": "NOT_STARTED",
+// "subject": "图像会议室的预约",
+// "meetingRoomName": "图像会议室",
+// "meetingRoomId": 2551,
+// "meetingRoomType": "common",
+// "buildingId": 1300,
+// "floorId": 2210,
+// "conferenceId": 249275,
+// "host": {
+// "memberId": 73825,
+// "name": "test",
+// "email": "linzy@milesight.com",
+// "role": "HOST",
+// "isResource": false,
+// "accessibleRealSchedule": false,
+// "userId": 78902,
+// "hasCheckined": false
+// },
+// "notificationTime": 15,
+// "willStartReminderMinutes": [
+// 15
+// ],
+// "scheduleType": "CONFERENCE",
+// "canBeExtended": false,
+// "roomExpired": false,
+// "checkInStatistics": false
+// },
+
+ private Integer type;
+ private String meeting;
+ private String id;
+ private String key;
+ private String subject;
+ private String first;
+ private String last;
+ private String date;
+ private String time;
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingResponse.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingResponse.java
new file mode 100644
index 0000000..2dd7650
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpMeetingResponse.java
@@ -0,0 +1,20 @@
+package com.milesight.beaveriot.integration.wp.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WpMeetingResponse {
+// {"data":{"id":249376,"subject":"111","scheduleSetting":{"startTime":"01:00","duration":30,"notificationTime":15,"willStartReminderMinutes":[15],"scheduleMode":"ONCE","simpleRepeatType":"NEVER","startDate":"2024-11-28","syncToThirdParty":true,"timezone":"UTC+8 Asia/Shanghai","enableDst":true,"firstStartTime":1732726800,"lastEndTime":1732730400},"host":{"memberId":73825,"name":"test","email":"linzy@milesight.com","role":"HOST","isResource":false,"accessibleRealSchedule":false,"userId":78902},"participants":[],"meetingRoom":{"id":2566,"name":"111","buildingName":"test","connected":false,"expired":false,"type":"common","buildingId":1300,"meetingRoomSettings":{"id":2512,"meetingRoomId":2566,"enterpriseId":101741,"restrictInWorkingHours":true,"allDay":true,"minStartTime":"00:00","maxEndTime":"00:00","minDuration":30,"maxDuration":180,"allowToBookBefore":365,"repeatable":true,"checkInRequired":true,"checkInNoticeTime":5,"checkInPermission":"Only Organizer","autoRelease":true,"autoReleaseTime":10,"checkOutPermission":"Only Organizer","checkInStatistics":false,"displayBooking":true,"autoCheckOut":true,"autoCheckOutDuration":15,"lightOnCheckIn":false,"lightOffCheckOut":false,"lightOnOffWork":false,"accessControlOn":false,"automaticCheckInWhenPeopleDetected":false,"automaticExtendWhenPeopleDetected":false}},"schedule":{"conferenceRecordId":245794,"startTime":1732726800,"endTime":1732728600,"originalStartTime":1732726800,"originalEndTime":1732728600,"allowCheckIn":false,"shouldCheckIn":false,"allowCheckOut":false,"status":"NOT_STARTED","subject":"111","meetingRoomName":"111","meetingRoomId":2566,"meetingRoomType":"common","buildingId":1300,"conferenceId":249376,"host":{"memberId":73825,"name":"test","email":"linzy@milesight.com","role":"HOST","isResource":false,"accessibleRealSchedule":false,"userId":78902,"hasCheckined":false},"notificationTime":15,"willStartReminderMinutes":[15],"scheduleType":"CONFERENCE","canBeExtended":false,"roomExpired":false,"checkInStatistics":false},"meetingService":false,"createVisitorRecord":false,"checkInStatistics":false,"visitType":0,"allowSelfRegistration":false,"conferenceReserveSource":"WEB_GRID"},"status":"Success","requestId":"59fd4722b9aeae5c8d4bc2c4000885c6"}
+
+ private Integer code;
+ private String errorCode;
+ private String message;
+
+
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpResponsePayload.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpResponsePayload.java
new file mode 100644
index 0000000..7c1b199
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/model/WpResponsePayload.java
@@ -0,0 +1,18 @@
+package com.milesight.beaveriot.integration.wp.model;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WpResponsePayload {
+
+ private String status;
+ private String requestId;
+ private JsonNode data;
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpClient.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpClient.java
new file mode 100644
index 0000000..606e8c2
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpClient.java
@@ -0,0 +1,307 @@
+package com.milesight.beaveriot.integration.wp.service;
+
+
+import cn.hutool.json.JSONObject;
+import com.milesight.beaveriot.context.api.EntityServiceProvider;
+import com.milesight.beaveriot.context.api.EntityValueServiceProvider;
+import com.milesight.beaveriot.integration.wp.constant.WpIntegrationConstants;
+import com.milesight.beaveriot.integration.wp.model.WpMeeting;
+import lombok.val;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class WpClient {
+
+
+ @Autowired
+ private EntityValueServiceProvider entityValueServiceProvider;
+
+ @Autowired
+ private EntityServiceProvider entityServiceProvider;
+
+ private static String COOKIE;
+
+ public void getToken() throws Exception {
+ val username = entityValueServiceProvider.findValueByKey(WpIntegrationConstants.getKey("openapi.username"));
+ val password = entityValueServiceProvider.findValueByKey(WpIntegrationConstants.getKey("openapi.password"));
+ if (username == null) {
+ return;
+ }
+ // 创建 HttpClient 实例
+ HttpClient client = HttpClient.newHttpClient();
+ // 创建请求体 JSON 字符串
+ String jsonInputString = String.format("{\"password\":\"%s\",\"username\":\"%s\",\"terminalType\":\"web\"}", password.asText(), username.asText());
+
+ // 创建 HttpRequest 实例
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(new URI("https://workplace.yeastar.cn/services/oauth/token"))
+ .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
+ .header("Content-Type", "application/json")
+ .header("Accept", "*/*")
+ .header("Cookie", "Authorization2=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjc4OTAyLCJ2ZXIiOjE3MzI2MjI4OTgsImdyYW50X3R5cGUiOiJwYXNzd29yZCIsInVzZXJfbmFtZSI6Imxpbnp5QG1pbGVzaWdodC5jb20iLCJwd2RfdmVyIjowLCJ0ZXJtaW5hbCI6IndlYiIsInJlZ2lvbiI6IkNOIiwianRpIjoiMjA0N2VmMjYtNmE1Zi00NmE5LTg0MTMtZjAxMTUyYjBkZmJjIiwiY2xpZW50X2lkIjoid2ViR2F0ZXdheSIsInRzIjoxNzMyNjIyODk4LCJleHBfaW4iOjI1OTIwMDB9.D6w5YSA4QGFdz8gfNRsjDdF46qOo8-ouOM0GHJx3ToQ")
+ .POST(HttpRequest.BodyPublishers.ofString(jsonInputString))
+ .build();
+
+ // 发送请求并获取响应
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+
+ // 获取响应头中的 Set-Cookie
+ Map> headers = response.headers().map();
+ List cookiesHeader = headers.get("Set-Cookie");
+ COOKIE = cookiesHeader.get(0);
+ }
+
+ public HttpResponse addConferenceRoom(String name, String memberCapacity) throws Exception {
+ getToken();
+ // 请求体
+ String jsonPayload = "{"
+ + "\"name\": \"" + name + "\","
+ + "\"buildingId\": 1300,"
+ + "\"facilityIds\": [6864, 6865, 6866, 6867, 6868],"
+ + "\"type\": \"common\","
+ + "\"restrictInWorkingHours\": true,"
+ + "\"minDuration\": 30,"
+ + "\"maxDuration\": 180,"
+ + "\"allowToBookBefore\": 365,"
+ + "\"repeatable\": true,"
+ + "\"checkInRequired\": true,"
+ + "\"checkInNoticeTime\": 5,"
+ + "\"checkInPermission\": \"Only Organizer\","
+ + "\"autoRelease\": true,"
+ + "\"autoReleaseTime\": 10,"
+ + "\"checkOutPermission\": \"Only Organizer\","
+ + "\"checkInStatistics\": false,"
+ + "\"deviceIds\": [],"
+ + "\"displayBooking\": true,"
+ + "\"lightOnCheckIn\": false,"
+ + "\"lightOffCheckOut\": false,"
+ + "\"lightOnOffWork\": false,"
+ + "\"automaticCheckInWhenPeopleDetected\": 0,"
+ + "\"automaticExtendWhenPeopleDetected\": 0,"
+ + "\"autoCheckOut\": true,"
+ + "\"autoCheckOutDuration\": 15,"
+ + "\"userIds\": [],"
+ + "\"departmentIds\": [1009324],"
+ + "\"memberCapacity\": \"" + memberCapacity + "\","
+ + "\"enterpriseId\": \"101741\""
+ + "}";
+ String url = "https://workplace.yeastar.cn/services/manager/conference/api/v1/meeting_rooms";
+ // 发送请求
+ return sendPostRequest(jsonPayload, url);
+
+ }
+
+ public void deleteConferenceRoom(int[] deviceIds) throws Exception {
+ getToken();
+ String jsonPayload = "{\"ids\":" + Arrays.toString(deviceIds) + ",\"enterpriseId\":\"101741\"}";
+ String url = "https://workplace.yeastar.cn/services/manager/conference/api/v1/meeting_rooms";
+ sendPostRequest(jsonPayload, url);
+ }
+
+
+ public HttpResponse allConferenceRoom() throws Exception {
+ getToken();
+ String url = "https://workplace.yeastar.cn/services/manager/conference/api/v1/meeting_rooms?enterpriseId=101741&pageSize=10&pageNumber=1¤tTime=1732597053";
+ return sendPostRequest(null, url);
+ }
+
+ public HttpResponse sendPostRequest(String jsonPayload, String url) throws Exception {
+ // 创建 HttpClient
+ HttpClient client = HttpClient.newHttpClient();
+ // 创建 HttpRequest
+ HttpRequest request;
+ if (jsonPayload == null) {
+ // 创建 HttpRequest
+ request = HttpRequest.newBuilder()
+ .uri(URI.create(url))
+ .header("accept", "application/json, text/plain, */*")
+ .header("accept-language", "zh-cn")
+ .header("cache-control", "no-cache")
+ .header("enterpriseid", "101741")
+ .header("origin", "https://workplace.yeastar.cn")
+ .header("pragma", "no-cache")
+ .header("priority", "u=1, i")
+ .header("referer", "https://workplace.yeastar.cn/admin/")
+ .header("sec-ch-ua", "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"")
+ .header("sec-ch-ua-mobile", "?0")
+ .header("sec-ch-ua-platform", "\"Windows\"")
+ .header("sec-fetch-dest", "empty")
+ .header("sec-fetch-mode", "cors")
+ .header("sec-fetch-site", "same-origin")
+ .header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")
+ .header("cookie", COOKIE)
+ .header("content-type", "application/json;charset=UTF-8")
+ .GET()
+ .build();
+ } else {
+ // 创建 HttpRequest
+ request = HttpRequest.newBuilder()
+ .uri(URI.create(url))
+ .header("accept", "application/json, text/plain, */*")
+ .header("accept-language", "zh-cn")
+ .header("cache-control", "no-cache")
+ .header("enterpriseid", "101741")
+ .header("origin", "https://workplace.yeastar.cn")
+ .header("pragma", "no-cache")
+ .header("priority", "u=1, i")
+ .header("referer", "https://workplace.yeastar.cn/admin/")
+ .header("sec-ch-ua", "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"")
+ .header("sec-ch-ua-mobile", "?0")
+ .header("sec-ch-ua-platform", "\"Windows\"")
+ .header("sec-fetch-dest", "empty")
+ .header("sec-fetch-mode", "cors")
+ .header("sec-fetch-site", "same-origin")
+ .header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")
+ .header("cookie", COOKIE)
+ .header("content-type", "application/json;charset=UTF-8")
+ .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
+ .build();
+ }
+ // 发送请求并获取响应
+ return client.send(request, HttpResponse.BodyHandlers.ofString());
+ }
+
+ public HttpResponse addMeeting(WpMeeting wpMeeting) throws Exception {
+ long firstStartTimeLong = Long.parseLong(wpMeeting.getFirstStartTime());
+ long lastEndTimeLong = Long.parseLong(wpMeeting.getLastEndTime());
+ String key = extractNumber(wpMeeting.getMeetingRoomId());
+ HttpResponse data = addMeetingRequest(key, wpMeeting.getSubject(), firstStartTimeLong, lastEndTimeLong, wpMeeting.getStartTime(), wpMeeting.getStartDate());
+ return data;
+ }
+
+ public static String extractNumber(String input) {
+ // 固定前缀和后缀
+ String prefix = "wp-integration.device.";
+ String suffix = ".schedule";
+ // 确保输入字符串包含前缀和后缀
+ if (input.startsWith(prefix) && input.endsWith(suffix)) {
+ // 提取前缀后的部分
+ String withoutPrefix = input.substring(prefix.length());
+ // 提取后缀前的部分
+ String number = withoutPrefix.substring(0, withoutPrefix.length() - suffix.length());
+ return number;
+ }
+ return null; // 如果输入字符串不符合预期格式,则返回null
+ }
+
+ public HttpResponse addMeetingRequest(String id, String subject, long firstStartTime, long lastEndTime, String startTime, String startDate) throws Exception {
+ getToken();
+ String url = String.format("https://workplace.yeastar.cn/services/conference/api/v1/meeting_rooms/%s/conferences", id);
+
+ // 计算两个时间戳之间的差值(以秒为单位)
+ long differenceInSeconds = lastEndTime - firstStartTime;
+
+ // 将差值从秒转换为分钟
+ long differenceInMinutes = differenceInSeconds / 60;
+ // 创建请求体
+ String jsonInputString = String.format(
+ "{\n" +
+ " \"subject\": \"%s\",\n" +
+ " \"scheduleSetting\": {\n" +
+ " \"duration\": %d,\n" +
+ " \"willStartReminderMinutes\": [\n" +
+ " 15\n" +
+ " ],\n" +
+ " \"scheduleMode\": \"ONCE\",\n" +
+ " \"simpleRepeatType\": \"NEVER\",\n" +
+ " \"firstStartTime\": %d,\n" +
+ " \"lastEndTime\": %d,\n" +
+ " \"customRecurrencePattern\": null,\n" +
+ " \"syncToThirdParty\": true,\n" +
+ " \"startTime\": \"%s\",\n" +
+ " \"startDate\": \"%s\",\n" +
+ " \"timezone\": \"UTC+8 Asia/Shanghai\",\n" +
+ " \"enableDst\": true\n" +
+ " },\n" +
+ " \"host\": {\n" +
+ " \"id\": 78902,\n" +
+ " \"memberId\": 73825,\n" +
+ " \"name\": \"test\",\n" +
+ " \"onlyName\": \"test\",\n" +
+ " \"departmentIds\": [\n" +
+ " 1009324\n" +
+ " ]\n" +
+ " },\n" +
+ " \"participants\": [],\n" +
+ " \"visitType\": 0,\n" +
+ " \"allowSelfRegistration\": false,\n" +
+ " \"conferenceReserveSource\": \"WEB_GRID\"\n" +
+ "}", subject, differenceInMinutes, firstStartTime, lastEndTime, startTime, startDate);
+
+ return sendPostRequest(jsonInputString, url);
+ }
+
+ public HttpResponse deleteMeeting(WpMeeting wpMeeting) throws Exception {
+ getToken();
+ String url = String.format("https://workplace.yeastar.cn/services/conference/api/v1/conferences/%s", wpMeeting.getMeetingId());
+ String jsonInputString = String.format("{\n" +
+ " \"selectStartTime\": %s,\n" +
+ " \"selectMode\": \"SELECTED\",\n" +
+ " \"cancelVisitorRecord\": false\n" +
+ "}", wpMeeting);
+ return sendPostRequest(jsonInputString, url);
+ }
+
+ public HttpResponse updateMeeting(WpMeeting wpMeeting) throws Exception {
+ long firstStartTimeLong = Long.parseLong(wpMeeting.getFirstStartTime());
+ long lastEndTimeLong = Long.parseLong(wpMeeting.getLastEndTime());
+ String key = extractNumber(wpMeeting.getMeetingRoomId());
+ HttpResponse data = updateMeetingRequest(key, wpMeeting.getSubject(), firstStartTimeLong, lastEndTimeLong, wpMeeting.getStartTime(), wpMeeting.getStartDate());
+ return data;
+ }
+
+ public HttpResponse updateMeetingRequest(String id, String subject, long firstStartTime, long lastEndTime, String startTime, String startDate) throws Exception {
+ getToken();
+ String url = String.format("https://workplace.yeastar.cn/services/conference/api/v1/conferences/%s", id);
+
+ // 计算两个时间戳之间的差值(以秒为单位)
+ long differenceInSeconds = lastEndTime - firstStartTime;
+
+ // 将差值从秒转换为分钟
+ long differenceInMinutes = differenceInSeconds / 60;
+ // 创建请求体
+ String jsonInputString = String.format(
+ "{\n" +
+ " \"subject\": \"%s\",\n" +
+ " \"scheduleSetting\": {\n" +
+ " \"duration\": %d,\n" +
+ " \"willStartReminderMinutes\": [\n" +
+ " 15\n" +
+ " ],\n" +
+ " \"scheduleMode\": \"ONCE\",\n" +
+ " \"simpleRepeatType\": \"NEVER\",\n" +
+ " \"firstStartTime\": %d,\n" +
+ " \"lastEndTime\": %d,\n" +
+ " \"customRecurrencePattern\": null,\n" +
+ " \"syncToThirdParty\": true,\n" +
+ " \"startTime\": \"%s\",\n" +
+ " \"startDate\": \"%s\",\n" +
+ " \"timezone\": \"UTC+8 Asia/Shanghai\",\n" +
+ " \"enableDst\": true\n" +
+ " },\n" +
+ " \"host\": {\n" +
+ " \"id\": 78902,\n" +
+ " \"memberId\": 73825,\n" +
+ " \"name\": \"test\",\n" +
+ " \"onlyName\": \"test\",\n" +
+ " \"departmentIds\": [\n" +
+ " 1009324\n" +
+ " ]\n" +
+ " },\n" +
+ " \"participants\": [],\n" +
+ " \"visitType\": 0,\n" +
+ " \"allowSelfRegistration\": false,\n" +
+ " \"conferenceReserveSource\": \"WEB_GRID\"\n" +
+ "}", subject, differenceInMinutes, firstStartTime, lastEndTime, startTime, startDate);
+ return sendPostRequest(jsonInputString, url);
+ }
+}
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpDeviceService.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpDeviceService.java
new file mode 100644
index 0000000..b71d2f9
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpDeviceService.java
@@ -0,0 +1,168 @@
+package com.milesight.beaveriot.integration.wp.service;
+
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.milesight.beaveriot.base.utils.JsonUtils;
+import com.milesight.beaveriot.context.api.DeviceServiceProvider;
+import com.milesight.beaveriot.context.constants.IntegrationConstants;
+import com.milesight.beaveriot.context.integration.enums.AccessMod;
+import com.milesight.beaveriot.context.integration.enums.EntityValueType;
+import com.milesight.beaveriot.context.integration.model.*;
+import com.milesight.beaveriot.context.integration.model.event.ExchangeEvent;
+import com.milesight.beaveriot.eventbus.annotations.EventSubscribe;
+import com.milesight.beaveriot.eventbus.api.Event;
+import com.milesight.beaveriot.integration.wp.constant.WpIntegrationConstants;
+import com.milesight.beaveriot.integration.wp.entity.WpIntegrationEntities;
+import com.milesight.beaveriot.integration.wp.model.WpMeeting;
+import com.milesight.beaveriot.integration.wp.model.WpMeetingRequest;
+import com.milesight.beaveriot.integration.wp.model.WpResponsePayload;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+
+@Service
+@Slf4j
+public class WpDeviceService {
+
+ @Autowired
+ private DeviceServiceProvider deviceServiceProvider;
+
+ @Autowired
+ private WpMeetingRoomService wpMeetingRoomService;
+
+ @SneakyThrows
+ @EventSubscribe(payloadKeyExpression = "wp-integration.device.*", eventType = ExchangeEvent.EventType.DOWN)
+ public void onDeviceExchangeEvent(ExchangeEvent event) {
+ val exchangePayload = event.getPayload();
+ }
+
+ @SneakyThrows
+ @EventSubscribe(payloadKeyExpression = "wp-integration.integration.sync_device", eventType = ExchangeEvent.EventType.DOWN)
+ public void onSyncDevice(Event event) {
+ try {
+
+ val wpResponsePayload = wpMeetingRoomService.allConferenceRoom();
+ if (wpResponsePayload == null) {
+ return;
+ }
+ String integrationId = WpIntegrationConstants.INTEGRATION_IDENTIFIER;
+ val data = wpResponsePayload.getData();
+ ArrayNode arrayNode = (ArrayNode) data.get("list");
+ arrayNode.forEach(node -> {
+ val identifier = node.get("id").asText();
+ val deviceName = node.get("name").asText();
+ val memberCapacity = node.get("memberCapacity").asInt();
+ ArrayNode schedules = (ArrayNode) node.get("schedules");
+ // 添加设备
+ addMeetingDevice(deviceName, memberCapacity, identifier);
+ if (schedules.size() != 0) {
+ val deviceKey = IntegrationConstants.formatIntegrationDeviceKey(integrationId, identifier);
+ // 使用 Jackson 进行反序列化
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
+ List wpMeetings = objectMapper.convertValue(schedules, List.class);
+ wpMeetings.forEach(meeting -> {
+ // 保存预约的会议历史数据
+ try {
+ wpMeetingRoomService.addMeetingRoom(WpMeetingRequest.builder().type(0).build(), meeting);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ });
+ } catch (Exception e) {
+ log.error("Error in onSyncDevice", e);
+ }
+ }
+
+ @SneakyThrows
+ @EventSubscribe(payloadKeyExpression = "wp-integration.integration.add_device.*", eventType = ExchangeEvent.EventType.DOWN)
+ public void onAddDevice(Event event) {
+ val deviceName = event.getPayload().getContext("device_name", "Device Name");
+ WpIntegrationEntities.AddDevice addDevice = event.getPayload();
+ Integer memberCapacity = addDevice.getMemberCapacity();
+
+ WpResponsePayload wpResponsePayload = wpMeetingRoomService.addConferenceRoom(addDevice, deviceName);
+ if (wpResponsePayload == null) {
+ log.error("Error in addConferenceRoom");
+ return;
+ }
+ val identifier = wpResponsePayload.getData().get("id").asText();
+ addMeetingDevice(deviceName, memberCapacity, identifier);
+ }
+
+ private void addMeetingDevice(String deviceName, Integer memberCapacity, String identifier) {
+ List entities = new ArrayList<>();
+ String integrationId = WpIntegrationConstants.INTEGRATION_IDENTIFIER;
+ val deviceKey = IntegrationConstants.formatIntegrationDeviceKey(integrationId, identifier);
+ WpMeeting wpMeeting = WpMeeting.builder()
+ .meetingRoomId(identifier)
+ .build();
+ // 添加额外实体
+ addAdditionalEntities(deviceKey, entities, wpMeeting);
+ // 添加设备
+ addDevice(deviceName, memberCapacity, identifier, entities);
+ }
+
+ private static void addAdditionalEntities(String deviceKey, List entities, WpMeeting wpMeeting) {
+ val integrationId = WpIntegrationConstants.INTEGRATION_IDENTIFIER;
+
+ Map attributes = new HashMap<>();
+ if (wpMeeting != null) {
+ // 遍历wpSchedule的所有属性,把属性值
+ for (Map.Entry entry : JsonUtils.toMap(wpMeeting).entrySet()) {
+ val key = entry.getKey();
+ val value = entry.getValue();
+ attributes.put(key, value);
+
+ }
+ }
+ entities.add(new EntityBuilder(integrationId, deviceKey)
+ .identifier("schedule")
+ .property("schedule", AccessMod.RW)
+ .valueType(EntityValueType.STRING)
+ .attributes(attributes)
+ .build());
+ entities.add(new EntityBuilder(integrationId, deviceKey)
+ .identifier(WpIntegrationConstants.InternalPropertyIdentifier.LAST_SYNC_TIME)
+ .property(WpIntegrationConstants.InternalPropertyIdentifier.LAST_SYNC_TIME, AccessMod.R)
+ .valueType(EntityValueType.LONG)
+ .attributes(Map.of("internal", true))
+ .build());
+ }
+
+ private void addDevice(String deviceName, Integer memberCapacity, String identifier, List entities) {
+ val integrationId = WpIntegrationConstants.INTEGRATION_IDENTIFIER;
+ val device = new DeviceBuilder(integrationId)
+ .name(deviceName)
+ .identifier(identifier)
+ .additional(Map.of("memberCapacity", memberCapacity))
+ .entities(entities)
+ .build();
+ deviceServiceProvider.save(device);
+ }
+
+ @SneakyThrows
+ @EventSubscribe(payloadKeyExpression = "wp-integration.integration.delete_device", eventType = ExchangeEvent.EventType.DOWN)
+ public void onDeleteDevice(Event event) {
+ val device = deviceServiceProvider.findByIdentifier(
+ ((Device) event.getPayload().getContext("device")).getIdentifier(), WpIntegrationConstants.INTEGRATION_IDENTIFIER);
+ val deviceId = device.getIdentifier();
+ wpMeetingRoomService.deleteConferenceRoom(deviceId);
+ deviceServiceProvider.deleteById(device.getId());
+ }
+
+}
+
+
diff --git a/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpMeetingRoomService.java b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpMeetingRoomService.java
new file mode 100644
index 0000000..f2b513d
--- /dev/null
+++ b/integrations/wp-integration/src/main/java/com/milesight/beaveriot/integration/wp/service/WpMeetingRoomService.java
@@ -0,0 +1,179 @@
+package com.milesight.beaveriot.integration.wp.service;
+
+
+import cn.hutool.json.JSONObject;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.milesight.beaveriot.context.api.DeviceServiceProvider;
+import com.milesight.beaveriot.context.api.EntityValueServiceProvider;
+import com.milesight.beaveriot.context.api.ExchangeFlowExecutor;
+import com.milesight.beaveriot.context.integration.model.ExchangePayload;
+import com.milesight.beaveriot.entity.repository.EntityHistoryRepository;
+import com.milesight.beaveriot.integration.wp.entity.WpIntegrationEntities;
+import com.milesight.beaveriot.integration.wp.model.WpMeeting;
+import com.milesight.beaveriot.integration.wp.model.WpMeetingRequest;
+import com.milesight.beaveriot.integration.wp.model.WpMeetingResponse;
+import com.milesight.beaveriot.integration.wp.model.WpResponsePayload;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.net.http.HttpResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@Service
+@Slf4j
+public class WpMeetingRoomService {
+
+
+ @Autowired
+ private DeviceServiceProvider deviceServiceProvider;
+
+ @Autowired
+ private EntityValueServiceProvider entityValueServiceProvider;
+
+ @Autowired
+ private ExchangeFlowExecutor exchangeFlowExecutor;
+
+ @Autowired
+ private EntityHistoryRepository entityHistoryRepository;
+
+ @Autowired
+ private WpClient wpClient;
+
+
+ public WpResponsePayload addConferenceRoom(WpIntegrationEntities.AddDevice addDevice, String deviceName) throws Exception {
+ Integer memberCapacity = addDevice.getMemberCapacity();
+ HttpResponse response = wpClient.addConferenceRoom(deviceName, String.valueOf(memberCapacity));
+ if (response.statusCode() == 200) {
+ // 使用 Jackson 进行反序列化
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
+ val wpResponsePayload = objectMapper.readValue(response.body(), WpResponsePayload.class);
+ return wpResponsePayload;
+ }
+ return null;
+ }
+
+ public void deleteConferenceRoom(String deviceId) throws Exception {
+ //String[]转int[]
+ int[] intArray = new int[1];
+ intArray[0] = Integer.parseInt(deviceId);
+ wpClient.deleteConferenceRoom(intArray);
+ }
+
+ public WpResponsePayload allConferenceRoom() throws Exception {
+ HttpResponse response = wpClient.allConferenceRoom();
+ if (response.statusCode() == 200) {
+ // 使用 Jackson 进行反序列化
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
+ WpResponsePayload wpResponsePayload = objectMapper.readValue(response.body(), WpResponsePayload.class);
+ return wpResponsePayload;
+ }
+ return null;
+ }
+
+ public WpMeetingResponse addMeetingRoom(WpMeetingRequest wpMeetingRequest, WpMeeting wpMeeting) {
+ WpMeetingResponse wpMeetingResponse = new WpMeetingResponse();
+ String id = "";
+ try {
+ if (wpMeetingRequest.getType() == 0) {
+ wpMeetingResponse = addMeeting(wpMeeting);
+ } else if (wpMeetingRequest.getType() == 1) {
+ wpMeetingResponse = updateMeeting(wpMeeting);
+ } else if (wpMeetingRequest.getType() == 2) {
+ wpMeetingResponse = deleteMeeting(wpMeeting);
+ }
+ } catch (Exception e) {
+ log.error("addMeeting error", e);
+ }
+ if (wpMeeting == null) {
+ wpMeeting = WpMeeting.builder()
+ .subject(wpMeetingRequest.getSubject())
+ .meetingRoomId(wpMeetingRequest.getKey())
+ .firstStartTime(wpMeetingRequest.getFirst())
+ .lastEndTime(wpMeetingRequest.getLast())
+ .startDate(wpMeetingRequest.getDate())
+ .startTime(wpMeetingRequest.getTime())
+ .meetingId(wpMeetingRequest.getMeeting())
+ .build();
+ } else {
+ wpMeeting.setMeetingId(id);
+ }
+ wpMeeting.setCreateTime(System.currentTimeMillis());
+ if (wpMeetingRequest.getType() == 2) {
+ wpMeeting.setSubject(null);
+ }
+ Map result = new HashMap();
+ result.put(wpMeeting.getMeetingRoomId(), wpMeeting.toString());
+ entityValueServiceProvider.saveHistoryRecord(ExchangePayload.create(result), Long.parseLong(wpMeeting.getFirstStartTime()) * 1000);
+ return wpMeetingResponse;
+ }
+
+ public WpMeetingResponse addMeeting(WpMeeting wpMeeting) {
+ WpMeetingResponse result = WpMeetingResponse.builder().build();
+ HttpResponse data = null;
+ try {
+ data = wpClient.addMeeting(wpMeeting);
+ // 解析 JSON 响应
+ JSONObject jsonObject = new JSONObject(data.body());
+ // 提取 "data" 对象
+ JSONObject dataObject = jsonObject.getJSONObject("data");
+ if (dataObject == null) {
+ return null;
+ }
+ result.setCode(dataObject.getInt("code"));
+ result.setMessage(String.valueOf(dataObject.getInt("id")));
+ } catch (Exception e) {
+ result.setCode(500);
+ }
+ return result;
+ }
+
+ public WpMeetingResponse updateMeeting(WpMeeting wpMeeting) {
+ WpMeetingResponse result = WpMeetingResponse.builder().build();
+ HttpResponse data = null;
+ try {
+ data = wpClient.updateMeeting(wpMeeting);
+ // 解析 JSON 响应
+ JSONObject jsonObject = new JSONObject(data.body());
+ // 提取 "data" 对象
+ JSONObject dataObject = jsonObject.getJSONObject("data");
+ if (dataObject == null) {
+ return null;
+ }
+ result.setCode(dataObject.getInt("code"));
+ result.setMessage(String.valueOf(dataObject.getInt("id")));
+ } catch (Exception e) {
+ result.setCode(500);
+ }
+ return result;
+ }
+
+ public WpMeetingResponse deleteMeeting(WpMeeting wpMeeting) {
+ WpMeetingResponse result = WpMeetingResponse.builder().build();
+ HttpResponse data = null;
+ try {
+ data = wpClient.deleteMeeting(wpMeeting);
+ // 解析 JSON 响应
+ JSONObject jsonObject = new JSONObject(data.body());
+ // 提取 "data" 对象
+ JSONObject dataObject = jsonObject.getJSONObject("data");
+ if (dataObject == null) {
+ return null;
+ }
+ result.setCode(dataObject.getInt("code"));
+ result.setMessage(String.valueOf(dataObject.getInt("id")));
+ } catch (Exception e) {
+ result.setCode(500);
+ }
+ return result;
+ }
+}
diff --git a/integrations/wp-integration/src/main/resources/integration.yaml b/integrations/wp-integration/src/main/resources/integration.yaml
new file mode 100644
index 0000000..e90fa92
--- /dev/null
+++ b/integrations/wp-integration/src/main/resources/integration.yaml
@@ -0,0 +1,10 @@
+integration:
+ wp-integration: # integration identifier
+ name: WP Conference Management # integration name
+ description: "WP Conference Management" # integration description
+ icon-url: "public/wp_icon.svg"
+ enabled: true # whether enable this integration. Must be "true" for now
+
+ entity-identifier-add-device: add_device
+ # the same to deleteDevice identifier
+ entity-identifier-delete-device: delete_device
diff --git a/integrations/wp-integration/src/main/resources/static/public/wp_icon.svg b/integrations/wp-integration/src/main/resources/static/public/wp_icon.svg
new file mode 100644
index 0000000..9dc7695
--- /dev/null
+++ b/integrations/wp-integration/src/main/resources/static/public/wp_icon.svg
@@ -0,0 +1,84 @@
+
\ No newline at end of file