@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);
}
Tutaj działa logika: jeśli w naszej bazie danych jest już taki użytkownik o chatId, to po prostu ustawiamy dla niego pole active=true. A jeśli nie ma takiego użytkownika, tworzymy nowego. To samo dotyczy polecenia /stop w 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);
}
Można zauważyć, że przy wywołaniu tego polecenia dla użytkownika ustawiane jest tylko pole active = false. I tyle: jego subskrypcje przetrwają i poczekają, gdy użytkownik ponownie zdecyduje się aktywować czat z botem. I wydawałoby się, że zadanie zostało już wykonane i można je zamknąć. Ale tego tam nie było. Najważniejszym zadaniem jest utworzenie alertu o nowych artykułach w prenumeracie. Tutaj te zadania zostaną całkowicie zaktualizowane i zakończone. Oznacza to, że dopóki nie wdrożymy powiadamiania o nowych artykułach, nie można go zamknąć. Dlatego zajmijmy się zadaniem JRTB-4 - tworzeniem czeku co 20 minut i powiadomień o nowych artykułach. Przyjaciele! Chcesz wiedzieć od razu, kiedy zostanie wydany nowy kod projektu? Kiedy pojawi się nowy artykuł? Dołącz do mojego kanału tg . Gromadzę tam moje artykuły, przemyślenia i rozwój open source.
Wdrażamy JRTB-4
Co musimy zrobić w ramach tego zadania:-
Utwórz zadanie, które będzie okresowo odwiedzać wszystkie grupy, dla których mamy subskrypcje w bazie, sortować artykuły według daty publikacji i sprawdzać, czy identyfikator ostatniej publikacji odpowiada wartości w GroupSub. Jeśli się nie zgadza, musisz dokładnie zrozumieć, ile artykułów zostało opublikowanych od ostatniego razu. Aktualizujemy last_article_id w GroupSub7 do bieżącego stanu.
-
Kiedy znajdziemy listę opublikowanych artykułów, wyszukujemy wszystkich AKTYWNYCH użytkowników tych grup i wysyłamy im powiadomienia o nowych artykułach.
Piszemy JavaRushPostClient
Tutaj nie będziemy się starali opisywać wszystkich żądań, które zostały do nas przesłane w API i utworzymy tylko to, które będzie nam potrzebne. W ten sposób osiągamy dwa cele jednocześnie:-
Przyspieszamy proces pisania naszej aplikacji.
-
Tę pracę pozostawiamy tym, którzy chcą pomóc naszej społeczności i decydują się spróbować swoich sił jako programista. Zrobię do tego zadania, które będzie można wykonać po MVP.
Podstawowe informacje o użytkowniku:
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;
}
Język:
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
}
Informacje o polubieniach:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents like's information.
*/
public class LikesInfo {
private Integer count;
private LikeStatus status;
}
LubięStan:
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
}
Typ postu:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents post types.
*/
public enum PostType {
UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}
Stan użytkownika publicznego:
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
}
W oparciu o wszystkie te DTO napiszmy główną klasę, aby otrzymywać artykuły:
Informacje o wpisie:
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;
}
Stwórzmy teraz interfejs do pracy i jego implementację. Do pracy z artykułami będziemy potrzebować tylko jednej metody:
Klient 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 przyjmuje dwa argumenty: identyfikator grupy i ostatni identyfikator artykułu, który bot już opublikował. Dlatego wszystkie artykuły, które zostały opublikowane później niż artykuł z lastPostId, zostaną przesłane . I jego realizacja:
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;
}
}
Do żądania dodajemy kilka filtrów:
- Order = NEW - tak, aby lista zawierała najpierw nowe;
- groupKid = groupId - wyszukaj tylko określone grupy;
- limit = 15 — ograniczamy liczbę artykułów na żądanie. Nasza częstotliwość wynosi 15-20 minut i spodziewamy się, że w tym czasie nie zostanie napisanych WIĘCEJ niż 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());
}
}
To bardzo prosty test, który sprawdza, czy w ogóle jest komunikacja z klientem, czy też nie. Znajduje 15 nowych artykułów w grupie Projekty Java, bo podaję mu ID pierwszego artykułu w tej grupie, a jest ich już ponad 15... Jest ich już 22! Nawet nie przypuszczałam, że będzie ich tak dużo. Jak się tego szybko dowiedziałem? Myślisz, że poszedł je policzyć? Nie) Użyłem przechwałki i sprawdziłem liczbę artykułów dla określonej grupy. Swoją drogą, w innych też możesz tak wyglądać... A ile artykułów jest w grupie RANDOM?... Już Ci powiem: jest ich 1062! Poważna kwota.
GO TO FULL VERSION