JavaRush /Blog Java /Random-MS /Kami menambah keupayaan untuk melanggan kumpulan artikel....

Kami menambah keupayaan untuk melanggan kumpulan artikel. (Bahagian 2) - "Projek Java dari A hingga Z"

Diterbitkan dalam kumpulan
Hai semua! Kami terus mengerjakan tugas yang kami mulakan minggu lepas ."Projek Java dari A hingga Z": Menambah keupayaan untuk melanggan sekumpulan artikel.  Bahagian 2 - 1

Kami melaksanakan JRTB-5

Sekarang kita perlu menambah arahan supaya kita boleh melanggan beberapa kumpulan artikel daripada JavaRush. Bagaimana hendak melakukannya? Kami akan mengikuti senario paling mudah yang saya buat. Memandangkan kami mempunyai akses melalui ID kumpulan, kami memerlukan pengguna untuk memindahkannya. Untuk melakukan ini, pengguna akan memasukkan arahan /addGroupSub GROUP_ID, yang akan berfungsi dalam salah satu daripada dua cara: jika hanya arahan itu sendiri datang: /addGroupSub , senarai semua kumpulan dan ID mereka dihantar sebagai balasan. Kemudian pengguna akan dapat memilih ID kumpulan yang dia perlukan dan mencipta versi kedua permintaan dalam arahan ini: /addGroupSub GROUP_ID - dan kemudian akan ada rekod kumpulan ini dengan pengguna ini. Saya fikir kita boleh melakukan yang lebih baik pada masa hadapan. Matlamat kami adalah untuk menunjukkan perkembangan, dan bukan pengalaman pengguna yang sangat hebat (saya malu untuk mengatakannya, tetapi saya tidak tahu istilah dalam bahasa Rusia yang bermaksud ini). Untuk menambah fungsi yang melalui keseluruhan aplikasi dengan betul (dalam kes kami, dari klien bot telegram ke pangkalan data), anda perlu bermula pada satu hujung. Kami akan melakukan ini dari sisi pangkalan data.

Menambah migrasi baharu ke pangkalan data

Perkara pertama yang perlu dilakukan ialah menambah penghijrahan pangkalan data baharu dan keupayaan untuk menyimpan data langganan kumpulan pengguna dalam JR. Untuk mengingati keadaan yang sepatutnya, kembali ke artikel " Perancangan projek: ukur tujuh kali ." Terdapat dalam foto kedua terdapat gambar rajah anggaran pangkalan data. Kita perlu menambah jadual untuk menyimpan maklumat kumpulan:
  • ID kumpulan dalam JavaRush juga akan menjadi ID kami. Kami mempercayai mereka dan percaya bahawa ID ini adalah unik;
  • tajuk - dalam gambar kami ia adalah nama - nama tidak rasmi kumpulan; iaitu, apa yang kita lihat di laman web JavaRush;
  • last_article_id - dan ini adalah medan yang menarik. Ia akan menyimpan ID terakhir artikel dalam kumpulan ini, yang bot telah dihantar kepada pelanggannya. Menggunakan medan ini, mekanisme untuk mencari artikel baharu akan berfungsi. Pelanggan baharu tidak akan menerima artikel yang diterbitkan sebelum pengguna melanggan: hanya artikel yang diterbitkan selepas melanggan kumpulan.
Kami juga akan mempunyai hubungan banyak-ke-banyak antara kumpulan dan jadual pengguna, kerana setiap pengguna boleh mempunyai banyak langganan kumpulan (satu-ke-banyak), dan setiap langganan kumpulan boleh mempunyai ramai pengguna (satu-ke-banyak, sahaja di sebelah sana). Ternyata ini akan menjadi ramai-ke-banyak kita. Bagi mereka yang mempunyai soalan, semak artikel dalam pangkalan data. Ya, saya tidak lama lagi merancang untuk membuat siaran di saluran Telegram, di mana saya akan mengumpulkan semua artikel pada pangkalan data. Inilah rupa migrasi pangkalan data kedua kami.
V00002__created_groupsub_many_to_many.sql:

-- add PRIMARY KEY FOR tg_user
ALTER TABLE tg_user ADD PRIMARY KEY (chat_id);

-- ensure that the tables with these names are removed before creating a new one.
DROP TABLE IF EXISTS group_sub;
DROP TABLE IF EXISTS group_x_user;

CREATE TABLE group_sub (
   id INT,
   title VARCHAR(100),
   last_article_id INT,
   PRIMARY KEY (id)
);

