สวัสดีทุกคนเพื่อนรักของฉัน ทีละขั้นตอนเราเข้าใกล้เป้าหมายของเรามากขึ้น - เพื่อเป็น MVP ของโครงการของเรา - JavaRush Telegram Bot อย่างที่ผมบอกไปแล้วในบทความที่แล้ว เหลือเพียง 5 งานเท่านั้น วันนี้เราจะกล่าวถึงสองเรื่อง อยากจะย้ำว่าโครงการจะไม่จบแค่นี้ ฉันยังมีแนวคิดและวิสัยทัศน์มากมายว่าโครงการนี้ควรพัฒนาอย่างไร มีอะไรใหม่ๆ ที่สามารถเพิ่มเข้าไปได้ และอะไรจะทำได้ดีกว่านี้ ก่อน MVP เราจะจัดทำบทความแยกต่างหากในหัวข้อการรีแฟคเตอร์ - นั่นคือเกี่ยวกับการปรับปรุงคุณภาพของโค้ดโดยไม่ต้องเปลี่ยนฟังก์ชันการทำงาน เมื่อถึงเวลานั้น โครงการทั้งหมดจะสามารถมองเห็นได้ และจะชัดเจนว่าสิ่งใดและสิ่งใดที่สามารถปรับปรุงได้ ในกรณีของเรา เราจะได้รับการปกป้องสูงสุดจากการทำลายฟังก์ชันการทำงาน เนื่องจากมีการเขียนการทดสอบจำนวนมาก เราจะเขียนย้อนหลังเกี่ยวกับสิ่งที่เราต้องการและสิ่งที่เราได้ในที่สุด นี่เป็นสิ่งที่มีประโยชน์มาก เรามาดูกันว่าทุกอย่างถูกต้องแค่ไหนเมื่อหกเดือนที่แล้ว อย่างน้อยนี่ก็น่าสนใจมากสำหรับฉัน หากใครอยากลองใช้ตัวเองในฐานะผู้ทดสอบด้วยตนเอง เขียนถึงเรา แล้วเราจะร่วมมือกัน มาทำให้โครงการนี้ดีขึ้นด้วยกัน! ดังนั้นนี่คือ: สองงานที่อธิบายไว้เมื่อหกเดือนที่แล้ว: JRTB-8และJRTB-9 . ฉันเริ่มมองหาสิ่งที่จำเป็นต้องนำไปใช้สำหรับงานเหล่านี้ และตระหนักว่าในแง่ของการเรียกใช้คำสั่ง ทุกอย่างพร้อมแล้ว มันเกิดขึ้น...) ที่นี่คุณสามารถดูStartCommandวิธีการดำเนินการ :
เช่น - สมัครสมาชิก - กดกริ่งให้ ดาว โครงการของเราเขียนความคิดเห็นและให้คะแนนบทความ! ขอบคุณทุกท่านที่อ่าน - แล้วพบกันใหม่!
@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);
}
ตรรกะใช้งานได้ที่นี่: หากฐานข้อมูลของเรามีผู้ใช้ดังกล่าวตาม chatId อยู่แล้ว เราก็เพียงตั้งค่าฟิลด์ active = true ให้กับเขา และหากไม่มีผู้ใช้ดังกล่าว เราจะสร้างผู้ใช้ใหม่ เช่นเดียวกับ คำสั่ง /stopใน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);
}
จะเห็นได้ว่าเมื่อเรียกใช้คำสั่งนี้เฉพาะฟิลด์ active = false เท่านั้นที่ถูกตั้งค่าสำหรับผู้ใช้ และนั่นคือทั้งหมด: การสมัครสมาชิกของเขาจะคงอยู่และรออยู่ในปีกเมื่อผู้ใช้ตัดสินใจเปิดใช้งานการแชทกับบอทอีกครั้ง และดูเหมือนว่างานจะเสร็จสิ้นแล้วและสามารถปิดได้ แต่มันไม่ได้อยู่ที่นั่น งานที่สำคัญที่สุดคือสร้างการแจ้งเตือนเกี่ยวกับบทความใหม่ในการสมัครสมาชิก นี่คือจุดที่งานเหล่านี้จะได้รับการอัปเดตและเสร็จสมบูรณ์อย่างสมบูรณ์ นั่นคือจนกว่าเราจะดำเนินการแจ้งเตือนบทความใหม่ ก็ไม่สามารถปิดได้ ดังนั้นมาจัดการงาน JRTB-4 กันเถอะ - สร้างเช็คทุก ๆ 20 นาทีและแจ้งเตือนเกี่ยวกับบทความใหม่ เพื่อน! คุณต้องการทราบทันทีเมื่อมีการเปิดตัวรหัสใหม่สำหรับโครงการหรือไม่? เมื่อไหร่จะมีบทความใหม่ออกมา? เข้าร่วมช่อง tg ของ ฉัน ที่นั่นฉันรวบรวมบทความ ความคิด และการพัฒนาโอเพ่นซอร์สของฉันไว้ด้วยกัน
เราใช้ JRTB-4
สิ่งที่เราต้องทำเพื่อเป็นส่วนหนึ่งของงานนี้:-
สร้างงานที่จะเยี่ยมชมกลุ่มทั้งหมดที่เราสมัครสมาชิกในฐานข้อมูลเป็นระยะๆ จัดเรียงบทความตามวันที่ตีพิมพ์ และตรวจสอบว่า ID ของการตีพิมพ์ครั้งล่าสุดตรงกับค่าใน GroupSub หรือไม่ หากไม่ตรงกัน ก็ต้องทำความเข้าใจให้แน่ชัดว่ามีบทความกี่บทความที่ได้รับการตีพิมพ์ตั้งแต่ครั้งล่าสุด เราอัปเดต Last_article_id ใน GroupSub7 เป็นสถานะปัจจุบัน
-
เมื่อเราพบรายการบทความที่เผยแพร่ เราจะค้นหาผู้ใช้ที่ใช้งานอยู่ทั้งหมดของกลุ่มเหล่านี้ และส่งการแจ้งเตือนเกี่ยวกับบทความใหม่ให้พวกเขา
/api/1.0/rest/posts รับโพสต์ตามตัวกรอง
เราจะดำเนินการตามคำขอนี้ เราต้องการอะไรในนั้น? รับรายชื่อบทความที่อยู่ในกลุ่มเฉพาะ และควรจัดเรียงตามวันที่ตีพิมพ์ วิธีนี้ทำให้เราสามารถนำ 15 บทความล่าสุดและตรวจสอบว่ามีการเผยแพร่สิ่งพิมพ์ใหม่ตามLastArticleIdจากฐานข้อมูลของเราหรือไม่ หากมีเราจะส่งต่อเพื่อประมวลผลและส่งไปยังผู้ใช้ ดังนั้นเราต้องเขียนJavaRushPostClient
เราเขียน JavaRushPostClient
ที่นี่เราจะไม่พยายามครอบคลุมคำขอทั้งหมดที่ส่งถึงเราใน API และจะสร้างเฉพาะคำขอที่เราต้องการเท่านั้น การทำเช่นนี้ทำให้เราบรรลุเป้าหมายสองประการพร้อมกัน:-
เราเร่งกระบวนการเขียนใบสมัครของเราให้เร็วขึ้น
-
เราปล่อยให้งานนี้ตกเป็นของผู้ที่ต้องการช่วยเหลือชุมชนของเราและตัดสินใจลองใช้ตัวเองในฐานะนักพัฒนา ฉันจะทำงานนี้ให้สำเร็จได้หลังจาก MVP
ข้อมูลผู้ใช้ฐาน:
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;
}
ภาษา:
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
}
ข้อมูลที่ชอบ:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents like's information.
*/
public class LikesInfo {
private Integer count;
private LikeStatus status;
}
ชอบสถานะ:
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
}
ประเภทโพสต์:
package com.github.javarushcommunity.jrtb.javarushclient.dto;
/**
* DTO, which represents post types.
*/
public enum PostType {
UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}
สถานะสาธารณะของผู้ใช้:
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
}
จาก DTO ทั้งหมดนี้ มาเขียนชั้นเรียนหลักเพื่อรับบทความกัน:
ข้อมูลโพสต์:
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;
}
ตอนนี้เรามาสร้างอินเทอร์เฟซที่จะใช้งานและการใช้งานกันดีกว่า เราต้องการเพียงวิธีเดียวในการทำงานกับบทความ:
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รับสองอาร์กิวเมนต์: ID กลุ่มและ ID สุดท้ายของบทความที่บอทได้โพสต์ไว้แล้ว ดังนั้น บทความทั้งหมดที่เผยแพร่ช้ากว่าบทความที่มีLastPostId จะถูกส่งต่อ และการนำไปปฏิบัติ:
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;
}
}
เราเพิ่มตัวกรองหลายรายการให้กับคำขอ:
- order = NEW - เพื่อให้รายการมีรายการใหม่ก่อน
- groupKid = groupId - ค้นหาเฉพาะบางกลุ่มเท่านั้น
- ขีดจำกัด = 15 — เราจำกัดจำนวนบทความต่อคำขอ ความถี่ของเราคือ 15-20 นาที และเราคาดหวังว่าในช่วงเวลานี้จะเขียนได้ไม่เกิน 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());
}
}
นี่เป็นการทดสอบง่ายๆ ที่จะตรวจสอบว่ามีการสื่อสารกับลูกค้าเลยหรือไม่ เขาพบบทความใหม่ 15 บทความในกลุ่มโครงการ Java เพราะฉันให้ ID ของบทความแรกในกลุ่มนี้แก่เขาและมีมากกว่า 15 บทความแล้ว... มี 22 บทความแล้ว! ไม่คิดว่าจะมีเยอะขนาดนี้ ฉันรู้ได้อย่างไรอย่างรวดเร็ว? คุณคิดว่าเขาไปนับพวกเขาเหรอ? ไม่) ฉันใช้คำสวาทและดูจำนวนบทความของกลุ่มใดกลุ่มหนึ่ง ยังไงก็ตามคุณสามารถดูแบบนี้ในคนอื่น ๆ ได้... และมีบทความกี่บทความในกลุ่ม RANDOM?... ฉันจะบอกคุณตอนนี้: มี 1,062 บทความ! ปริมาณที่ร้ายแรง
GO TO FULL VERSION