提交 c3ec1f2f 编写于 作者: 小傅哥's avatar 小傅哥

feat: Ai 自动回帖实现

上级 76e3453b
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>xfg-dev-tech-app</module> <module>xfg-dev-tech-app</module>
<module>xfg-dev-tech-infrastructure</module>
<module>xfg-dev-tech-domain</module>
<module>xfg-dev-tech-trigger</module>
</modules> </modules>
<properties> <properties>
...@@ -45,6 +48,27 @@ ...@@ -45,6 +48,27 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>32.1.2-jre</version> <version>32.1.2-jre</version>
</dependency> </dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>chatglm-sdk-java</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.10</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
......
...@@ -54,6 +54,21 @@ ...@@ -54,6 +54,21 @@
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>chatglm-sdk-java</artifactId>
</dependency>
<!-- 系统 module -->
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-infrastructure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-trigger</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package cn.bugstack.xfg.dev.tech.config;
import cn.bugstack.chatglm.session.OpenAiSession;
import cn.bugstack.chatglm.session.OpenAiSessionFactory;
import cn.bugstack.chatglm.session.defaults.DefaultOpenAiSessionFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description ChatGLMSDK
* @create 2023-10-22 10:00
*/
@Configuration
@EnableConfigurationProperties(ChatGLMSDKConfigProperties.class)
public class ChatGLMSDKConfig {
@Bean
@ConditionalOnProperty(value = "chatglm.sdk.config.enabled", havingValue = "true", matchIfMissing = false)
public OpenAiSession openAiSession(ChatGLMSDKConfigProperties properties) {
// 1. 配置文件
cn.bugstack.chatglm.session.Configuration configuration = new cn.bugstack.chatglm.session.Configuration();
configuration.setApiHost(properties.getApiHost());
configuration.setApiSecretKey(properties.getApiSecretKey());
// 2. 会话工厂
OpenAiSessionFactory factory = new DefaultOpenAiSessionFactory(configuration);
// 3. 开启会话
return factory.openSession();
}
}
package cn.bugstack.xfg.dev.tech.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description ChatGLMSDK Config
* @create 2023-10-22 10:00
*/
@Data
@ConfigurationProperties(prefix = "chatglm.sdk.config", ignoreInvalidFields = true)
public class ChatGLMSDKConfigProperties {
/** 状态;open = 开启、close 关闭 */
private boolean enable;
/** 转发地址 */
private String apiHost;
/** 可以申请 sk-*** */
private String apiSecretKey;
}
...@@ -2,6 +2,25 @@ server: ...@@ -2,6 +2,25 @@ server:
port: 8091 port: 8091
application: application:
name: xfg-dev-tech-mock name: xfg-dev-tech-mock
# ChatGLM SDK Config
chatglm:
sdk:
config:
# 状态;true = 开启、false 关闭
enabled: true
# 官网地址
api-host: https://open.bigmodel.cn/
# 官网申请 https://open.bigmodel.cn/usercenter/apikeys
api-secret-key: d570f7c5d289cdac2abdfdc562e39f3f.trqz1dH8ZK6ED7Pg
# 知识星球配置信息;id -> 星球ID、user-id -> 用户ID、cookie -> 登录cookie
zsxq:
config:
id: 28885518425541
user-id: 241858242255511
cookie: zsxq_access_token=E0538FF2-B440-69E9-57D1-59EA37B9C0C6_9D76421394C6F474
# 日志 # 日志
logging: logging:
level: level:
......
package cn.bugstack.xfg.dev.tech.test;
import cn.bugstack.xfg.dev.tech.domain.zsxq.service.IAiReply;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 单元测试
* @create 2023-10-22 09:08
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApiTest {
@Resource
private IAiReply aiReply;
@Test
public void test_IAiReply() {
aiReply.doAiReply();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-mock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xfg-dev-tech-domain</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>chatglm-sdk-java</artifactId>
</dependency>
</dependencies>
<build>
<finalName>xfg-dev-tech-domain</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerVersion>${java.version}</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.domain.zsxq.adapter;
import cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo.TopicsItemVO;
import java.util.List;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 知识星球接口适配
* @create 2023-10-22 10:11
*/
public interface IZSXQAdapter {
List<TopicsItemVO> queryTopics();
void comment(long topicId, String content);
}
package cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 话题
* @create 2023-10-22 10:13
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TopicsItemVO {
private long topicId;
private String talk;
private List<ShowCommentsItem> showCommentsItems;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ShowCommentsItem {
private long userId;
}
}
package cn.bugstack.xfg.dev.tech.domain.zsxq.service;
import cn.bugstack.chatglm.model.*;
import cn.bugstack.chatglm.session.OpenAiSession;
import cn.bugstack.xfg.dev.tech.domain.zsxq.adapter.IZSXQAdapter;
import cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo.TopicsItemVO;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 只能回帖
* @create 2023-10-22 10:10
*/
@Slf4j
@Service
public class AiReply implements IAiReply {
@Autowired(required = false)
private OpenAiSession openAiSession;
@Resource
private IZSXQAdapter zsxqAdapter;
@Value("${zsxq.config.user-id}")
private Long userId;
private final String regex = "<e type=\"mention\" uid=\"(\\d+)\" title=\"(.*?)\" /> (.*)";
private volatile Set<Long> topicIds = new HashSet<>();
@Override
public void doAiReply() {
List<TopicsItemVO> topicsItemVOS = zsxqAdapter.queryTopics();
for (TopicsItemVO topicsItem : topicsItemVOS) {
// 是否回答过判断
if (!isCommentDone(topicsItem)) continue;
// 找到圈我我帖子
long topicId = topicsItem.getTopicId();
String text = topicsItem.getTalk();
// "<e type="mention" uid="241858242255511" title="%40%E5%B0%8F%E5%82%85%E5%93%A5" /> 提问 java 冒泡排序"
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
if (!matcher.find()) continue;
String uid = matcher.group(1);
String remainingText = matcher.group(3);
if (this.userId.equals(Long.valueOf(uid))) {
if (null == openAiSession) {
log.info("你没有开启 ChatGLM 参考yml配置文件来开启");
// 你可以使用 ChatGLM SDK 进行回答,回复问题;
zsxqAdapter.comment(topicId, "【测试,只回答圈我的帖子】对接 ChatGLM SDK https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java.html 回答:" + remainingText);
} else {
log.info("ChatGLM 进入回答 {} {}", topicId, remainingText);
if (topicIds.contains(topicId)) {
continue;
} else {
topicIds.add(topicId);
}
new Thread(() -> {
// 入参;模型、请求信息
ChatCompletionRequest request = new ChatCompletionRequest();
request.setModel(Model.CHATGLM_LITE); // chatGLM_6b_SSE、chatglm_lite、chatglm_lite_32k、chatglm_std、chatglm_pro
request.setPrompt(new ArrayList<ChatCompletionRequest.Prompt>() {
private static final long serialVersionUID = -7988151926241837899L;
{
add(ChatCompletionRequest.Prompt.builder()
.role(Role.user.getCode())
.content(remainingText)
.build());
}
});
// 请求
try {
StringBuilder content = new StringBuilder();
openAiSession.completions(request, new EventSourceListener() {
@Override
public void onEvent(EventSource eventSource, @Nullable String id, @Nullable String type, String data) {
ChatCompletionResponse chatCompletionResponse = com.alibaba.fastjson.JSON.parseObject(data, ChatCompletionResponse.class);
log.info("测试结果 onEvent:{}", chatCompletionResponse.getData());
// type 消息类型,add 增量,finish 结束,error 错误,interrupted 中断
if (EventType.finish.getCode().equals(type)) {
ChatCompletionResponse.Meta meta = com.alibaba.fastjson.JSON.parseObject(chatCompletionResponse.getMeta(), ChatCompletionResponse.Meta.class);
log.info("[输出结束] Tokens {}", com.alibaba.fastjson.JSON.toJSONString(meta));
}
content.append(chatCompletionResponse.getData());
}
@Override
public void onClosed(EventSource eventSource) {
log.info("对话完成");
// 你可以使用 ChatGLM SDK 进行回答,回复问题;
String contents = "ChatGLM 回答:" + content;
int maxLength = 5000;
int contentLength = contents.length();
int startIndex = 0;
int endIndex = maxLength;
while (startIndex < contentLength) {
if (endIndex > contentLength) {
endIndex = contentLength;
}
String subContent = contents.substring(startIndex, endIndex);
zsxqAdapter.comment(topicId, subContent);
startIndex = endIndex;
endIndex += maxLength;
}
topicIds.remove(topicId);
}
});
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}).start();
}
}
}
log.info("AI回复:{}", JSON.toJSONString(topicsItemVOS));
}
private boolean isCommentDone(TopicsItemVO topicsItem) {
List<TopicsItemVO.ShowCommentsItem> showComments = topicsItem.getShowCommentsItems();
if (null == showComments || showComments.isEmpty()) return true;
for (TopicsItemVO.ShowCommentsItem item : topicsItem.getShowCommentsItems()) {
long userId = item.getUserId();
if (this.userId == userId) {
return false;
}
}
return true;
}
}
package cn.bugstack.xfg.dev.tech.domain.zsxq.service;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 智能AI回帖
* @create 2023-10-22 10:08
*/
public interface IAiReply {
void doAiReply();
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-mock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xfg-dev-tech-infrastructure</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>xfg-dev-tech-infrastructure</finalName>
</build>
</project>
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.adapter;
import cn.bugstack.xfg.dev.tech.domain.zsxq.adapter.IZSXQAdapter;
import cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo.TopicsItemVO;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.api.IZSXQApi;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.RespData;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.ResponseDTO;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.TopicsItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 知识星球适配器接口
* @create 2023-10-22 10:18
*/
@Slf4j
@Service
public class ZSXQAdapter implements IZSXQAdapter {
@Resource
private IZSXQApi zsxqApi;
@Override
public List<TopicsItemVO> queryTopics() {
try {
ResponseDTO responseDTO = zsxqApi.topics();
RespData respData = responseDTO.getRespData();
List<TopicsItem> topics = respData.getTopics();
List<TopicsItemVO> topicsItemVOList = new ArrayList<>();
for (TopicsItem topicsItem : topics) {
TopicsItemVO topicsItemVO = TopicsItemVO.builder()
.topicId(topicsItem.getTopicId())
.talk(topicsItem.getTalk().getText())
.showCommentsItems(topicsItem.getShowComments() != null ? topicsItem.getShowComments().stream()
.map(showCommentsItem -> {
TopicsItemVO.ShowCommentsItem item = new TopicsItemVO.ShowCommentsItem();
item.setUserId(showCommentsItem.getOwner().getUserId());
return item;
})
.collect(Collectors.toList()) : new ArrayList<>())
.build();
topicsItemVOList.add(topicsItemVO);
}
return topicsItemVOList;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void comment(long topicId, String content) {
zsxqApi.comment(topicId, content);
}
}
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.api;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.ResponseDTO;
import java.io.IOException;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 知识星球API接口
* @create 2023-10-22 09:47
*/
public interface IZSXQApi {
/**
* 查询知识星球帖子内容
*
* @return 帖子数据
* @throws IOException 异常
*/
ResponseDTO topics() throws IOException;
/**
* 回复帖子
*
* @param topicId 帖子ID
* @param content 回复内容
*/
void comment(long topicId, String content);
}
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.api.impl;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.api.IZSXQApi;
import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.ResponseDTO;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 知识星球Api实现
* @create 2023-10-22 09:53
*/
@Slf4j
@Component
public class ZSXQApi implements IZSXQApi {
@Value("${zsxq.config.id}")
private String id;
@Value("${zsxq.config.cookie}")
private String cookie;
@Override
public ResponseDTO topics() throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet get = new HttpGet("https://api.zsxq.com/v2/groups/" + id + "/topics?scope=all&count=20");
get.addHeader("Accept-Encoding", "deflate, gzip");
get.addHeader("accept", "application/json, text/plain, */*");
get.addHeader("accept-language", "zh-CN,zh;q=0.9,en;q=0.8");
get.addHeader("authority", "api.zsxq.com");
get.addHeader("cookie", cookie);
get.addHeader("dnt", "1");
get.addHeader("origin", "https://wx.zsxq.com");
get.addHeader("referer", "https://wx.zsxq.com/");
get.addHeader("sec-ch-ua", "\"Chromium\";v=\"118\", \"Google Chrome\";v=\"118\", \"Not=A?Brand\";v=\"99\"");
get.addHeader("sec-ch-ua-mobile", "?0");
get.addHeader("sec-ch-ua-platform", "\"macOS\"");
get.addHeader("sec-fetch-dest", "empty");
get.addHeader("sec-fetch-mode", "cors");
get.addHeader("sec-fetch-site", "same-site");
get.addHeader("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36");
get.addHeader("x-request-id", "372177b46-4e7d-9373-d891-98a22adaeb7");
get.addHeader("x-signature", "32b39b5d1af5995e3b5022e58a8d8f23cd427434");
get.addHeader("x-timestamp", "1697249698");
get.addHeader("x-version", "2.45.0");
CloseableHttpResponse response = httpClient.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String jsonStr = EntityUtils.toString(response.getEntity());
return JSON.parseObject(jsonStr, ResponseDTO.class);
} else {
throw new RuntimeException("Err Code is " + response.getStatusLine().getStatusCode());
}
}
@Override
public void comment(long topicId, String content) {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("https://api.zsxq.com/v2/topics/" + topicId + "/comments");
httpPost.setHeader("Accept-Encoding", "deflate, gzip");
httpPost.setHeader("accept", "application/json, text/plain, */*");
httpPost.setHeader("accept-language", "zh-CN,zh;q=0.9,en;q=0.8");
httpPost.setHeader("authority", "api.zsxq.com");
httpPost.setHeader("content-type", "application/json");
httpPost.setHeader("cookie", cookie);
httpPost.setHeader("dnt", "1");
httpPost.setHeader("origin", "https://wx.zsxq.com");
httpPost.setHeader("referer", "https://wx.zsxq.com/");
httpPost.setHeader("sec-ch-ua", "\"Chromium\";v=\"118\", \"Google Chrome\";v=\"118\", \"Not=A?Brand\";v=\"99\"");
httpPost.setHeader("sec-ch-ua-mobile", "?0");
httpPost.setHeader("sec-ch-ua-platform", "\"macOS\"");
httpPost.setHeader("sec-fetch-dest", "empty");
httpPost.setHeader("sec-fetch-mode", "cors");
httpPost.setHeader("sec-fetch-site", "same-site");
httpPost.setHeader("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36");
httpPost.setHeader("x-request-id", "162ae5f17-2123-4ae3-67df-8b9775414e0");
httpPost.setHeader("x-signature", "698895e3ec4e651128b3d16755546bd2bc659687");
httpPost.setHeader("x-timestamp", "1697257286");
httpPost.setHeader("x-version", "2.45.0");
String requestBody = "{\"req_data\":{\"text\":\"" + StringEscapeUtils.escapeJava(content) + "\",\"image_ids\":[],\"mentioned_user_ids\":[]}}";
try {
httpPost.setEntity(new StringEntity(requestBody));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity);
log.info("回贴结果 {}", responseString);
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class Group{
@SerializedName("group_id")
private long groupId;
@SerializedName("background_url")
private String backgroundUrl;
@SerializedName("name")
private String name;
@SerializedName("type")
private String type;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class Owner{
@SerializedName("avatar_url")
private String avatarUrl;
@SerializedName("user_id")
private long userId;
@SerializedName("name")
private String name;
@SerializedName("location")
private String location;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
@Data
public class RespData{
@SerializedName("topics")
private List<TopicsItem> topics;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class ResponseDTO {
@SerializedName("resp_data")
private RespData respData;
@SerializedName("succeeded")
private boolean succeeded;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class ShowCommentsItem{
@SerializedName("owner")
private Owner owner;
@SerializedName("likes_count")
private int likesCount;
@SerializedName("create_time")
private String createTime;
@SerializedName("rewards_count")
private int rewardsCount;
@SerializedName("sticky")
private boolean sticky;
@SerializedName("text")
private String text;
@SerializedName("comment_id")
private long commentId;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class Talk{
@SerializedName("owner")
private Owner owner;
@SerializedName("text")
private String text;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
@Data
public class TopicsItem{
@SerializedName("reading_count")
private int readingCount;
@SerializedName("create_time")
private String createTime;
@SerializedName("user_specific")
private UserSpecific userSpecific;
@SerializedName("rewards_count")
private int rewardsCount;
@SerializedName("show_comments")
private List<ShowCommentsItem> showComments;
@SerializedName("type")
private String type;
@SerializedName("digested")
private boolean digested;
@SerializedName("likes_count")
private int likesCount;
@SerializedName("comments_count")
private int commentsCount;
@SerializedName("sticky")
private boolean sticky;
@SerializedName("talk")
private Talk talk;
@SerializedName("topic_id")
private long topicId;
@SerializedName("readers_count")
private int readersCount;
@SerializedName("group")
private Group group;
}
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
@Data
public class UserSpecific{
@SerializedName("subscribed")
private boolean subscribed;
@SerializedName("liked")
private boolean liked;
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-mock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>xfg-dev-tech-trigger</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>cn.bugstack</groupId>
<artifactId>xfg-dev-tech-domain</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>xfg-dev-tech-trigger</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerVersion>${java.version}</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package cn.bugstack.xfg.dev.tech.job;
import cn.bugstack.xfg.dev.tech.domain.zsxq.service.IAiReply;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author Fuzhengwei bugstack.cn @小傅哥
* @description 回帖JOB
* @create 2023-10-22 11:02
*/
@Slf4j
@Component()
public class ReplyJob {
@Resource
private IAiReply aiReply;
@Scheduled(cron = "0/10 * * * * ?")
public void exec() throws Exception {
aiReply.doAiReply();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册