CREATE TABLE group_x_user (
   group_sub_id INT NOT NULL,
   user_id VARCHAR(100) NOT NULL,
   FOREIGN KEY (user_id) REFERENCES tg_user(chat_id),
   FOREIGN KEY (group_sub_id) REFERENCES group_sub(id),
   UNIQUE(user_id, group_sub_id)
);
Adalah penting untuk ambil perhatian bahawa pertama saya menukar jadual lama - saya menambah kunci utama kepadanya. Saya entah bagaimana terlepas ini pada masa itu, tetapi sekarang MySQL tidak memberi saya peluang untuk menambah KUNCI ASING untuk jadual gorup_x_user, dan sebagai sebahagian daripada penghijrahan ini saya mengemas kini pangkalan data. Sila ambil perhatian satu aspek penting. Menukar pangkalan data harus dilakukan dengan cara ini - semua yang diperlukan adalah dalam migrasi baharu, tetapi bukan dengan mengemas kini migrasi yang telah dikeluarkan. Ya, dalam kes kami tiada apa yang akan berlaku, kerana ini adalah projek ujian dan kami tahu bahawa ia digunakan di satu tempat sahaja, tetapi ini adalah pendekatan yang salah. Tetapi kami mahu semuanya betul. Seterusnya ialah memadamkan jadual sebelum menciptanya. kenapa ni? Supaya jika kebetulan terdapat jadual dengan nama sedemikian dalam pangkalan data, penghijrahan tidak akan gagal dan akan berfungsi dengan tepat seperti yang diharapkan. Dan kemudian kami menambah dua jadual. Semuanya seperti yang kita mahukan. Sekarang kita perlu melancarkan aplikasi kita. Jika semuanya bermula dan tidak pecah, maka penghijrahan direkodkan. Dan untuk menyemak semula ini, kami pergi ke pangkalan data untuk memastikan bahawa: a) jadual sedemikian telah muncul; b) terdapat kemasukan baru dalam jadual teknikal flyway. Ini melengkapkan kerja migrasi, mari kita beralih ke repositori.

Menambah lapisan repositori

Terima kasih kepada Spring Boot Data, semuanya sangat mudah di sini: kami perlu menambah entiti GroupSub, mengemas kini sedikit TelegramUser dan menambah GroupSubRepository yang hampir kosong: Kami menambah entiti GroupSub pada pakej yang sama seperti TelegramUser:
package com.github.javarushcommunity.jrtb.repository.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

import static java.util.Objects.isNull;

@Data
@Entity
@Table(name = "group_sub")
@EqualsAndHashCode
public class GroupSub {

   @Id
   private Integer id;

   @Column(name = "title")
   private String title;

   @Column(name = "last_article_id")
   private Integer lastArticleId;

   @ManyToMany(fetch = FetchType.EAGER)
   @JoinTable(
           name = "group_x_user",
           joinColumns = @JoinColumn(name = "group_sub_id"),
           inverseJoinColumns = @JoinColumn(name = "user_id")
   )
   private List<TelegramUser> users;

   public void addUser(TelegramUser telegramUser) {
       if (isNull(users)) {
           users = new ArrayList<>();
       }
       users.add(telegramUser);
   }
}
Satu perkara yang perlu diberi perhatian ialah kami mempunyai medan pengguna tambahan yang akan mengandungi koleksi semua pengguna yang melanggan kumpulan itu. Dan dua anotasi - ManyToMany dan JoinTable - adalah apa yang kami perlukan untuk ini. Medan yang sama perlu ditambah untuk TelegramUser:
@ManyToMany(mappedBy = "users", fetch = FetchType.EAGER)
private List<GroupSub> groupSubs;
Medan ini menggunakan gabungan yang ditulis dalam entiti GroupSub. Dan, sebenarnya, kelas repositori kami untuk GroupSub ialah GroupSubRepository :
package com.github.javarushcommunity.jrtb.repository;

import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
* {@link Repository} for {@link GroupSub} entity.
*/
@Repository
public interface GroupSubRepository extends JpaRepository<GroupSub, Integer> {
}
Pada peringkat ini, kami tidak memerlukan kaedah tambahan: yang dilaksanakan dalam nenek moyang JpaRepository sudah cukup untuk kami. Mari tulis ujian dalam TelegramUserRepositoryIT yang akan menyemak bahawa banyak-ke-banyak kerja kami. Idea ujian ialah kami akan menambah 5 kumpulan langganan setiap pengguna ke pangkalan data melalui skrip sql, dapatkan pengguna ini dengan IDnya dan semak sama ada kami menerima kumpulan tersebut dengan tepat dan dengan nilai yang sama. Bagaimana hendak melakukannya? Anda boleh membenamkan pembilang ke dalam data, yang kemudiannya boleh kami lalui dan semak. Berikut ialah skrip fiveGroupSubsForUser.sql:
INSERT INTO tg_user VALUES (1, 1);

