@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);
}
Die Logik funktioniert hier: Wenn unsere Datenbank bereits einen solchen Benutzer per ChatId hat, setzen wir einfach das Feld active = true für ihn. Und wenn es keinen solchen Benutzer gibt, erstellen wir einen neuen. Das Gleiche gilt für den /stop- Befehl in 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);
}
Es ist ersichtlich, dass beim Aufruf dieses Befehls nur das Feld active = false für den Benutzer gesetzt wird. Und das ist alles: Seine Abonnements bleiben bestehen und warten in den Startlöchern, wenn der Benutzer sich erneut dazu entschließt, den Chat mit dem Bot zu aktivieren. Und es scheint, dass die Aufgabe bereits abgeschlossen ist und geschlossen werden kann. Aber es war nicht da. Die wichtigste Aufgabe besteht darin, eine Benachrichtigung über neue Artikel im Abonnement zu erstellen. Hier werden diese Aufgaben komplett aktualisiert und erledigt. Das heißt, bis wir die Benachrichtigung über neue Artikel implementiert haben, kann sie nicht geschlossen werden. Kümmern wir uns daher um die Aufgabe JRTB-4 – alle 20 Minuten einen Scheck und Benachrichtigungen über neue Artikel erstellen. Freunde! Möchten Sie sofort wissen, wann neuer Code für das Projekt veröffentlicht wird? Wann erscheint ein neuer Artikel? Treten Sie meinem TG-Kanal bei . Dort sammle ich meine Artikel, meine Gedanken, meine Open-Source-Entwicklung zusammen.
Wir implementieren JRTB-4
Was wir im Rahmen dieser Aufgabe tun müssen:-
Erstellen Sie einen Job, der regelmäßig alle Gruppen besucht, für die wir Abonnements in der Datenbank haben, Artikel nach Veröffentlichungsdatum sortieren und prüfen, ob die ID der letzten Veröffentlichung mit dem Wert in GroupSub übereinstimmt. Wenn es nicht übereinstimmt, müssen Sie genau wissen, wie viele Artikel seit dem letzten Mal veröffentlicht wurden. Wir aktualisieren last_article_id in GroupSub7 auf den aktuellen Stand.
-
Wenn wir eine Liste veröffentlichter Artikel gefunden haben, finden wir alle AKTIVEN Benutzer für diese Gruppen und senden ihnen Benachrichtigungen über neue Artikel.
Wir schreiben JavaRushPostClient
Hier werden wir nicht versuchen, alle Anfragen abzudecken, die uns in der API übergeben wurden, sondern nur diejenige erstellen, die wir benötigen. Damit erreichen wir gleich zwei Ziele:-
Wir beschleunigen den Prozess des Verfassens unserer Bewerbung.
-
Diese Arbeit überlassen wir denen, die unserer Community helfen wollen und sich dazu entschließen, sich als Entwickler zu versuchen. Ich werde dafür Aufgaben erstellen, die nach dem MVP erledigt werden können.
BaseUserInfo:
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;
}
Sprache:
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
}
LikesInfo:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents like's information.
*/
public class LikesInfo {
private Integer count;
private LikeStatus status;
}
LikeStatus:
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
}
Post-Typ:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents post types.
*/
public enum PostType {
UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}
UserPublicStatus:
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
}
Basierend auf all diesen DTOs schreiben wir eine Hauptklasse zum Empfangen von Artikeln:
Beitragsinfo:
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;
}
Lassen Sie uns nun eine Schnittstelle zum Arbeiten und deren Implementierung erstellen. Wir benötigen nur eine Methode, um mit Artikeln zu arbeiten:
JavaRushPostClient:
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 benötigt zwei Argumente: die Gruppen-ID und die letzte ID des Artikels, den der Bot bereits gepostet hat. Daher werden alle Artikel übertragen, die später als der Artikel mit lastPostId veröffentlicht wurden . Und seine Umsetzung:
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;
}
}
Wir fügen der Anfrage mehrere Filter hinzu:
- order = NEW – damit die Liste zuerst neue enthält;
- groupKid = groupId – nur nach bestimmten Gruppen suchen;
- limit = 15 – wir begrenzen die Anzahl der Artikel pro Anfrage. Unsere Frequenz beträgt 15-20 Minuten und wir gehen davon aus, dass in dieser Zeit nicht MEHR als 15 (!) geschrieben werden.
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());
}
}
Hierbei handelt es sich um einen sehr einfachen Test, der überprüft, ob überhaupt eine Kommunikation mit dem Client stattfindet oder nicht. Er findet 15 neue Artikel in der Gruppe „Java-Projekte“, weil ich ihm die ID des ersten Artikels in dieser Gruppe gebe, und es sind bereits mehr als 15 davon … Es sind bereits 22 davon! Ich hätte nicht einmal gedacht, dass es so viele davon geben würden. Wie habe ich es schnell herausgefunden? Glaubst du, er ging, um sie zu zählen? Nein) Ich habe einen Swager verwendet und mir die Anzahl der Artikel für eine bestimmte Gruppe angesehen. So kann man übrigens auch bei anderen aussehen... Und wie viele Artikel gibt es in der RANDOM-Gruppe?... Ich verrate es euch jetzt: Es sind 1062 davon! Ernsthafte Menge.
GO TO FULL VERSION