@Override
public void execute(Update update) {
String chatId = update.getMessage().getChatId().toString();
telegramUserService.findByChatId(chatId).ifPresentOrElse(
user -> {
user.setActive(true);
telegramUserService.save(user);
},
() -> {
TelegramUser telegramUser = new TelegramUser();
telegramUser.setActive(true);
telegramUser.setChatId(chatId);
telegramUserService.save(telegramUser);
});
sendBotMessageService.sendMessage(chatId, START_MESSAGE);
}
La lógica funciona aquí: si nuestra base de datos ya tiene dicho usuario por chatId, simplemente configuramos el campo active = true para él. Y si no existe tal usuario, creamos uno nuevo. Lo mismo ocurre con el comando /stop en StopCommand :
@Override
public void execute(Update update) {
telegramUserService.findByChatId(update.getMessage().getChatId().toString())
.ifPresent(it -> {
it.setActive(false);
telegramUserService.save(it);
});
sendBotMessageService.sendMessage(update.getMessage().getChatId().toString(), STOP_MESSAGE);
}
Se puede ver que al llamar a este comando, solo se establece el campo active = false para el usuario. Y eso es todo: sus suscripciones vivirán y esperarán entre bastidores cuando el usuario decida nuevamente activar el chat con el bot. Y parecería que la tarea ya se ha completado y se puede cerrar. Pero no estaba ahí. La tarea más importante es crear una alerta sobre nuevos artículos en la suscripción. Aquí es donde estas tareas se actualizarán y completarán por completo. Es decir, hasta que no hayamos implementado la notificación de nuevos artículos no se podrá cerrar. Por lo tanto, vamos a ocuparnos de la tarea JRTB-4: crear un cheque cada 20 minutos y notificaciones sobre nuevos artículos. ¡Amigos! ¿Quiere saber inmediatamente cuándo se publica el nuevo código para el proyecto? ¿Cuándo sale un nuevo artículo? Únete a mi canal tg . Allí recopilo mis artículos, mis pensamientos y mi desarrollo de código abierto.
Implementamos JRTB-4
Qué debemos hacer como parte de esta tarea:-
Cree un trabajo que irá periódicamente a todos los grupos a los que tengamos suscripciones en la base de datos, ordenará los artículos por fecha de publicación y comprobará si el ID de la última publicación coincide con el valor en GroupSub. Si no coincide, entonces necesita saber exactamente cuántos artículos se han publicado desde la última vez. Actualizamos last_article_id en GroupSub7 al estado actual.
-
Cuando encontramos una lista de artículos publicados, buscamos todos los usuarios ACTIVOS de estos grupos y les enviamos notificaciones sobre nuevos artículos.
Escribimos JavaRushPostClient
Aquí no intentaremos cubrir todas las solicitudes que nos enviaron en la API y crearemos solo la que necesitemos. Con esto conseguimos dos objetivos a la vez:-
Aceleramos el proceso de redacción de nuestra solicitud.
-
Dejamos este trabajo a aquellos que quieran ayudar a nuestra comunidad y decidan probarse a sí mismos como desarrolladores. Haré tareas para esto que se puedan completar después del MVP.
Información de usuario base:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
/**
* DTO, which represents base user information.
*/
@Data
public class BaseUserInfo {
private String city;
private String country;
private String displayName;
private Integer id;
private String job;
private String key;
private Integer level;
private String pictureUrl;
private String position;
private UserPublicStatus publicStatus;
private String publicStatusMessage;
private Integer rating;
private Integer userId;
}
Idioma:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents languages.
*/
public enum Language {
UNKNOWN,
ENGLISH,
GERMAN,
SPANISH,
HINDI,
FRENCH,
PORTUGUESE,
POLISH,
BENGALI,
PUNJABI,
CHINESE,
ITALIAN,
INDONESIAN,
MARATHI,
TAMIL,
TELUGU,
JAPANESE,
KOREAN,
URDU,
TAIWANESE,
NETHERLANDS,
RUSSIAN,
UKRAINIAN
}
Me gustaInformación:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents like's information.
*/
public class LikesInfo {
private Integer count;
private LikeStatus status;
}
Me gustaEstado:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents like's status.
*/
public enum LikeStatus {
UNKNOWN,
LIKE,
HOT,
FOLLOW,
FAVORITE,
SOLUTION,
HELPFUL,
ARTICLE,
OSCAR,
DISLIKE,
WRONG,
SPAM,
ABUSE,
FOUL,
TROLLING,
OFFTOPIC,
DUPLICATE,
DIRTY,
OUTDATED,
BORING,
UNCLEAR,
HARD,
EASY,
FAKE,
SHAM,
AWFUL
}
Tipo de mensaje:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents post types.
*/
public enum PostType {
UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}
Estado público del usuario:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents user public status.
*/
public enum UserPublicStatus {
UNKNOWN,
BEGINNER,
ACTIVE,
STRONG,
GRADUATED,
INTERNSHIP_IN_PROGRESS,
INTERNSHIP_COMPLETED,
RESUME_COMPLETED,
LOOKING_FOR_JOB,
HAVE_JOB;
}
VisibilityStatus:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents visibility status.
*/
public enum VisibilityStatus {
UNKNOWN,
RESTRICTED,
PUBLIC,
PROTECTED,
PRIVATE,
DISABLED,
DELETED
}
Basándonos en todos estos DTO, escribamos una clase principal para recibir artículos:
Información de publicación:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
/**
* DTO, which represents post information.
*/
@Data
public class PostInfo {
private BaseUserInfo authorInfo;
private Integer commentsCount;
private String content;
private Long createdTime;
private String description;
private GroupInfo groupInfo;
private Integer id;
private String key;
private Language language;
private LikesInfo likesInfo;
private GroupInfo originalGroupInfo;
private String pictureUrl;
private Double rating;
private Integer ratingCount;
private String title;
private PostType type;
private Long updatedTime;
private UserDiscussionInfo userDiscussionInfo;
private Integer views;
private VisibilityStatus visibilityStatus;
}
Ahora creemos una interfaz con la que trabajar y su implementación. Solo necesitaremos un método para trabajar con artículos:
Cliente JavaRushPost:
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import java.util.List;
/**
* Client for Javarush Open API corresponds to Posts.
*/
public interface JavaRushPostClient {
/**
* Find new posts since lastPostId in provided group.
*
* @param groupId provided group ID.
* @param lastPostId provided last post ID.
* @return the collection of the new {@link PostInfo}.
*/
List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId);
}
findNewPosts toma dos argumentos: el ID del grupo y el último ID del artículo que el bot ya publicó. Por lo tanto, se transmitirán todos aquellos artículos que fueron publicados con posterioridad al artículo con lastPostId . Y su implementación:
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import kong.unirest.GenericType;
import kong.unirest.Unirest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class JavaRushPostClientImpl implements JavaRushPostClient {
private final String javarushApiPostPath;
public JavaRushPostClientImpl(@Value("${javarush.api.path}") String javarushApi) {
this.javarushApiPostPath = javarushApi + "/posts";
}
@Override
public List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId) {
List<PostInfo> lastPostsByGroup = Unirest.get(javarushApiPostPath)
.queryString("order", "NEW")
.queryString("groupKid", groupId)
.queryString("limit", 15)
.asObject(new GenericType<List<PostInfo>>() {
}).getBody();
List<PostInfo> newPosts = new ArrayList<>();
for (PostInfo post : lastPostsByGroup) {
if (lastPostId.equals(post.getId())) {
return newPosts;
}
newPosts.add(post);
}
return newPosts;
}
}
Agregamos varios filtros a la solicitud:
- orden = NUEVO - para que la lista contenga primero los nuevos;
- groupKid = groupId: busca solo ciertos grupos;
- límite = 15: limitamos el número de artículos por solicitud. Nuestra frecuencia es de 15 a 20 minutos y esperamos que durante este tiempo no se escriban MÁS de 15 (!).
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClientTest.JAVARUSH_API_PATH;
@DisplayName("Integration-level testing for JavaRushPostClient")
class JavaRushPostClientTest {
private final JavaRushPostClient postClient = new JavaRushPostClientImpl(JAVARUSH_API_PATH);
@Test
public void shouldProperlyGetNew15Posts() {
//when
List<PostInfo> newPosts = postClient.findNewPosts(30, 2935);
//then
Assertions.assertEquals(15, newPosts.size());
}
}
Esta es una prueba muy simple que verifica si existe alguna comunicación con el cliente o no. Encuentra 15 artículos nuevos en el grupo de proyectos Java, porque le doy el ID del primer artículo de este grupo, y ya hay más de 15... ¡Ya son 22! Ni siquiera pensé que habría tantos. ¿Cómo me enteré rápidamente? ¿Crees que fue a contarlos? No) Utilicé un swager y miré la cantidad de artículos de un grupo determinado. Por cierto, puedes lucir así en otros... ¿Y cuántos artículos hay en el grupo ALEATORIO?... Te lo digo ahora: ¡hay 1062! Cantidad seria.
GO TO FULL VERSION