INSERT INTO group_sub VALUES
(1, 'g1', 1),
(2, 'g2', 2),
(3, 'g3', 3),
(4, 'g4', 4),
(5, 'g5', 5);

INSERT INTO group_x_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);
Dan ujian itu sendiri:
@Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveGroupSubsForUser.sql"})
@Test
public void shouldProperlyGetAllGroupSubsForUser() {
   //when
   Optional<TelegramUser> userFromDB = telegramUserRepository.findById("1");

   //then
   Assertions.assertTrue(userFromDB.isPresent());
   List<GroupSub> groupSubs = userFromDB.get().getGroupSubs();
   for (int i = 0; i < groupSubs.size(); i++) {
       Assertions.assertEquals(String.format("g%s", (i + 1)), groupSubs.get(i).getTitle());
       Assertions.assertEquals(i + 1, groupSubs.get(i).getId());
       Assertions.assertEquals(i + 1, groupSubs.get(i).getLastArticleId());
   }
}
Sekarang mari kita tambahkan ujian makna yang sama untuk entiti GroupSub. Untuk melakukan ini, mari buat kelas ujian groupSubRepositoryIT dalam pakej yang sama seperti groupSubRepositoryIT :
package com.github.javarushcommunity.jrtb.repository;

import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.jdbc.Sql;

import java.util.List;
import java.util.Optional;

import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE;

/**
* Integration-level testing for {@link GroupSubRepository}.
*/
@ActiveProfiles("test")
@DataJpaTest
@AutoConfigureTestDatabase(replace = NONE)
public class GroupSubRepositoryIT {

   @Autowired
   private GroupSubRepository groupSubRepository;

   @Sql(scripts = {"/sql/clearDbs.sql", "/sql/fiveUsersForGroupSub.sql"})
   @Test
   public void shouldProperlyGetAllUsersForGroupSub() {
       //when
       Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(1);

       //then
       Assertions.assertTrue(groupSubFromDB.isPresent());
       Assertions.assertEquals(1, groupSubFromDB.get().getId());
       List<TelegramUser> users = groupSubFromDB.get().getUsers();
       for(int i=0; i<users.size(); i++) {
           Assertions.assertEquals(String.valueOf(i + 1), users.get(i).getChatId());
           Assertions.assertTrue(users.get(i).isActive());
       }
   }
}
Dan skrip fiveUsersForGroupSub.sql yang hilang:
INSERT INTO tg_user VALUES
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);

INSERT INTO group_sub VALUES (1, 'g1', 1);

INSERT INTO group_x_user VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5);
Pada ketika ini, sebahagian daripada kerja dengan repositori boleh dianggap selesai. Sekarang mari kita tulis lapisan perkhidmatan.

Kami menulis GroupSubService

Pada peringkat ini, untuk bekerja dengan kumpulan langganan, kami hanya perlu dapat menyimpannya, jadi tiada masalah: kami mencipta perkhidmatan GroupSubService dan pelaksanaan GroupSubServiceImpl dalam pakej yang mengandungi perkhidmatan lain - perkhidmatan:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;

/**
* Service for manipulating with {@link GroupSub}.
*/
public interface GroupSubService {

   GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo);
}
Dan pelaksanaannya:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
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 javax.ws.rs.NotFoundException;
import java.util.Optional;

@Service
public class GroupSubServiceImpl implements GroupSubService {

   private final GroupSubRepository groupSubRepository;
   private final TelegramUserService telegramUserService;

   @Autowired
   public GroupSubServiceImpl(GroupSubRepository groupSubRepository, TelegramUserService telegramUserService) {
       this.groupSubRepository = groupSubRepository;
       this.telegramUserService = telegramUserService;
   }

