* Добавлен ENUM для определения источника события

* Добавлен кастомный SQL метод возвращающий сообщения из БД новее запрошеной даты
* Добавлен глобальный обработчик сообщений
* Исрпавлены конфигурации spring, которые приводили к ошибкам в создании бинов
* Добавлен статический класс с методами вк апи
This commit is contained in:
Mark Struchkov 2019-01-05 00:45:57 +03:00
parent da8b5cba11
commit 30f4c09bbd
25 changed files with 214 additions and 154 deletions

View File

@ -10,6 +10,18 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>consultant-core</artifactId> <artifactId>consultant-core</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<properties> <properties>
<persistence.ver>1.0.2</persistence.ver> <persistence.ver>1.0.2</persistence.ver>
@ -43,6 +55,11 @@
<artifactId>spring-data-jpa</artifactId> <artifactId>spring-data-jpa</artifactId>
<version>${spring.data}</version> <version>${spring.data}</version>
</dependency> </dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -2,20 +2,20 @@ package org.sadtech.consultant.database.entity;
import lombok.Data; import lombok.Data;
import javax.persistence.Entity; import javax.persistence.*;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Data @Data
@Entity @Entity
public class Message { public class Messages {
@Id @Id
@GeneratedValue @GeneratedValue
private Long idMess; private Long idMess;
private Long idUser; private Long idUser;
private String text; private String text;
private String date; private Long date;
@Enumerated(EnumType.STRING)
private SourceMessage source;
} }

View File

@ -1,17 +0,0 @@
package org.sadtech.consultant.database.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
@Data
@Entity
public class SocialNetworks {
@Id
private Long id;
private Long idVk;
private Long idFacebook;
}

View File

@ -0,0 +1,5 @@
package org.sadtech.consultant.database.entity;
public enum SourceMessage {
VK, FACEBOOK;
}

View File

@ -2,8 +2,7 @@ package org.sadtech.consultant.database.entity;
import lombok.Data; import lombok.Data;
import javax.persistence.Entity; import javax.persistence.*;
import javax.persistence.Id;
import java.util.List; import java.util.List;
@Entity @Entity
@ -16,7 +15,10 @@ public class User {
private String token; private String token;
private String lastName; private String lastName;
private String city; private String city;
// private List<SocialNetworks> socialNetworks;
@ElementCollection
@CollectionTable(name="SocialNetworks", joinColumns=@JoinColumn(name="id"))
private List<String> socialNetworks;
} }

View File

@ -1,8 +1,16 @@
package org.sadtech.consultant.database.repository; package org.sadtech.consultant.database.repository;
import org.sadtech.consultant.database.entity.Message; import org.sadtech.consultant.database.entity.Messages;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface MessageRepository extends JpaRepository<Message, Long> { import java.util.Collection;
import java.util.List;
public interface MessageRepository extends JpaRepository<Messages, Long> {
@Query("SELECT u FROM Messages u WHERE u.date > :date")
Collection<Messages> getMessagesByRange(@Param("date") Long date);
} }

View File

@ -3,8 +3,7 @@ package org.sadtech.consultant.database.repository;
import org.sadtech.consultant.database.entity.NextUnit; import org.sadtech.consultant.database.entity.NextUnit;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
public interface NextUnitRepositoriy extends JpaRepository<NextUnit, Long> { public interface NextUnitRepository extends JpaRepository<NextUnit, Long> {
} }

View File

@ -1,7 +0,0 @@
package org.sadtech.consultant.database.repository;
import org.sadtech.consultant.database.entity.SocialNetworks;
import org.springframework.data.jpa.repository.JpaRepository;
public interface SocialNetworksRepositoriy extends JpaRepository<SocialNetworks, Long> {
}

View File

