代码地址以及视频地址
实现小夹子网的对接
打开小夹子网了解如何对接
完成认证的功能
通过小夹子网编写相关常量信息
public interface ClipWebConstants {
/**
* 基础路由
*/
String BASIC_URI = "http://101.33.214.46/comm_pc/communication-support-clip/v1/clip-api";
/**
* 应用ID
*/
String APPID = "";
/**
* 绑定邮箱
*/
String mail = "18061877017@163.com";
}
编写小夹子网公共响应
@Data
public class ClipWebResponse {
@SerializedName("result")
private Boolean result;
@SerializedName("code")
private Integer code;
@SerializedName("message")
private String message;
@SerializedName("data")
private Object data;
}
引入http请求依赖
<!-- okhttp -->
<dependency>
<groupId>com.mzlion</groupId>
<artifactId>easy-okhttp</artifactId>
<version>1.1.4</version>
</dependency>
测试认证请求是否成功
@SpringBootTest
public class ClipWebTest {
@Test
public void testAuth() {
var response = HttpClient
.get(ClipWebConstants.BASIC_URI + "/auth")
.queryString("appId", ClipWebConstants.APPID)
.queryString("mail", ClipWebConstants.MAIL)
.asBean(ClipWebResponse.class);
System.out.println(response);
}
}
完成获取内容列表
@Test
public void testContentList() {
var authResponse = HttpClient
.get(ClipWebConstants.BASIC_URI + "/auth")
.queryString("appId", ClipWebConstants.APPID)
.queryString("mail", ClipWebConstants.MAIL)
.asBean(ClipWebResponse.class);
String token = authResponse.getData().toString();
var contentListResponse = HttpClient
.get(ClipWebConstants.BASIC_URI + "/contentList")
.header("ApiToken", token)
.queryString("title", "qq")
.queryString("current", 1)
.queryString("size", 100)
.asBean(ClipWebResponse.class);
System.out.println(contentListResponse);
}
实现list_clip_title_like指令
增加相关配置信息
在application.yml中加入
qq:
owner: 1781913075
group: 680634950
指令定义
模糊查询clip列表
定义指令: list_clip_title_like
对应正则: list_clip_title_like\s.{1,30}
编写list_clip_title_like指令代码
@OnGroup
@Filter(value = "list_clip_title_like\s(?<title>.{1,30})", matchType = MatchType.REGEX_MATCHES, trim = true)
public void doPrivateMsg(GroupMsg event, MsgSender sender, @FilterValue("title") String title) {
GroupInfo groupInfo = event.getGroupInfo();
if (groupCode.equals(groupInfo.getGroupCode())) {
String msg = event.getMsg();
System.out.println("=============");
System.out.println(title);
System.out.println("=============");
}
}
}
实现token缓存,引入相关依赖
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
在application.yml添加相关配置信息
spring:
redis:
url: redis://123456@localhost:6379
username: root
jedis:
pool:
max-active: 8
max-wait: -1
min-idle: 0
max-idle: 8
/**
* Redis使用FastJson序列化
*
* @author linq
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
static {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz) {
return TypeFactory.defaultInstance().constructType(clazz);
}
}
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings(value = {"unchecked", "rawtypes", "deprecation"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
@Slf4j
@Component("simpleBotPrivateMsgEvent")
public class SimpleBotPrivateMsgEvent {
@Value("${qq.group}")
private String groupCode;
@Value("${qq.owner}")
private String ownerCode;
@Resource
private StringRedisTemplate stringRedisTemplate;
@PostConstruct
public void initAuthToken() {
doSetAuthToken();
log.info("auth-token: {}", stringRedisTemplate.opsForValue().get(ClipWebConstants.AUTH_TOKEN));
}
private void doSetAuthToken() {
var response = HttpClient
.get(ClipWebConstants.BASIC_URI + "/auth")
.queryString("appId", ClipWebConstants.APPID)
.queryString("mail", ClipWebConstants.MAIL)
.asBean(ClipWebResponse.class);
stringRedisTemplate.opsForValue().setIfAbsent(ClipWebConstants.AUTH_TOKEN, response.getData().toString(), 12, TimeUnit.HOURS);
}
@OnGroup
@Filter(value = "list_clip_title_like\s(?<title>.{1,30})", matchType = MatchType.REGEX_MATCHES, trim = true)
public void doPrivateMsg(GroupMsg event, MsgSender sender, @FilterValue("title") String title) {
GroupInfo groupInfo = event.getGroupInfo();
if (groupCode.equals(groupInfo.getGroupCode())) {
String authToken = stringRedisTemplate.opsForValue().get(ClipWebConstants.AUTH_TOKEN);
if (authToken == null || authToken.equals("")) {
doSetAuthToken();
}
String msg = event.getMsg();
System.out.println("=============");
System.out.println(title);
System.out.println("=============");
}
}
}
完成推送功能
package linc.cool.robot.simple;
import catcode.CatCodeUtil;
import catcode.CodeBuilder;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mzlion.easyokhttp.HttpClient;
import linc.cool.robot.clip.ClipWebContentInfo;
import linc.cool.robot.clip.response.ClipWebResponse;
import linc.cool.robot.constants.ClipWebConstants;
import lombok.extern.slf4j.Slf4j;
import love.forte.simbot.annotation.Filter;
import love.forte.simbot.annotation.FilterValue;
import love.forte.simbot.annotation.OnGroup;
import love.forte.simbot.api.message.containers.GroupAccountInfo;
import love.forte.simbot.api.message.containers.GroupInfo;
import love.forte.simbot.api.message.events.GroupMsg;
import love.forte.simbot.api.sender.MsgSender;
import love.forte.simbot.filter.MatchType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author yqlin
* @date 2022/4/6 17:05
* @description
*/
@Slf4j
@Component("simpleBotPrivateMsgEvent")
public class SimpleBotPrivateMsgEvent {
@Value("${qq.group}")
private String groupCode;
@Value("${qq.owner}")
private String ownerCode;
private final CatCodeUtil catCodeUtil = CatCodeUtil.INSTANCE;
@Resource
private StringRedisTemplate stringRedisTemplate;
@PostConstruct
public void initAuthToken() {
doSetAuthToken();
log.info("auth-token: {}", stringRedisTemplate.opsForValue().get(ClipWebConstants.AUTH_TOKEN));
}
private void doSetAuthToken() {
var response = HttpClient
.get(ClipWebConstants.BASIC_URI + "/auth")
.queryString("appId", ClipWebConstants.APPID)
.queryString("mail", ClipWebConstants.MAIL)
.asBean(ClipWebResponse.class);
stringRedisTemplate.opsForValue().setIfAbsent(ClipWebConstants.AUTH_TOKEN, response.getData().toString(), 12, TimeUnit.HOURS);
}
@OnGroup
@Filter(value = "list_clip_title_like\s(?<title>.{1,30})", matchType = MatchType.REGEX_MATCHES, trim = true)
public void doPrivateMsg(GroupMsg event, MsgSender sender, @FilterValue("title") String title) {
GroupInfo groupInfo = event.getGroupInfo();
if (groupCode.equals(groupInfo.getGroupCode())) {
String authToken = stringRedisTemplate.opsForValue().get(ClipWebConstants.AUTH_TOKEN);
if (authToken == null || authToken.equals("")) {
doSetAuthToken();
}
authToken = stringRedisTemplate.opsForValue().get(ClipWebConstants.AUTH_TOKEN);
List<ClipWebContentInfo> contentInfoList = doGetUrlList(title, authToken);
final CodeBuilder<String> codeBuilder = catCodeUtil.getStringCodeBuilder("at", false);
GroupAccountInfo accountInfo = event.getAccountInfo();
String atAccountInfo = codeBuilder.key("code").value(accountInfo.getAccountCode()).build();
StringBuilder contentInfo = new StringBuilder();
for (ClipWebContentInfo content : contentInfoList) {
contentInfo.append(content.getTitle()).append("->").append(content.getUrlContent()).append("\n");
}
String template = """
= = = 亮哥小弟提示你 = = =
%s
%s
= = = = = = = = = = = =
""";
sender.SENDER.sendGroupMsgAsync(groupCode, String.format(template, contentInfo, atAccountInfo));
}
}
private List<ClipWebContentInfo> doGetUrlList(String title, String authToken) {
var contentListResponse = HttpClient
.get(ClipWebConstants.BASIC_URI + "/contentList")
.header("ApiToken", authToken)
.queryString("title", title)
.queryString("current", 1)
.queryString("size", 100)
.asBean(ClipWebResponse.class);
Object data = contentListResponse.getData();
JSONObject jsonObject = JSONArray.parseObject(JSON.toJSONString(data));
JSONArray records = jsonObject.getJSONArray("records");
List<ClipWebContentInfo> contentList = new ArrayList<>();
for (int i = 0; i < records.size(); i++) {
JSONObject record = records.getJSONObject(i);
String t = String.valueOf(record.get("title"));
String u = String.valueOf(record.get("urlContent"));
contentList.add(new ClipWebContentInfo(t, u));
}
return contentList;
}
}