   @Override
   public GroupSub save(String chatId, GroupDiscussionInfo groupDiscussionInfo) {
       TelegramUser telegramUser = telegramUserService.findByChatId(chatId).orElseThrow(NotFoundException::new);
       //TODO add exception handling
       GroupSub groupSub;
       Optional<GroupSub> groupSubFromDB = groupSubRepository.findById(groupDiscussionInfo.getId());
       if(groupSubFromDB.isPresent()) {
           groupSub = groupSubFromDB.get();
           Optional<TelegramUser> first = groupSub.getUsers().stream()
                   .filter(it -> it.getChatId().equalsIgnoreCase(chatId))
                   .findFirst();
           if(first.isEmpty()) {
               groupSub.addUser(telegramUser);
           }
       } else {
           groupSub = new GroupSub();
           groupSub.addUser(telegramUser);
           groupSub.setId(groupDiscussionInfo.getId());
           groupSub.setTitle(groupDiscussionInfo.getTitle());
       }
       return groupSubRepository.save(groupSub);
   }
}
Agar Data Spring berfungsi dengan betul dan rekod banyak-ke-banyak dibuat, kami perlu mendapatkan pengguna daripada pangkalan data kami untuk kumpulan langganan yang kami cipta dan menambahkannya pada objek GroupSub. Oleh itu, apabila kami memindahkan langganan ini untuk menyimpan, sambungan juga akan dibuat melalui jadual group_x_user. Mungkin terdapat situasi apabila kumpulan langganan sedemikian telah dibuat dan anda hanya perlu menambah pengguna lain padanya. Untuk melakukan ini, kami mula-mula mendapatkan ID kumpulan daripada pangkalan data, dan jika terdapat rekod, kami bekerja dengannya, jika tidak, kami mencipta yang baharu. Adalah penting untuk ambil perhatian bahawa untuk bekerja dengan TelegramUser kami menggunakan TelegramUserService untuk mengikuti prinsip SOLID yang terakhir. Pada masa ini, jika kita tidak menemui rekod mengikut ID, saya hanya membuang pengecualian. Ia tidak diproses dalam apa-apa cara sekarang: kami akan melakukan ini pada penghujungnya, sebelum MVP. Mari tulis dua ujian unit untuk kelas GroupSubServiceTest . Mana satu yang kita perlukan? Saya ingin memastikan bahawa kaedah simpan akan dipanggil dalam GroupSubRepository dan entiti dengan satu pengguna tunggal akan dihantar ke GroupSub - yang akan mengembalikan TelegramUserService kepada kami menggunakan ID yang disediakan. Dan pilihan kedua, apabila kumpulan dengan ID yang sama sudah berada dalam pangkalan data dan kumpulan ini sudah mempunyai satu pengguna, dan anda perlu menyemak bahawa pengguna lain akan ditambahkan ke kumpulan ini dan objek ini akan disimpan. Berikut adalah pelaksanaannya:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.repository.GroupSubRepository;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.repository.entity.TelegramUser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.Optional;

@DisplayName("Unit-level testing for GroupSubService")
public class GroupSubServiceTest {

   private GroupSubService groupSubService;
   private GroupSubRepository groupSubRepository;
   private TelegramUser newUser;

   private final static String CHAT_ID = "1";

   @BeforeEach
   public void init() {
       TelegramUserService telegramUserService = Mockito.mock(TelegramUserService.class);
       groupSubRepository = Mockito.mock(GroupSubRepository.class);
       groupSubService = new GroupSubServiceImpl(groupSubRepository, telegramUserService);

       newUser = new TelegramUser();
       newUser.setActive(true);
       newUser.setChatId(CHAT_ID);

       Mockito.when(telegramUserService.findByChatId(CHAT_ID)).thenReturn(Optional.of(newUser));
   }

   @Test
   public void shouldProperlySaveGroup() {
       //given

       GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
       groupDiscussionInfo.setId(1);
       groupDiscussionInfo.setTitle("g1");

       GroupSub expectedGroupSub = new GroupSub();
       expectedGroupSub.setId(groupDiscussionInfo.getId());
       expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
       expectedGroupSub.addUser(newUser);

       //when
       groupSubService.save(CHAT_ID, groupDiscussionInfo);

       //then
       Mockito.verify(groupSubRepository).save(expectedGroupSub);
   }

