Рефакторинг

This commit is contained in:
upagge 2020-05-16 09:53:28 +03:00
parent 2364a9788c
commit 8e8d09350a
No known key found for this signature in database
GPG Key ID: 15CD012E46F6BA34
30 changed files with 537 additions and 190 deletions

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# VK Bot
С помощью этой библиотеки вы можете написать своего бота для социальной сети ВКонтакте.
Если вы хотите написать бота для другой социальной сети, воспользуйтесь
[этим проектом](https://github.com/uPagge/social-bot).
## Dependency
maven:
```
<dependency>
<groupId>org.sadtech.vkbot</groupId>
<artifactId>vkbot-sdk</artifactId>
<version>0.2.2-SNAPSHOT</version>
</dependency>
```
## Примеры ботов
1. [Простой пример](https://github.com/uPagge/simple-vkbot/tree/master) использования всех юнитов
2. BitbucketBot - позволяет настроить уведомления для пользователей standalone Bitbucket Server.
## Quick Start
Для быстрой конфигурации воспользуйтесь проектом [VK BOT QUICK](), который сам создаст все бины, кроме юнитов.
В данном проекте
предлагаются более гибкие настройки.
## Докуменация
Рекомендуем ознакомиться с [докуменацией проекта](https://github.com/uPagge/social-bot), на основании которого написан
данный модуль.

159
pom.xml
View File

@ -4,11 +4,133 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>org.sadtech.vkbot</groupId> <groupId>org.sadtech.vk.bot</groupId>
<artifactId>vkbot-core</artifactId> <artifactId>vkbot-sdk</artifactId>
<version>0.2.2-SNAPSHOT</version> <version>1.0.0-RELEASE</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>VK Bot</name>
<description>Библиотека для написания ботов для социальной сети ВКонтакте.</description>
<url>https://github.com/uPagge/vk-bot</url>
<scm>
<connection>scm:git:https://github.com/uPagge/vk-bot.git</connection>
<url>https://github.com/uPagge/vk-bot</url>
<developerConnection>scm:git:https://github.com/uPagge/vk-bot.git</developerConnection>
</scm>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<properties>
<social.bot.ver>1.0.0-RELEASE</social.bot.ver>
<vksdk.ver>1.0.6</vksdk.ver>
<spring.jpa.ver>2.1.3.RELEASE</spring.jpa.ver>
<lombock.ver>1.18.12</lombock.ver>
</properties>
<dependencies>
<dependency>
<groupId>com.vk.api</groupId>
<artifactId>sdk</artifactId>
<version>${vksdk.ver}</version>
</dependency>
<dependency>
<groupId>org.sadtech.social</groupId>
<artifactId>social-bot</artifactId>
<version>${social.bot.ver}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.jpa.ver}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombock.ver}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -22,39 +144,12 @@
</plugins> </plugins>
</build> </build>
<properties>
<social.autoresponder.ver>0.6.6-SNAPSHOT</social.autoresponder.ver>
<vksdk.ver>1.0.6</vksdk.ver>
</properties>
<dependencies>
<dependency>
<groupId>com.vk.api</groupId>
<artifactId>sdk</artifactId>
<version>${vksdk.ver}</version>
</dependency>
<dependency>
<groupId>org.sadtech.social</groupId>
<artifactId>social-autoresponder</artifactId>
<version>${social.autoresponder.ver}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
</dependencies>
<developers> <developers>
<developer> <developer>
<id>uPagge</id>
<name>Struchkov Mark</name> <name>Struchkov Mark</name>
<email>upagge@mail.ru</email> <email>upagge@mail.ru</email>
<organization>SADTECH</organization>
</developer> </developer>
</developers> </developers>

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot; package org.sadtech.vk.bot.sdk;
import org.sadtech.autoresponder.repository.UnitPointerRepository; import org.sadtech.autoresponder.repository.UnitPointerRepository;
import org.sadtech.social.bot.GeneralAutoResponder; import org.sadtech.social.bot.GeneralAutoResponder;
@ -11,7 +11,7 @@ import java.util.Set;
public class MessageAutoresponderVk extends GeneralAutoResponder<Mail> { public class MessageAutoresponderVk extends GeneralAutoResponder<Mail> {
public MessageAutoresponderVk(Set<MainUnit> menuUnit, Sending sending, MessageService<Mail> messageService, UnitPointerRepository unitPointerRepository) { public MessageAutoresponderVk(Set<MainUnit> menuUnit, Sending sending, MessageService<Mail> messageService, UnitPointerRepository<MainUnit> unitPointerRepository) {
super(menuUnit, sending, messageService, unitPointerRepository); super(menuUnit, sending, messageService, unitPointerRepository);
} }

View File

@ -0,0 +1,43 @@
package org.sadtech.vk.bot.sdk.config;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.sadtech.vk.bot.sdk.exception.ConfigException;
import java.util.Optional;
/**
*
* Класс для сохранения информации о конфигурации, необходимых для создания {@link VkConnect}.
*
* @author upagge
*/
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VkConfig {
private VkConfigGroup configGroup;
private VkConfigUser configUser;
private VkConfigService configService;
public VkConfigGroup getConfigGroup() {
return Optional.ofNullable(configGroup)
.orElseThrow(() -> new ConfigException("Конфигурация сервиса для группы найдена"));
}
public VkConfigUser getConfigUser() {
return Optional.ofNullable(configUser)
.orElseThrow(() -> new ConfigException("Конфигурация для пользователя не найдена"));
}
public VkConfigService getConfigService() {
return Optional.ofNullable(configService)
.orElseThrow(() -> new ConfigException("Конфигурация сервиса не найдена, создайте класс VkConfigService!"));
}
}

View File

@ -0,0 +1,19 @@
package org.sadtech.vk.bot.sdk.config;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VkConfigGroup {
private String groupToken;
private Integer groupId;
}

View File

@ -0,0 +1,19 @@
package org.sadtech.vk.bot.sdk.config;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VkConfigService {
private Integer appId;
private String serviceToken;
}

View File

@ -0,0 +1,19 @@
package org.sadtech.vk.bot.sdk.config;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VkConfigUser {
private Integer userId;
private String token;
}

View File

@ -0,0 +1,64 @@
package org.sadtech.vk.bot.sdk.config;
import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.GroupActor;
import com.vk.api.sdk.client.actors.ServiceActor;
import com.vk.api.sdk.client.actors.UserActor;
import com.vk.api.sdk.httpclient.HttpTransportClient;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
/**
*
* Используется для сохранения объектов конфигурации, необходимых для работы SDK VK.
*
* @author upagge
*/
@RequiredArgsConstructor
public class VkConnect {
private final VkConfig vkConfig;
private VkApiClient vkApiClient;
private GroupActor groupActor;
private ServiceActor serviceActor;
private UserActor userActor;
public VkApiClient getVkApiClient() {
return Optional.ofNullable(vkApiClient).orElseGet(this::initVkApiClient);
}
public GroupActor getGroupActor() {
return Optional.ofNullable(groupActor).orElseGet(this::initGroupActor);
}
public UserActor getUserActor() {
return Optional.ofNullable(userActor).orElseGet(this::initUserActor);
}
public ServiceActor getServiceActor() {
return Optional.ofNullable(serviceActor).orElseGet(this::initServiceActor);
}
private UserActor initUserActor() {
userActor = new UserActor(vkConfig.getConfigUser().getUserId(), vkConfig.getConfigUser().getToken());
return userActor;
}
private VkApiClient initVkApiClient() {
vkApiClient = new VkApiClient(HttpTransportClient.getInstance());
return vkApiClient;
}
private GroupActor initGroupActor() {
groupActor = new GroupActor(vkConfig.getConfigGroup().getGroupId(), vkConfig.getConfigGroup().getGroupToken());
return groupActor;
}
private ServiceActor initServiceActor() {
serviceActor = new ServiceActor(vkConfig.getConfigService().getAppId(), vkConfig.getConfigService().getServiceToken());
return serviceActor;
}
}

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.domain.jpa; package org.sadtech.vk.bot.sdk.domain.jpa;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -10,8 +10,6 @@ import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
/** /**
* TODO: Добавить описание класса.
*
* @author upagge [28/07/2019] * @author upagge [28/07/2019]
*/ */
@Data @Data
@ -27,4 +25,5 @@ public class JsonObjectId extends BasicEntity {
public JsonObjectId(String json) { public JsonObjectId(String json) {
this.json = json; this.json = json;
} }
} }

View File

@ -0,0 +1,9 @@
package org.sadtech.vk.bot.sdk.exception;
public class ConfigException extends RuntimeException {
public ConfigException(String message) {
super(message);
}
}

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.repository; package org.sadtech.vk.bot.sdk.repository;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;

View File

@ -1,7 +1,7 @@
package org.sadtech.vkbot.core.repository.impl; package org.sadtech.vk.bot.sdk.repository.impl;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import org.sadtech.vkbot.core.repository.RawEventRepository; import org.sadtech.vk.bot.sdk.repository.RawEventRepository;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@ -1,10 +1,10 @@
package org.sadtech.vkbot.core.repository.impl.jpa; package org.sadtech.vk.bot.sdk.repository.impl.jpa;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import org.sadtech.vkbot.core.domain.jpa.JsonObjectId; import org.sadtech.vk.bot.sdk.domain.jpa.JsonObjectId;
import org.sadtech.vkbot.core.repository.RawEventRepository; import org.sadtech.vk.bot.sdk.repository.RawEventRepository;
import org.sadtech.vkbot.core.repository.jpa.RawEventRepositoryJpa; import org.sadtech.vk.bot.sdk.repository.jpa.RawEventRepositoryJpa;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;

View File

@ -1,6 +1,6 @@
package org.sadtech.vkbot.core.repository.jpa; package org.sadtech.vk.bot.sdk.repository.jpa;
import org.sadtech.vkbot.core.domain.jpa.JsonObjectId; import org.sadtech.vk.bot.sdk.domain.jpa.JsonObjectId;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.sender; package org.sadtech.vk.bot.sdk.sender;
import com.vk.api.sdk.client.VkApiClient; import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.GroupActor; import com.vk.api.sdk.client.actors.GroupActor;
@ -6,14 +6,15 @@ import com.vk.api.sdk.exceptions.ApiException;
import com.vk.api.sdk.exceptions.ClientException; import com.vk.api.sdk.exceptions.ClientException;
import com.vk.api.sdk.objects.messages.Keyboard; import com.vk.api.sdk.objects.messages.Keyboard;
import com.vk.api.sdk.queries.messages.MessagesSendQuery; import com.vk.api.sdk.queries.messages.MessagesSendQuery;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.social.core.domain.BoxAnswer; import org.sadtech.social.core.domain.BoxAnswer;
import org.sadtech.social.core.domain.keyboard.KeyBoard; import org.sadtech.social.core.domain.keyboard.KeyBoard;
import org.sadtech.social.core.service.sender.SendType; import org.sadtech.social.core.service.sender.SendType;
import org.sadtech.social.core.service.sender.Sending; import org.sadtech.social.core.service.sender.Sending;
import org.sadtech.vkbot.config.VkConnect; import org.sadtech.vk.bot.sdk.config.VkConnect;
import org.sadtech.vkbot.core.convert.KeyBoardConvert; import org.sadtech.vk.bot.sdk.utils.VkInsertData;
import org.sadtech.vkbot.utils.VkInsertData; import org.springframework.core.convert.ConversionService;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@ -24,24 +25,25 @@ public class MailSenderVk implements Sending {
private final VkApiClient vkApiClient; private final VkApiClient vkApiClient;
private final GroupActor groupActor; private final GroupActor groupActor;
private final VkInsertData vkInsertData; private final VkInsertData vkInsertData;
private final KeyBoardConvert keyBoardConvert;
@Setter
private ConversionService conversionService;
public MailSenderVk(VkConnect vkConnect) { public MailSenderVk(VkConnect vkConnect) {
this.vkApiClient = vkConnect.getVkApiClient(); this.vkApiClient = vkConnect.getVkApiClient();
this.groupActor = vkConnect.getGroupActor(); this.groupActor = vkConnect.getGroupActor();
this.vkInsertData = new VkInsertData(vkConnect); this.vkInsertData = new VkInsertData(vkConnect);
keyBoardConvert = new KeyBoardConvert(vkConnect);
} }
@Override @Override
public void send(Long personId, BoxAnswer boxAnswer) { public void send(Long personId, BoxAnswer boxAnswer) {
MessagesSendQuery messagesSendQuery = createMessage(boxAnswer, personId.longValue()); MessagesSendQuery messagesSendQuery = createMessage(boxAnswer, personId);
sendMessage(messagesSendQuery); sendMessage(messagesSendQuery);
} }
private MessagesSendQuery createMessage(BoxAnswer boxAnswer, Long peerId) { private MessagesSendQuery createMessage(BoxAnswer boxAnswer, Long peerId) {
MessagesSendQuery messages = vkApiClient.messages().send(groupActor).peerId(peerId.intValue()) MessagesSendQuery messages = vkApiClient.messages().send(groupActor).peerId(peerId.intValue())
.message(vkInsertData.insertWords(boxAnswer.getMessage(), peerId.intValue())) .message(vkInsertData.insertWords(boxAnswer.getMessage(), peerId))
.randomId(ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE)); .randomId(ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE));
messages.keyboard(convertKeyBoard(boxAnswer.getKeyBoard())); messages.keyboard(convertKeyBoard(boxAnswer.getKeyBoard()));
@ -61,7 +63,7 @@ public class MailSenderVk implements Sending {
private Keyboard convertKeyBoard(KeyBoard keyboard) { private Keyboard convertKeyBoard(KeyBoard keyboard) {
if (keyboard != null) { if (keyboard != null) {
return keyBoardConvert.convertKeyboard(keyboard); return conversionService.convert(keyboard, Keyboard.class);
} else { } else {
Keyboard keyboardVk = new Keyboard(); Keyboard keyboardVk = new Keyboard();
keyboardVk.setOneTime(true); keyboardVk.setOneTime(true);

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.service; package org.sadtech.vk.bot.sdk.service;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;

View File

@ -0,0 +1,19 @@
package org.sadtech.vk.bot.sdk.service.convert;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vk.api.sdk.objects.messages.Message;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class JsonObjectToMessageConvert implements Converter<JsonObject, Message> {
private final Gson gson = new Gson();
@Override
public Message convert(JsonObject source) {
return gson.fromJson(source.get("object"), Message.class);
}
}

View File

@ -1,5 +1,7 @@
package org.sadtech.vkbot.core.convert; package org.sadtech.vk.bot.sdk.service.convert;
import com.vk.api.sdk.client.actors.GroupActor;
import com.vk.api.sdk.client.actors.ServiceActor;
import com.vk.api.sdk.objects.messages.Keyboard; import com.vk.api.sdk.objects.messages.Keyboard;
import com.vk.api.sdk.objects.messages.KeyboardButton; import com.vk.api.sdk.objects.messages.KeyboardButton;
import com.vk.api.sdk.objects.messages.KeyboardButtonAction; import com.vk.api.sdk.objects.messages.KeyboardButtonAction;
@ -11,21 +13,26 @@ import org.sadtech.social.core.domain.keyboard.KeyBoardButton;
import org.sadtech.social.core.domain.keyboard.KeyBoardLine; import org.sadtech.social.core.domain.keyboard.KeyBoardLine;
import org.sadtech.social.core.domain.keyboard.button.KeyBoardButtonAccount; import org.sadtech.social.core.domain.keyboard.button.KeyBoardButtonAccount;
import org.sadtech.social.core.domain.keyboard.button.KeyBoardButtonText; import org.sadtech.social.core.domain.keyboard.button.KeyBoardButtonText;
import org.sadtech.vkbot.config.VkConnect; import org.sadtech.vk.bot.sdk.config.VkConnect;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class KeyBoardConvert { @Component
public class KeyBoardConvert implements Converter<KeyBoard, Keyboard> {
private final VkConnect vkConnect; private final GroupActor groupActor;
private final ServiceActor serviceActor;
public KeyBoardConvert(VkConnect vkConnect) { public KeyBoardConvert(VkConnect vkConnect) {
this.vkConnect = vkConnect; this.groupActor = vkConnect.getGroupActor();
this.serviceActor = vkConnect.getServiceActor();
} }
@Override
public Keyboard convertKeyboard(KeyBoard keyboard) { public Keyboard convert(KeyBoard keyboard) {
Keyboard keyboardVk = new Keyboard(); Keyboard keyboardVk = new Keyboard();
keyboardVk.setOneTime(keyboard.isOneTime()); keyboardVk.setOneTime(keyboard.isOneTime());
@ -81,17 +88,17 @@ public class KeyBoardConvert {
stringBuilder stringBuilder
.append("action=pay-to-group&amount=") .append("action=pay-to-group&amount=")
.append(button.getAmount()).append("&group_id=") .append(button.getAmount()).append("&group_id=")
.append(vkConnect.getGroupActor().getGroupId()); .append(groupActor.getGroupId());
} else { } else {
stringBuilder stringBuilder
.append("action=transfer-to-group") .append("action=transfer-to-group")
.append(button.getAmount()).append("&group_id=") .append(button.getAmount()).append("&group_id=")
.append(vkConnect.getGroupActor().getGroupId()); .append(groupActor.getGroupId());
} }
if (button.getAccountId() != null) { if (button.getAccountId() != null) {
stringBuilder.append("&description=").append(button.getAccountId()); stringBuilder.append("&description=").append(button.getAccountId());
} }
return stringBuilder.append("&aid=").append(vkConnect.getServiceActor().getId()).toString(); return stringBuilder.append("&aid=").append(serviceActor.getId()).toString();
} }
private static KeyboardButtonColor convertColor(ButtonColor color) { private static KeyboardButtonColor convertColor(ButtonColor color) {

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.convert; package org.sadtech.vk.bot.sdk.service.convert;
import com.vk.api.sdk.objects.messages.ForeignMessage; import com.vk.api.sdk.objects.messages.ForeignMessage;
import com.vk.api.sdk.objects.messages.Message; import com.vk.api.sdk.objects.messages.Message;
@ -7,7 +7,8 @@ import org.sadtech.social.core.domain.content.Mail;
import org.sadtech.social.core.domain.content.attachment.Attachment; import org.sadtech.social.core.domain.content.attachment.Attachment;
import org.sadtech.social.core.domain.content.attachment.AudioMessage; import org.sadtech.social.core.domain.content.attachment.AudioMessage;
import org.sadtech.social.core.domain.content.attachment.Geo; import org.sadtech.social.core.domain.content.attachment.Geo;
import org.sadtech.vkbot.convert.Convert; import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -15,10 +16,11 @@ import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MessageMailConvert implements Convert<Message, Mail> { @Component
public class MessageMailConvert implements Converter<Message, Mail> {
@Override @Override
public Mail converting(Message message) { public Mail convert(Message message) {
Mail mail = new Mail(); Mail mail = new Mail();
mail.setText(message.getText()); mail.setText(message.getText());
mail.setCreateDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(message.getDate()), TimeZone.getDefault().toZoneId())); mail.setCreateDate(LocalDateTime.ofInstant(Instant.ofEpochSecond(message.getDate()), TimeZone.getDefault().toZoneId()));

View File

@ -1,27 +1,22 @@
package org.sadtech.vkbot.core.distribution; package org.sadtech.vk.bot.sdk.service.distribution;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.vkbot.core.distribution.subscriber.AbstractBasketSubscribe; import org.sadtech.vk.bot.sdk.service.RawEventService;
import org.sadtech.vkbot.core.service.RawEventService; import org.sadtech.vk.bot.sdk.service.distribution.subscriber.AbstractBasketSubscribe;
import java.util.Optional;
import java.util.Set; import java.util.Set;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class EventDistributor implements Runnable { public class EventDistributor {
private final RawEventService rawEventService; private final RawEventService rawEventService;
private final Set<AbstractBasketSubscribe<JsonObject, ?>> basketSubscribes; private final Set<AbstractBasketSubscribe<JsonObject, ?>> basketSubscribes;
@Override
public void run() { public void run() {
while (true) { rawEventService.getNewEvent().forEach(this::goNextSubscribe);
Optional.ofNullable(rawEventService.getNewEvent())
.ifPresent(events -> events.forEach(this::goNextSubscribe));
}
} }
private void goNextSubscribe(JsonObject object) { private void goNextSubscribe(JsonObject object) {
@ -29,4 +24,5 @@ public class EventDistributor implements Runnable {
.filter(basketSubscribe -> basketSubscribe.check(object)) .filter(basketSubscribe -> basketSubscribe.check(object))
.forEach(basketSubscribe -> basketSubscribe.update(object)); .forEach(basketSubscribe -> basketSubscribe.update(object));
} }
} }

View File

@ -1,29 +1,27 @@
package org.sadtech.vkbot.core.distribution.subscriber; package org.sadtech.vk.bot.sdk.service.distribution.subscriber;
import org.sadtech.vkbot.convert.Convert; import lombok.Setter;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public abstract class AbstractBasketSubscribe<S, C> { @Setter
public abstract class AbstractBasketSubscribe<S, C> implements BasketSubscribeService<S, C> {
private Set<AbstractBasketSubscribe> basketSubscribes; private Set<AbstractBasketSubscribe> basketSubscribes;
private AbstractBasketSubscribe prioritySubscribe; private AbstractBasketSubscribe prioritySubscribe;
protected Convert<S, C> convert;
public AbstractBasketSubscribe() {
convert = (object) -> (C) object;
}
public abstract boolean check(S object); public abstract boolean check(S object);
public void update(S object) { public void update(S object) {
C newObject = convert.converting(object); C newObject = convert(object);
if (!goNextSubscribe(newObject)) { if (!goNextSubscribe(newObject)) {
processing(newObject); processing(newObject);
} }
} }
public abstract C convert(S object);
private boolean goNextSubscribe(C object) { private boolean goNextSubscribe(C object) {
AtomicBoolean flag = new AtomicBoolean(false); AtomicBoolean flag = new AtomicBoolean(false);
if (prioritySubscribe != null && prioritySubscribe.check(object)) { if (prioritySubscribe != null && prioritySubscribe.check(object)) {
@ -42,28 +40,4 @@ public abstract class AbstractBasketSubscribe<S, C> {
public abstract void processing(C object); public abstract void processing(C object);
public Set<AbstractBasketSubscribe> getBasketSubscribes() {
return basketSubscribes;
}
public void setBasketSubscribes(Set<AbstractBasketSubscribe> basketSubscribes) {
this.basketSubscribes = basketSubscribes;
}
public AbstractBasketSubscribe getPrioritySubscribe() {
return prioritySubscribe;
}
public void setPrioritySubscribe(AbstractBasketSubscribe prioritySubscribe) {
this.prioritySubscribe = prioritySubscribe;
}
public Convert getConvert() {
return convert;
}
public void setConvert(Convert convert) {
this.convert = convert;
}
} }

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.distribution.subscriber; package org.sadtech.vk.bot.sdk.service.distribution.subscriber;
import com.vk.api.sdk.objects.messages.Message; import com.vk.api.sdk.objects.messages.Message;
import com.vk.api.sdk.objects.messages.MessageAttachmentType; import com.vk.api.sdk.objects.messages.MessageAttachmentType;
@ -24,6 +24,11 @@ public class AccountSubscribe extends AbstractBasketSubscribe<Message, Message>
&& "Payment awaiting acceptance".equals(userMessage.getAttachments().get(0).getLink().getCaption()); && "Payment awaiting acceptance".equals(userMessage.getAttachments().get(0).getLink().getCaption());
} }
@Override
public Message convert(Message object) {
return object;
}
@Override @Override
public void processing(Message message) { public void processing(Message message) {
if (message.getText() != null) { if (message.getText() != null) {
@ -34,7 +39,7 @@ public class AccountSubscribe extends AbstractBasketSubscribe<Message, Message>
} }
} catch (PaymentException e) { } catch (PaymentException e) {
log.error(e.getMessage()); log.error(e.getMessage());
sending.send(message.getPeerId().longValue(), BoxAnswer.builder().message(e.getDescription()).build()); sending.send(message.getPeerId().longValue(), BoxAnswer.builder().message(e.getMessage()).build());
} }
} }
} }

View File

@ -0,0 +1,9 @@
package org.sadtech.vk.bot.sdk.service.distribution.subscriber;
public interface BasketSubscribeService<S, C> {
void update(S object);
void processing(C object);
}

View File

@ -0,0 +1,35 @@
package org.sadtech.vk.bot.sdk.service.distribution.subscriber;
import com.google.gson.JsonObject;
import com.vk.api.sdk.objects.messages.Message;
import org.sadtech.social.core.domain.content.Mail;
import org.sadtech.social.core.service.MailService;
import org.springframework.core.convert.ConversionService;
public class MailSubscriber extends AbstractBasketSubscribe<JsonObject, Message> {
private final MailService mailService;
private final ConversionService conversionService;
public MailSubscriber(MailService mailService, ConversionService conversionService) {
this.mailService = mailService;
this.conversionService = conversionService;
}
@Override
public boolean check(JsonObject object) {
String type = object.get("type").getAsString();
return "message_new".equals(type);
}
@Override
public Message convert(JsonObject object) {
return conversionService.convert(object, Message.class);
}
@Override
public void processing(Message message) {
mailService.add(conversionService.convert(message, Mail.class));
}
}

View File

@ -1,10 +1,10 @@
package org.sadtech.vkbot.core.service.impl; package org.sadtech.vk.bot.sdk.service.impl;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.vkbot.core.repository.RawEventRepository; import org.sadtech.vk.bot.sdk.repository.RawEventRepository;
import org.sadtech.vkbot.core.service.RawEventService; import org.sadtech.vk.bot.sdk.service.RawEventService;
import java.util.Set; import java.util.Set;
@ -17,13 +17,13 @@ public class RawEventServiceImpl implements RawEventService {
@Override @Override
public void cleanAll() { public void cleanAll() {
rawEventRepository.cleanAll(); rawEventRepository.cleanAll();
log.info("Репозиторий событий очищен"); log.trace("Репозиторий событий очищен");
} }
@Override @Override
public void add(JsonObject jsonObject) { public void add(JsonObject jsonObject) {
rawEventRepository.add(jsonObject); rawEventRepository.add(jsonObject);
log.info("Событие отправленно в репозиторий"); log.trace("Событие отправленно в репозиторий");
} }
@Override @Override

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.listener; package org.sadtech.vk.bot.sdk.service.listener;
import com.vk.api.sdk.client.VkApiClient; import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.GroupActor; import com.vk.api.sdk.client.actors.GroupActor;
@ -8,9 +8,15 @@ import com.vk.api.sdk.exceptions.LongPollServerKeyExpiredException;
import com.vk.api.sdk.objects.callback.longpoll.responses.GetLongPollEventsResponse; import com.vk.api.sdk.objects.callback.longpoll.responses.GetLongPollEventsResponse;
import com.vk.api.sdk.objects.groups.LongPollServer; import com.vk.api.sdk.objects.groups.LongPollServer;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.vkbot.config.VkConnect; import org.sadtech.vk.bot.sdk.config.VkConnect;
import org.sadtech.vkbot.core.service.RawEventService; import org.sadtech.vk.bot.sdk.service.RawEventService;
/**
*
* Слушает и сохраняет события, которые происодят во ВКонтакте, основываясь на LongPoll API.
*
* @author upagge
*/
@Slf4j @Slf4j
public class EventListenerVk implements Runnable { public class EventListenerVk implements Runnable {
@ -35,7 +41,7 @@ public class EventListenerVk implements Runnable {
.waitTime(DEFAULT_WAIT_TIME) .waitTime(DEFAULT_WAIT_TIME)
.execute(); .execute();
eventsResponse.getUpdates().parallelStream().forEach(object -> { eventsResponse.getUpdates().parallelStream().forEach(object -> {
log.info("Новое событие от LongPoll\n" + object); log.trace("Новое событие от LongPoll\n" + object);
rawEventService.add(object); rawEventService.add(object);
}); });
lastTimeStamp = eventsResponse.getTs(); lastTimeStamp = eventsResponse.getTs();
@ -52,7 +58,7 @@ public class EventListenerVk implements Runnable {
private LongPollServer getLongPollServer() throws ClientException, ApiException { private LongPollServer getLongPollServer() throws ClientException, ApiException {
log.debug("LongPoll сервер инициализирован"); log.debug("LongPoll сервер инициализирован");
if (actor != null) { if (actor != null) {
return vk.groups().getLongPollServer(actor, actor.getGroupId()).execute(); return vk.groupsLongPoll().getLongPollServer(actor, actor.getGroupId()).execute();
} else { } else {
throw new NullPointerException("Group actor"); throw new NullPointerException("Group actor");
} }
@ -67,8 +73,4 @@ public class EventListenerVk implements Runnable {
} }
} }
public RawEventService getRawEventService() {
return rawEventService;
}
} }

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.core.utils; package org.sadtech.vk.bot.sdk.utils;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -11,10 +11,17 @@ import com.vk.api.sdk.objects.users.Fields;
import com.vk.api.sdk.objects.users.UserMin; import com.vk.api.sdk.objects.users.UserMin;
import com.vk.api.sdk.objects.users.UserXtrCounters; import com.vk.api.sdk.objects.users.UserXtrCounters;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.sadtech.vkbot.config.VkConnect; import org.sadtech.vk.bot.sdk.config.VkConnect;
import java.util.List; import java.util.List;
import java.util.Optional;
/**
*
* Надстройка над API VK, для упрощеного доступа.
*
* @author upagge
*/
@Slf4j @Slf4j
public class VkApi { public class VkApi {
@ -22,11 +29,11 @@ public class VkApi {
private final ServiceActor actor; private final ServiceActor actor;
public VkApi(VkConnect vkConnect) { public VkApi(VkConnect vkConnect) {
vk = vkConnect.getVkApiClient(); this.vk = vkConnect.getVkApiClient();
actor = vkConnect.getServiceActor(); this.actor = vkConnect.getServiceActor();
} }
public UserMin getUserMini(Integer id) { public Optional<UserMin> getUserMini(Integer id) {
UserMin userMin = null; UserMin userMin = null;
Gson gson = new Gson(); Gson gson = new Gson();
try { try {
@ -37,20 +44,20 @@ public class VkApi {
} catch (ApiException | ClientException e) { } catch (ApiException | ClientException e) {
log.error(e.getMessage()); log.error(e.getMessage());
} }
return userMin; return Optional.ofNullable(userMin);
} }
public String getUserUniver(Integer id) { public Optional<String> getUserUniver(Integer id) {
List<UserXtrCounters> temp = null; List<UserXtrCounters> temp = null;
try { try {
temp = vk.users().get(actor).userIds(String.valueOf(id)).fields(Fields.UNIVERSITIES).execute(); temp = vk.users().get(actor).userIds(String.valueOf(id)).fields(Fields.UNIVERSITIES).execute();
} catch (ApiException | ClientException e) { } catch (ApiException | ClientException e) {
log.error(e.getMessage()); log.error(e.getMessage());
} }
return temp != null ? temp.get(0).getUniversities().get(0).getName() : null; return temp != null ? Optional.of(temp.get(0).getUniversities().get(0).getName()) : Optional.empty();
} }
public String getUserCity(Integer id) { public Optional<String> getUserCity(Integer id) {
List<UserXtrCounters> temp = null; List<UserXtrCounters> temp = null;
try { try {
temp = vk.users().get(actor).userIds(String.valueOf(id)).fields(Fields.CITY).execute(); temp = vk.users().get(actor).userIds(String.valueOf(id)).fields(Fields.CITY).execute();
@ -58,9 +65,9 @@ public class VkApi {
log.error(e.getMessage()); log.error(e.getMessage());
} }
if (temp != null && checkCity(temp)) { if (temp != null && checkCity(temp)) {
return temp.get(0).getCity().getTitle(); return Optional.of(temp.get(0).getCity().getTitle());
} }
return null; return Optional.empty();
} }
private boolean checkCity(List<UserXtrCounters> temp) { private boolean checkCity(List<UserXtrCounters> temp) {

View File

@ -0,0 +1,39 @@
package org.sadtech.vk.bot.sdk.utils;
import com.vk.api.sdk.objects.users.UserMin;
import org.sadtech.vk.bot.sdk.config.VkConnect;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VkInsertData {
private final VkApi vkApi;
public VkInsertData(VkConnect vkConnect) {
this.vkApi = new VkApi(vkConnect);
}
public String insertWords(String message, Long personId) {
Pattern pattern = Pattern.compile("%(\\w+)%");
Matcher m = pattern.matcher(message);
StringBuffer result = new StringBuffer();
while (m.find()) {
insert(m.group(0), personId.intValue()).ifPresent(s -> m.appendReplacement(result, s));
}
m.appendTail(result);
return result.toString();
}
private Optional<String> insert(String key, Integer userId) {
switch (key) {
case "%firstname%":
return vkApi.getUserMini(userId).map(UserMin::getFirstName);
case "%lastname%":
return vkApi.getUserMini(userId).map(UserMin::getLastName);
}
return Optional.empty();
}
}

View File

@ -1,15 +0,0 @@
package org.sadtech.vkbot.core.config;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
* TODO: Добавить описание класса.
*
* @author upagge [28/07/2019]
*/
@EnableJpaRepositories(basePackages = "org.sadtech.vkbot.core.repository.jpa")
@EntityScan(basePackages = "org.sadtech.vkbot.core.domain.jpa")
public class VkBotJpaConfig {
}

View File

@ -1,35 +0,0 @@
package org.sadtech.vkbot.core.distribution.subscriber;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vk.api.sdk.objects.messages.Message;
import org.sadtech.social.core.domain.content.Mail;
import org.sadtech.social.core.service.MailService;
import org.sadtech.vkbot.convert.Convert;
import org.sadtech.vkbot.core.convert.MessageMailConvert;
public class MailSubscriber extends AbstractBasketSubscribe<JsonObject, Message> {
private final MailService mailService;
private final Convert<Message, Mail> mailConvert = new MessageMailConvert();
public MailSubscriber(MailService mailService) {
this.mailService = mailService;
this.convert = (object) -> {
Gson gson = new Gson();
return gson.fromJson(object.getAsJsonObject("object"), Message.class);
};
}
@Override
public boolean check(JsonObject object) {
String type = object.get("type").getAsString();
return "message_new".equals(type);
}
@Override
public void processing(Message object) {
mailService.add(mailConvert.converting(object));
}
}