-
سڀني گروپن ۾ ڳولھيو جيڪي اسان جي ڊيٽابيس ۾ آھن نوان آرٽيڪل پوئين عمل کان پوء شايع ٿيل آھن.
ھي اسڪيم گروپن جو ھڪڙو ننڍڙو تعداد بيان ڪري ٿو - صرف اھي جيڪي فعال استعمال ڪندڙ آھن. ان وقت اهو مون کي منطقي لڳي رهيو هو، پر هاڻي مان سمجهان ٿو ته ان جي قطع نظر ته فعال صارف آهن ڪنهن مخصوص گروپ جي رڪنيت حاصل ڪئي آهي يا نه، توهان کي اڃا تائين جديد آرٽيڪل رکڻ جي ضرورت آهي جيڪا بوٽ تي پروسيس ڪئي وئي آهي. هڪ صورتحال پيدا ٿي سگهي ٿي جڏهن هڪ نئون صارف فوري طور تي هن گروپ جي غير فعال ٿيڻ کان پوء شايع ٿيل مضمونن جو پورو تعداد حاصل ڪري. اهو متوقع رويو نه آهي، ۽ ان کان بچڻ لاءِ، اسان کي انهن گروپن کي پنهنجي ڊيٽابيس مان رکڻو پوندو جن وٽ في الحال فعال استعمال ڪندڙ تازه ترين نه آهن. -
جيڪڏھن نوان مضمون آھن، انھن سڀني صارفين لاءِ پيغام ٺاھيو جيڪي فعال طور تي ھن گروپ ۾ رڪنيت رکن ٿا. جيڪڏهن ڪو نئون مضمون نه آهي، اسان صرف ڪم مڪمل ڪريون ٿا.
ڳوليو نئون آرٽيڪل سروس:
package com.github.javarushcommunity.jrtb.service;
/**
* Service for finding new articles.
*/
public interface FindNewArticleService {
/**
* Find new articles and notify subscribers about it.
*/
void findNewArticles();
}
بلڪل سادو، صحيح؟ اهو ان جو جوهر آهي، ۽ تمام ڏکيائي عمل ۾ ٿيندي:
package com.github.javarushcommunity.jrtb.service;
import com.github.javarushcommunity.jrtb.javarushclient.JavaRushPostClient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class FindNewArticleServiceImpl implements FindNewArticleService {
public static final String JAVARUSH_WEB_POST_FORMAT = "https://javarush.com/groups/posts/%s";
private final GroupSubService groupSubService;
private final JavaRushPostClient javaRushPostClient;
private final SendBotMessageService sendMessageService;
@Autowired
public FindNewArticleServiceImpl(GroupSubService groupSubService,
JavaRushPostClient javaRushPostClient,
SendBotMessageService sendMessageService) {
this.groupSubService = groupSubService;
this.javaRushPostClient = javaRushPostClient;
this.sendMessageService = sendMessageService;
}
@Override
public void findNewArticles() {
groupSubService.findAll().forEach(gSub -> {
List<PostInfo> newPosts = javaRushPostClient.findNewPosts(gSub.getId(), gSub.getLastArticleId());
setNewLastArticleId(gSub, newPosts);
notifySubscribersAboutNewArticles(gSub, newPosts);
});
}
private void notifySubscribersAboutNewArticles(GroupSub gSub, List<PostInfo> newPosts) {
Collections.reverse(newPosts);
List<String> messagesWithNewArticles = newPosts.stream()
.map(post -> String.format("✨Вышла новая статья <b>%s</b> в группе <b>%s</b>.✨\n\n" +
"<b>Описание:</b> %s\n\n" +
"<b>Ссылка:</b> %s\n",
post.getTitle(), gSub.getTitle(), post.getDescription(), getPostUrl(post.getKey())))
.collect(Collectors.toList());
gSub.getUsers().stream()
.filter(TelegramUser::isActive)
.forEach(it -> sendMessageService.sendMessage(it.getChatId(), messagesWithNewArticles));
}
private void setNewLastArticleId(GroupSub gSub, List<PostInfo> newPosts) {
newPosts.stream().mapToInt(PostInfo::getId).max()
.ifPresent(id -> {
gSub.setLastArticleId(id);
groupSubService.save(gSub);
});
}
private String getPostUrl(String key) {
return String.format(JAVARUSH_WEB_POST_FORMAT, key);
}
}
هتي اسان ترتيب سان هر شيء سان معاملو ڪنداسين:
-
GroupService استعمال ڪندي اسان سڀني گروپن کي ڳوليندا آهيون جيڪي ڊيٽابيس ۾ آهن.
-
پوءِ اسان سڀني گروپن ڏانهن منتشر ٿي وڃون ٿا ۽ هر هڪ لاءِ اسان آخري آرٽيڪل ۾ ٺاهيل ڪلائنٽ کي سڏين ٿا - javaRushPostClient.findNewPosts .
-
اڳيون، setNewArticleId طريقو استعمال ڪندي ، اسان پنهنجي تازي نئين آرٽيڪل جي آرٽيڪل ID کي اپڊيٽ ڪندا آهيون ته جيئن اسان جي ڊيٽابيس کي خبر پوي ته اسان اڳ ۾ ئي نئين تي پروسيس ڪري چڪا آهيون.
-
۽ انهي حقيقت کي استعمال ڪندي ته GroupSub وٽ استعمال ڪندڙن جو مجموعو آهي، اسان فعال ماڻهن جي ذريعي وڃون ٿا ۽ نون مضمونن بابت اطلاع موڪليندا آهيون.
FindNewArticleJob ٺاهيو
اسان اڳ ۾ ئي ڳالهايو آهي ته SpringScheduler ڇا آهي، پر اچو ته ان کي جلدي ورجائي: اهو پس منظر جي عمل کي ٺاهڻ لاءِ اسپرنگ فريم ورڪ ۾ هڪ ميکانيزم آهي جيڪو اسان مقرر ڪيل مخصوص وقت تي هلندو. توھان کي ھن لاءِ ڇا گھرجي؟ پهريون قدم اسان جي اسپرنگ ان پٽ ڪلاس ۾ @EnableScheduling تشريح شامل ڪرڻ آهي:package com.github.javarushcommunity.jrtb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
public class JavarushTelegramBotApplication {
public static void main(String[] args) {
SpringApplication.run(JavarushTelegramBotApplication.class, args);
}
}
ٻيو قدم هڪ ڪلاس ٺاهڻ آهي، ان کي ApplicationContext ۾ شامل ڪريو ۽ ان ۾ هڪ طريقو ٺاهيو جيڪو وقتي طور تي هلندو. اسان ھڪڙي سطح تي ھڪڙي نوڪري پيڪيج ٺاھيو آھي جيئن مخزن، خدمت، وغيره، ۽ اتي اسان ٺاھيون ٿا FindNewArticleJob ڪلاس :
package com.github.javarushcommunity.jrtb.job;
import com.github.javarushcommunity.jrtb.service.FindNewArticleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
* Job for finding new articles.
*/
@Slf4j
@Component
public class FindNewArticlesJob {
private final FindNewArticleService findNewArticleService;
@Autowired
public FindNewArticlesJob(FindNewArticleService findNewArticleService) {
this.findNewArticleService = findNewArticleService;
}
@Scheduled(fixedRateString = "${bot.recountNewArticleFixedRate}")
public void findNewArticles() {
LocalDateTime start = LocalDateTime.now();
log.info("Find new article job started.");
findNewArticleService.findNewArticles();
LocalDateTime end = LocalDateTime.now();
log.info("Find new articles job finished. Took seconds: {}",
end.toEpochSecond(ZoneOffset.UTC) - start.toEpochSecond(ZoneOffset.UTC));
}
}
هن ڪلاس کي ايپليڪيشن جي حوالي سان شامل ڪرڻ لاءِ مون استعمال ڪيو @Component تشريح . ۽ انهي ڪري ته ڪلاس جي اندر جو طريقو ڄاڻي ٿو ته ان کي وقتي طور تي هلائڻ جي ضرورت آهي، مون طريقي سان هڪ تشريح شامل ڪئي: @Scheduled(fixedRateString = "${bot.recountNewArticleFixedRate}") . پر ان جو ڪهڙو قدر ٿيندو - اسان ان کي اڳ ۾ ئي application.properties فائل ۾ مقرر ڪيو آهي:
bot.recountNewArticleFixedRate = 900000
هتي قيمت مليسيڪن ۾ آهي. اهو 15 منٽ ٿيندو. ھن طريقي ۾، سڀ ڪجھ سادو آھي: مون لاگز ۾ پنھنجي لاءِ ھڪڙو سپر سادو ميٽرڪ شامل ڪيو آھي نون مضمونن جي ڳولھا کي ڳڻڻ لاءِ، گھٽ ۾ گھٽ سمجھڻ لاءِ ته اھو ڪيترو تيزيءَ سان ڪم ڪري ٿو.
نئين ڪارڪردگي جي جانچ
ھاڻي اسان پنھنجي ٽيسٽ بوٽ تي ٽيسٽ ڪنداسين. پر ڪيئن؟ مان هر دفعي آرٽيڪل کي حذف نه ڪندس ته ڏيکاريو ته نوٽيفڪيشن اچي ويا آهن؟ بلڪل نه. اسان صرف ڊيٽابيس ۾ ڊيٽا کي ايڊٽ ڪنداسين ۽ ايپليڪيشن کي لانچ ڪنداسين. مان ان کي منهنجي ٽيسٽ سرور تي آزمائيندس. هن کي ڪرڻ لاء، اچو ته ڪجهه گروپ جي رڪنيت حاصل ڪريو. جڏهن رڪنيت مڪمل ٿي ويندي، گروپ کي تازي آرٽيڪل جي موجوده ID ڏني ويندي. اچو ته ڊيٽابيس ڏانھن وڃو ۽ قيمت ٻن مضمونن کي واپس تبديل ڪريو. نتيجي طور، اسان اميد رکون ٿا ته اتي ڪيترائي آرٽيڪل هوندا جيئن اسان اڳ ۾ LastArticleId سيٽ ڪيو . اڳيون، اسان سائيٽ تي وڃون ٿا، جاوا پروجيڪٽ گروپ ۾ آرٽيڪل کي ترتيب ڏيو - نئون پهريون - ۽ لسٽ مان ٽئين مضمون ڏانھن وڃو: اچو ته ھيٺئين مضمون ڏانھن وڃو ۽ ايڊريس بار مان اسان کي آرٽيڪل Id - 3313: اڳيون حاصل ڪيو. ، MySQL Workbench ڏانھن وڃو ۽ آخري آرٽيڪل آئي ڊي جي قيمت کي 3313 ۾ تبديل ڪريو. اچو ته ڏسون ته ھڪڙو گروپ ڊيٽابيس ۾ آھي: ۽ ان لاءِ اسين حڪم جاري ڪنداسين: ۽ اھو اھو آھي، ھاڻي توھان کي انتظار ڪرڻو پوندو ڪم جي ايندڙ لانچ تائين. نئين مضمونن جي ڳولا ڪريو. اسان کي جاوا پروجيڪٽ گروپ مان نئين مضمون بابت ٻه پيغام حاصل ڪرڻ جي اميد آهي. جيئن اهي چون ٿا، نتيجو اچڻ ۾ ڊگهو نه هو: اهو ظاهر ٿئي ٿو ته بوٽ ڪم ڪيو جيئن اسان توقع ڪئي.ختم ٿيڻ
هميشه وانگر، اسان نسخي کي pom.xml ۾ تازه ڪاري ڪريون ٿا ۽ RELEASE_NOTES ۾ هڪ داخلا شامل ڪريو ته جيئن ڪم جي تاريخ محفوظ ٿي وڃي ۽ توهان هميشه واپس وڃو ۽ سمجهي سگهو ٿا ته ڇا تبديلي آئي آهي. تنهن ڪري، اسان هڪ يونٽ طرفان نسخو وڌايو:<version>0.7.0-SNAPSHOT</version>
۽ تازه ڪاري RELEASE_NOTES:
GO TO FULL VERSION