   @Test
   public void shouldProperlyAddUserToExistingGroup() {
       //given
       TelegramUser oldTelegramUser = new TelegramUser();
       oldTelegramUser.setChatId("2");
       oldTelegramUser.setActive(true);

       GroupDiscussionInfo groupDiscussionInfo = new GroupDiscussionInfo();
       groupDiscussionInfo.setId(1);
       groupDiscussionInfo.setTitle("g1");

       GroupSub groupFromDB = new GroupSub();
       groupFromDB.setId(groupDiscussionInfo.getId());
       groupFromDB.setTitle(groupDiscussionInfo.getTitle());
       groupFromDB.addUser(oldTelegramUser);

       Mockito.when(groupSubRepository.findById(groupDiscussionInfo.getId())).thenReturn(Optional.of(groupFromDB));

       GroupSub expectedGroupSub = new GroupSub();
       expectedGroupSub.setId(groupDiscussionInfo.getId());
       expectedGroupSub.setTitle(groupDiscussionInfo.getTitle());
       expectedGroupSub.addUser(oldTelegramUser);
       expectedGroupSub.addUser(newUser);

       //when
       groupSubService.save(CHAT_ID, groupDiscussionInfo);

       //then
       Mockito.verify(groupSubRepository).findById(groupDiscussionInfo.getId());
       Mockito.verify(groupSubRepository).save(expectedGroupSub);
   }

}
Saya juga menambah kaedah init() dengan anotasi BeforeEach. Dengan cara ini, mereka biasanya mencipta kaedah yang akan dilaksanakan sebelum setiap ujian dijalankan, dan adalah mungkin untuk meletakkan logik biasa ke dalamnya untuk semua ujian. Dalam kes kami, kami perlu mengunci TelegramUserService dengan cara yang sama untuk semua ujian kelas ini, jadi masuk akal untuk memindahkan logik ini kepada kaedah biasa. Terdapat dua reka bentuk mokito yang digunakan di sini:
  • Mockito.when(o1.m1(a1)).thenReturn(o2) - di dalamnya kita katakan bahawa apabila kaedah m1 dipanggil pada objek o1 dengan hujah a1 , kaedah akan mengembalikan objek o2 . Ini adalah hampir fungsi paling penting mockito - untuk memaksa objek olok-olok mengembalikan dengan tepat apa yang kita perlukan;

  • Mockito.verify(o1).m1(a1) - yang mengesahkan bahawa kaedah m1 dipanggil pada objek o1 dengan hujah a1 . Sudah tentu, mungkin untuk menggunakan objek yang dikembalikan bagi kaedah simpan, tetapi saya memutuskan untuk menjadikannya lebih rumit dengan menunjukkan kaedah lain yang mungkin. Bilakah ia boleh berguna? Dalam kes di mana kaedah kelas olok-olok mengembalikan batal. Kemudian tanpa Mockito.verify tidak akan ada kerja)))

Kami terus berpegang kepada idea bahawa ujian perlu ditulis, dan banyak daripadanya perlu ditulis. Peringkat seterusnya bekerja dengan pasukan bot telegram.

Buat arahan /addGroupSub

Di sini kita perlu melaksanakan logik berikut: jika kita hanya menerima arahan, tanpa sebarang konteks, kami membantu pengguna dan memberinya senarai semua kumpulan dengan ID mereka supaya dia boleh menghantar maklumat yang diperlukan kepada bot. Dan jika pengguna menghantar arahan kepada bot dengan beberapa perkataan lain - cari kumpulan dengan ID itu atau tulis bahawa tiada kumpulan sedemikian. Mari tambah nilai baharu dalam ename kami - CommandName:
ADD_GROUP_SUB("/addgroupsub")
Mari kita beralih lebih jauh dari pangkalan data ke bot telegram - buat kelas AddGroupSubCommand dalam pakej arahan:
package com.github.javarushcommunity.jrtb.command;

import com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.repository.entity.GroupSub;
import com.github.javarushcommunity.jrtb.service.GroupSubService;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import org.telegram.telegrambots.meta.api.objects.Update;

import java.util.stream.Collectors;

import static com.github.javarushcommunity.jrtb.command.CommandName.ADD_GROUP_SUB;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getChatId;
import static com.github.javarushcommunity.jrtb.command.CommandUtils.getMessage;
import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.SPACE;
import static org.apache.commons.lang3.StringUtils.isNumeric;

/**
* Add Group subscription {@link Command}.
*/
public class AddGroupSubCommand implements Command {

   private final SendBotMessageService sendBotMessageService;
   private final JavaRushGroupClient javaRushGroupClient;
   private final GroupSubService groupSubService;

   public AddGroupSubCommand(SendBotMessageService sendBotMessageService, JavaRushGroupClient javaRushGroupClient,
                             GroupSubService groupSubService) {
       this.sendBotMessageService = sendBotMessageService;
       this.javaRushGroupClient = javaRushGroupClient;
       this.groupSubService = groupSubService;
   }