@ -1,8 +1,12 @@
package org.sadtech.consultant.database.service; package org.sadtech.consultant.database.service;
import org.sadtech.consultant.database.entity.Message; import org.sadtech.consultant.database.entity.Messages;
import java.util.List;
public interface MessageService { public interface MessageService {
void addMessage(Message message); void addMessage(Messages message);
List<Messages> getMessageRange(Long date);
} }

View File

@ -1,4 +0,0 @@
package org.sadtech.consultant.database.service;
public interface SocialNetworksService {
}

View File

@ -1,18 +1,25 @@
package org.sadtech.consultant.database.service.impl; package org.sadtech.consultant.database.service.impl;
import org.sadtech.consultant.database.entity.Message; import org.sadtech.consultant.database.entity.Messages;
import org.sadtech.consultant.database.repository.MessageRepository; import org.sadtech.consultant.database.repository.MessageRepository;
import org.sadtech.consultant.database.service.MessageService; import org.sadtech.consultant.database.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
@Service @Service
public class MessageServiceImpl implements MessageService { public class MessageServiceImpl implements MessageService {
@Autowired @Autowired
private MessageRepository repository; private MessageRepository repository;
public void addMessage(Message message) { public void addMessage(Messages message) {
repository.saveAndFlush(message); repository.saveAndFlush(message);
} }
@Override
public List<Messages> getMessageRange(Long date) {
return (List<Messages>) repository.getMessagesByRange(date);
}
} }

View File

@ -1,6 +1,6 @@
package org.sadtech.consultant.database.service.impl; package org.sadtech.consultant.database.service.impl;
import org.sadtech.consultant.database.repository.NextUnitRepositoriy; import org.sadtech.consultant.database.repository.NextUnitRepository;
import org.sadtech.consultant.database.service.NextUnitService; import org.sadtech.consultant.database.service.NextUnitService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -9,6 +9,6 @@ import org.springframework.stereotype.Service;
public class NextUnitServiceImpl implements NextUnitService { public class NextUnitServiceImpl implements NextUnitService {
@Autowired @Autowired
private NextUnitRepositoriy repositoriy; private NextUnitRepository repository;
} }

View File

@ -1,14 +0,0 @@
package org.sadtech.consultant.database.service.impl;
import org.sadtech.consultant.database.repository.SocialNetworksRepositoriy;
import org.sadtech.consultant.database.service.SocialNetworksService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SocialNetworksServiceImpl implements SocialNetworksService {
@Autowired
private SocialNetworksRepositoriy repositoriy;
}

View File

@ -0,0 +1,40 @@
package org.sadtech.consultant.processing;
import lombok.extern.log4j.Log4j;
import org.sadtech.consultant.database.entity.Messages;
import org.sadtech.consultant.database.service.MessageService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@Log4j
@Component
public class MessageHandler {
private MessageService service;
private long data;
public MessageHandler(MessageService service) {
this.service = service;
data = new Date().getTime() / 1000;
}
@Async
public void processing() {
while (true) {
List<Messages> messages = service.getMessageRange(data);
for (Messages message : messages) {
System.out.println(message);
data = message.getDate();
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@ -82,9 +82,6 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId> <artifactId>spring-core</artifactId>
@ -121,12 +118,6 @@
<version>5.1.3.RELEASE</version> <version>5.1.3.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet}</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
@ -154,14 +145,12 @@
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector}</version> <version>${mysql.connector}</version>
<scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId> <artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.entitymanager}</version> <version>${hibernate.entitymanager}</version>
<scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
@ -174,6 +163,7 @@
<artifactId>slf4j-nop</artifactId> <artifactId>slf4j-nop</artifactId>
<version>1.7.13</version> <version>1.7.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.sadtech</groupId> <groupId>org.sadtech</groupId>
<artifactId>consultant-core</artifactId> <artifactId>consultant-core</artifactId>

View File

@ -1,14 +1,15 @@
package org.sadtech.vkbot; package org.sadtech.vkbot;
import lombok.extern.log4j.Log4j; import lombok.extern.log4j.Log4j;
import org.sadtech.vkbot.config.DataConfig; import org.sadtech.consultant.processing.MessageHandler;
import org.sadtech.vkbot.config.SpringConfigVk; import org.sadtech.vkbot.config.SpringConfigVk;
import org.sadtech.vkbot.listener.EventListenable; import org.sadtech.vkbot.listener.EventListenable;
import org.sadtech.vkbot.listener.handlers.Handled; import org.sadtech.vkbot.handlers.Handled;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@Log4j @Log4j
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Main main = new Main(); Main main = new Main();
main.run(); main.run();
@ -17,11 +18,13 @@ public class Main {
public void run() throws Exception { public void run() throws Exception {
log.info("\n\n\n\n=== Запуск прогарммы ===\n\n"); log.info("\n\n\n\n=== Запуск прогарммы ===\n\n");
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigVk.class, DataConfig.class); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigVk.class);
EventListenable eventListener = context.getBean(EventListenable.class); EventListenable eventListener = context.getBean(EventListenable.class);
eventListener.listen(); eventListener.listen();
Handled dispetcherHandler = context.getBean(Handled.class); Handled dispetcherHandler = context.getBean(Handled.class);
dispetcherHandler.sortAndSend(); dispetcherHandler.sortAndSend();
MessageHandler messageHandler = context.getBean(MessageHandler.class);
messageHandler.processing();
log.info("\n\n=== Конец программы ===\n\n"); log.info("\n\n=== Конец программы ===\n\n");
} }

View File

@ -0,0 +1,47 @@
package org.sadtech.vkbot;
import com.google.gson.Gson;
import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.GroupActor;
import com.vk.api.sdk.exceptions.ApiException;
import com.vk.api.sdk.exceptions.ClientException;
import com.vk.api.sdk.objects.users.User;
import com.vk.api.sdk.objects.users.UserFull;
import com.vk.api.sdk.objects.users.UserXtrCounters;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Component;
import java.util.List;
@Log4j
@Component
public class VkApi {
private static VkApiClient vk;
private static GroupActor actor;
public VkApi(VkApiClient vk, GroupActor actor) {
this.vk = vk;
this.actor = actor;
}
public static void sendMessage(Integer id, String text) {
try {
vk.messages().send(actor).userId(id).message(text).execute();
} catch (ApiException | ClientException e) {
e.printStackTrace();
}
}
public static String getUserName(Integer id) {
List<UserXtrCounters> user = null;
UserFull userFull = null;
try {
user = vk.users().get(actor).userIds(String.valueOf(id)).execute();
} catch (ApiException | ClientException e) {
e.printStackTrace();
}
return user.get(0).getLastName() + " " + user.get(0).getFirstName();
}
}

View File

@ -1,24 +0,0 @@
package org.sadtech.vkbot;
import com.vk.api.sdk.client.VkApiClient;
import com.vk.api.sdk.client.actors.GroupActor;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Component;
@Log4j
@Component
public class VkOpenMethod {
private VkApiClient vk;
private GroupActor actor;
public VkOpenMethod(VkApiClient vk, GroupActor actor) {
this.vk = vk;
this.actor = actor;
}
public void sendMessage(Integer id, String text) {
vk.messages().send(actor).userId(id).peerId(id).message(text);
}
}

View File

@ -3,7 +3,9 @@ package org.sadtech.vkbot.config;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@ -14,7 +16,8 @@ import java.util.Properties;
@Configuration @Configuration
@EnableTransactionManagement @EnableTransactionManagement
@ComponentScan("org.sadtech.consultant.database.service")
@EnableJpaRepositories("org.sadtech.consultant.database.repository")
public class DataConfig { public class DataConfig {
@Value("${db.driver}") @Value("${db.driver}")

View File

@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*; import org.springframework.context.annotation.*;
import org.springframework.core.task.TaskExecutor; import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor; import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -20,9 +19,10 @@ import java.util.concurrent.Executors;
@Configuration @Configuration
@EnableAsync @EnableAsync
@Import({DataConfig.class})
@PropertySource("classpath:config.properties") @PropertySource("classpath:config.properties")
@ComponentScan("org.sadtech.vkbot.listener") @Import({DataConfig.class})
@ComponentScan({"org.sadtech.vkbot", "org.sadtech.consultant.processing"})
public class SpringConfigVk { public class SpringConfigVk {
@Value("${vk.groupID}") @Value("${vk.groupID}")
@ -74,9 +74,7 @@ public class SpringConfigVk {
GetLongPollServerResponse getLongPollServerResponse = null; GetLongPollServerResponse getLongPollServerResponse = null;
try { try {
getLongPollServerResponse = vkApiClient().groups().getLongPollServer(groupActor()).execute(); getLongPollServerResponse = vkApiClient().groups().getLongPollServer(groupActor()).execute();
} catch (ApiException e) { } catch (ApiException | ClientException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace(); e.printStackTrace();
} }
return getLongPollServerResponse; return getLongPollServerResponse;

View File

@ -1,4 +1,4 @@
package org.sadtech.vkbot.listener.handlers; package org.sadtech.vkbot.handlers;
public interface Handled { public interface Handled {

View File

@ -1,11 +1,11 @@
package org.sadtech.vkbot.listener.handlers.impl; package org.sadtech.vkbot.handlers.impl;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import lombok.extern.log4j.Log4j; import lombok.extern.log4j.Log4j;
import org.sadtech.vkbot.handlers.Handled;
import org.sadtech.vkbot.listener.Observable; import org.sadtech.vkbot.listener.Observable;
import org.sadtech.vkbot.listener.Observer; import org.sadtech.vkbot.listener.Observer;
import org.sadtech.vkbot.listener.data.ResponsibleData; import org.sadtech.vkbot.listener.data.ResponsibleData;
import org.sadtech.vkbot.listener.handlers.Handled;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -0,0 +1,46 @@
package org.sadtech.vkbot.handlers.impl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vk.api.sdk.objects.messages.Message;
import lombok.extern.log4j.Log4j;
import org.sadtech.consultant.database.entity.Messages;
import org.sadtech.consultant.database.entity.SourceMessage;
import org.sadtech.consultant.database.service.MessageService;
import org.sadtech.vkbot.VkApi;
import org.sadtech.vkbot.listener.Observable;
import org.sadtech.vkbot.listener.Observer;
import org.springframework.stereotype.Component;
@Log4j
@Component
public class MessageHandlerVk implements Observer {
private MessageService service;
public MessageHandlerVk(Observable dispetcherHandler, MessageService messageService) {
this.service = messageService;
dispetcherHandler.registerObserver(this);
}
@Override
public void update(JsonObject object) {
if (object.get("type").toString().equals("\"message_new\"")) {
Gson gson = new Gson();
Message message = gson.fromJson(object.getAsJsonObject("object"), Message.class);
send(message);
}
}
private void send(Message userMessage) {
log.info(userMessage.getBody());
Messages message = new Messages();
message.setIdUser(Long.valueOf(userMessage.getUserId()));
message.setText(userMessage.getBody());
message.setDate(Long.valueOf(userMessage.getDate()));
message.setSource(SourceMessage.VK);
VkApi.sendMessage(userMessage.getUserId(), "Здравствуйте, " + VkApi.getUserName(userMessage.getUserId()) + "!\nВаше сообщение получено!\n");
service.addMessage(message);
}
}

View File

@ -1,39 +0,0 @@
package org.sadtech.vkbot.listener.handlers.impl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.vk.api.sdk.objects.messages.Message;
import lombok.extern.log4j.Log4j;
import org.sadtech.consultant.database.service.MessageService;
import org.sadtech.consultant.database.service.impl.MessageServiceImpl;
import org.sadtech.vkbot.listener.Observable;
import org.sadtech.vkbot.listener.Observer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Log4j
@Component
public class MessageHandlerVk implements Observer {
private Observable dispetcherHandler;
// @Autowired
// private MessageService service;
public MessageHandlerVk(Observable dispetcherHandler) {
this.dispetcherHandler = dispetcherHandler;
dispetcherHandler.registerObserver(this);
}
@Override
public void update(JsonObject object) {
if (object.get("type").toString().equals("\"message_new\"")) {
Gson gson = new Gson();
Message message = gson.fromJson(object.getAsJsonObject("object"), Message.class);
send(message);
}
}
private void send(Message message) {
log.info(message.getBody());
}
}

View File

@ -1,7 +1,5 @@
package org.sadtech.vkbot.listener.impl; package org.sadtech.vkbot.listener.impl;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.vk.api.sdk.actions.LongPoll; import com.vk.api.sdk.actions.LongPoll;
import com.vk.api.sdk.callback.longpoll.queries.GetLongPollEventsQuery; import com.vk.api.sdk.callback.longpoll.queries.GetLongPollEventsQuery;
import com.vk.api.sdk.callback.longpoll.responses.GetLongPollEventsResponse; import com.vk.api.sdk.callback.longpoll.responses.GetLongPollEventsResponse;
@ -10,15 +8,15 @@ import com.vk.api.sdk.client.actors.GroupActor;
import com.vk.api.sdk.exceptions.ApiException; 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.groups.responses.GetLongPollServerResponse; import com.vk.api.sdk.objects.groups.responses.GetLongPollServerResponse;
import jdk.nashorn.internal.parser.JSONParser;
import lombok.extern.log4j.Log4j; import lombok.extern.log4j.Log4j;
import org.json.JSONObject; import org.sadtech.vkbot.VkApi;
import org.sadtech.vkbot.listener.EventListenable; import org.sadtech.vkbot.listener.EventListenable;
import org.sadtech.vkbot.listener.data.ResponsibleData; import org.sadtech.vkbot.listener.data.ResponsibleData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Date;
@Log4j @Log4j
@Component @Component
public class EventListenerVk implements EventListenable { public class EventListenerVk implements EventListenable {
@ -57,8 +55,6 @@ public class EventListenerVk implements EventListenable {
responseData.add(eventsResponse.getUpdates().get(0)); responseData.add(eventsResponse.getUpdates().get(0));
log.info(eventsResponse.getUpdates()); log.info(eventsResponse.getUpdates());
String test = "{\"one_time\":false,\"buttons\":[[{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"1\\\"}\",\"label\":\"Red2\"},\"color\":\"negative\"},{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"2\\\"}\",\"label\":\"Green\"},\"color\":\"positive\"}],[{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"3\\\"}\",\"label\":\"White\"},\"color\":\"default\"},{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"4\\\"}\",\"label\":\"Blue\"},\"color\":\"primary\"}]]}"; String test = "{\"one_time\":false,\"buttons\":[[{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"1\\\"}\",\"label\":\"Red2\"},\"color\":\"negative\"},{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"2\\\"}\",\"label\":\"Green\"},\"color\":\"positive\"}],[{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"3\\\"}\",\"label\":\"White\"},\"color\":\"default\"},{\"action\":{\"type\":\"text\",\"payload\":\"{\\\"button\\\": \\\"4\\\"}\",\"label\":\"Blue\"},\"color\":\"primary\"}]]}";
vk.messages().send(actor).peerId(244319573).keyboard(test).message("Сообщение получено").execute();
} }
longPollEventsQuery = longPoll.getEvents(server.getServer(), server.getKey(), eventsResponse.getTs()).waitTime(20); longPollEventsQuery = longPoll.getEvents(server.getServer(), server.getKey(), eventsResponse.getTs()).waitTime(20);
} while (true); } while (true);