   @Override
   public void execute(Update update) {
       if (getMessage(update).equalsIgnoreCase(ADD_GROUP_SUB.getCommandName())) {
           sendGroupIdList(getChatId(update));
           return;
       }
       String groupId = getMessage(update).split(SPACE)[1];
       String chatId = getChatId(update);
       if (isNumeric(groupId)) {
           GroupDiscussionInfo groupById = javaRushGroupClient.getGroupById(Integer.parseInt(groupId));
           if (isNull(groupById.getId())) {
               sendGroupNotFound(chatId, groupId);
           }
           GroupSub savedGroupSub = groupSubService.save(chatId, groupById);
           sendBotMessageService.sendMessage(chatId, "Подписал на группу " + savedGroupSub.getTitle());
       } else {
           sendGroupNotFound(chatId, groupId);
       }
   }

   private void sendGroupNotFound(String chatId, String groupId) {
       String groupNotFoundMessage = "Нет группы с ID = \"%s\"";
       sendBotMessageService.sendMessage(chatId, String.format(groupNotFoundMessage, groupId));
   }

   private void sendGroupIdList(String chatId) {
       String groupIds = javaRushGroupClient.getGroupList(GroupRequestArgs.builder().build()).stream()
               .map(group -> String.format("%s - %s \n", group.getTitle(), group.getId()))
               .collect(Collectors.joining());

       String message = "Whatбы подписаться на группу - передай комадну вместе с ID группы. \n" +
               "Например: /addGroupSub 16. \n\n" +
               "я подготовил список всех групп - выберай Howую хочешь :) \n\n" +
               "Name группы - ID группы \n\n" +
               "%s";

       sendBotMessageService.sendMessage(chatId, String.format(message, groupIds));
   }
}
Kelas ini menggunakan kaedah isNumeric daripada pustaka apache-commons, jadi mari tambahkannya pada ingatan kita:
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>${apache.commons.version}</version>
</dependency>
Dan dalam blok sifat:
<apache.commons.version>3.11</apache.commons.version>
Semua logik ini ada dalam kelas. Baca dengan teliti. Jika anda mempunyai sebarang soalan/cadangan, tulis di dalam komen. Selepas ini, kami perlu menambah arahan ke CommandContainer dalam peta arahan kami:
.put(ADD_GROUP_SUB.getCommandName(), new AddGroupSubCommand(sendBotMessageService, javaRushGroupClient, groupSubService))
Dan segala-galanya untuk pasukan ini. Saya ingin menguji fungsi ini, tetapi setakat ini saya hanya boleh melihatnya dalam pangkalan data. Dalam bahagian tiga, saya akan menambah perubahan daripada JRTB-6 supaya kita boleh melihat senarai kumpulan yang dilanggan oleh pengguna. Sekarang adalah baik untuk menyemak semua ini. Untuk melakukan ini, kami akan melakukan semua tindakan dalam Telegram dan menyemak dalam pangkalan data. Oleh kerana kami mempunyai ujian bertulis, semuanya sepatutnya baik-baik saja. Artikel itu sudah agak panjang, jadi kami akan menulis ujian untuk AddGroupSubCommand kemudian, dan menambah TODO dalam kod supaya tidak lupa.

kesimpulan

Dalam artikel ini, kami melihat kerja menambah fungsi melalui keseluruhan aplikasi, bermula dari pangkalan data dan berakhir dengan bekerja dengan pelanggan yang menggunakan bot. Biasanya tugas sedemikian membantu untuk memahami projek dan memahami intipatinya. Fahami cara ia berfungsi. Hari ini topiknya tidak mudah, jadi jangan malu: tulis soalan anda dalam komen, dan saya akan cuba menjawabnya. Adakah anda suka projek itu? Beri bintang pada Github : dengan cara ini jelas bahawa mereka berminat dengan projek itu, dan saya akan gembira. Seperti yang mereka katakan, seorang tuan sentiasa gembira apabila karyanya dihargai. Kod ini akan mengandungi ketiga-tiga bahagian STEP_6 dan akan tersedia sebelum artikel ini. Bagaimana untuk mengetahui tentangnya? Mudah sahaja - sertai saluran telegram , tempat saya menerbitkan semua maklumat tentang artikel saya tentang bot telegram. Terima kasih untuk membaca! Bahagian 3 sudah di sini .

Senarai semua bahan dalam siri ini adalah pada permulaan artikel ini.

Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION