JavaRush /Java блогу /Random-KY /Java'да Telegram ботун түзүү: идеядан жайылтууга чейин
John Watson
Деңгээл

Java'да Telegram ботун түзүү: идеядан жайылтууга чейин

Группада жарыяланган
Боттор деген эмне? Бул тууралуу кененирээк бул жерден окуй аласыз . Биринчиден, сиз Telegramдагы ботторду иштеп чыгуу үчүн китепкананын расмий documentтерин окуп чыгышыңыз керек (мындан ары API деп аталат). Ал бул жерде жатат . Java тorнде Telegram ботун түзүү: идеядан жайылтууга чейин - 1Ал жерде бардыгы абдан жеткorктүү жана түшүнүктүү. Жазып, сүйүнгөндөй көрүнөт! Бирок бул анчалык жөнөкөй эмес. Издөө системаларында көп убакыт өткөргөндөн кийин, мен ботту иштеп чыгуу боюнча бorмдин үзүндүлөрүн таптым, мисалы, клавиатураны кантип жасоо, CallbackQuery процессин жана башка ушул сыяктуу. Мен эч качан Java'да ботторду иштеп чыгуу үчүн толук жана ар тараптуу жол таба элекмин. Бул макаланы жазууга түрткү болду. Интернетте көптөгөн сайттар бар, анда сиз өзүңүздүн ботуңузду даяр жайгаштыруу менен түзө аласыз. Бирок кеп мына ушунда. көпчүлүк учурда, боттор негизги маалымат менен камсыз кыла турган түзүлөт жана башкалар. Биздин бот - бул толук кандуу веб-тиркеме, ага сиз маалымат базасын байлай аласыз, ар кандай API'лерге суроо-талаптарды жасай аласыз, сайттарды талдай аласыз, татаал эсептөөлөрдү ж.б. Маселе сиздин фантазияңыз менен гана чектелет. Бул саптарда мен сизге эмне жөнүндө жаза турганымды бир аз түшүндүрдүм деп үмүттөнөм. Telegramда ботту каттоо өтө жөнөкөй, бул процесс жогорудагы шилтемедеги documentтерде кеңири сүрөттөлгөн. Биздин колдонмо үчүн сиз болгону боттун атын жана каттоодон өткөндөн кийин ала турган белгини бorшиңиз керек. Негизи, бот бул жөн гана консолдук веб тиркеме. Frontend жок, таза буйруктарды иштетүү. Эгер сиз Күтүү режимин жакшы өздөштүрүп алгыңыз келсе же JSON анализин үйрөнгүңүз келсе, анда бул долбоор сиз үчүн. Келгиле, көз карандылыкты pom.xmlге кошуудан баштайлы (сиз Maven колдонуп жатасыз деп ойлойбуз). Сиз муну мындай кылсаңыз болот:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Андан кийин класс түзүп Bot, класстан мурастап TelegramLongPollingBot, анын ыкмаларын жокко чыгарабыз:
public class Bot extends TelegramLongPollingBot {

    /**
     * Method for receiving messages.
     * @param update Contains a message from the user.
     */
    @Override
    public void onUpdateReceived(Update update) {
	String message = update.getMessage().getText();
	sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Method for setting up a message and sending it.
     * @param chatId chat id
     * @param s The string to send as a message.
     */
    public synchronized void sendMsg(String chatId, String s) {
        SendMessage sendMessage = new SendMessage();
        sendMessage.enableMarkdown(true);
        sendMessage.setChatId(chatId);
        sendMessage.setText(s);
        try {
            sendMessage(sendMessage);
        } catch (TelegramApiException e) {
            log.log(Level.SEVERE, "Exception: ", e.toString());
        }
    }

    /**
     * The method returns the name of the bot specified during registration.
     * @return bot name
     */
    @Override
    public String getBotUsername() {
        returnBotName;
    }

    /**
     * The method returns the bot's token to communicate with the Telegram server
     * @return token for the bot
     */
    @Override
    public String getBotToken() {
        returnBotToken;
    }
}
Ооба, ыкманын мазмуну main:
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Аны методдорго киргизүү менен getBotUsername()биз getBotToken()ботту ишке киргизебиз. Азырынча ал бизге жөнөткөн билдирүүлөрүбүздү гана кайра багыттайт, кандайдыр бир “күзгү”. Мунун баары төмөнкүдөй иштейт: сиз тиркемени ишке киргизгениңизде, ал төмөнкү URL дареги боюнча секунданын ичинде бир жолу Telegram serverине GET өтүнүчүн жөнөтө баштайт: https://api.telegram.org/BotToken/getMe, бул жерде BotToken бардык билдирүүлөрдү камтыган JSON жообун алган ботуңуздун белгиси. Ар бир мындай билдирүү китепкана тарабынан иштелип чыгат жана методго OnUpdateReceived(Update update)an object катары келет Update. Мына ошону менен иштешебиз. Бул Telegram ботторунун сулуулугу, алар каалаган компьютерде иштей алат, тестирлөө үчүн тиркемени ишке киргизиш керек, ар бир өзгөртүүдөн кийин аны хостингге жайгаштыруунун кереги жок. Бул абдан ыңгайлуу. Албетте, ботту вебхук аркылуу иштөөгө конфигурациялоого болот; колдонмону Интернеттен тапса болот; жөнөкөйлүк үчүн биз LongPolling аркылуу иштейбиз. Билдирүүлөрдү кантип иштетүү жана жооп катары эмнени жөнөтүү тил куралдары жана китепкана менен гана чектелет, калганынын баары сиздин каалооңузда. Сиз үчүн YouTube'дан видеолорду издей турган бот жасасаңыз болот, сиз күн сайын өзүңүзгө жөнөткөн нерсеңизди жөнөтө турган бот жасай аласыз, мисалы, бир жылдан кийин, бир түрдөгү убакыт капсуласы. Же сиз CRM тутумдарына кантип интеграциялоону жана чакан бизнес үчүн ботторду жасоону үйрөнө аласыз, бардыгы сиздин фантазияңыз менен чектелген. Уланта бер. Ботторду колдонгондор, «/»мисалы, белгиден башталган буйруктарды колдонуу менен алар менен иштешүү ыңгайлуу экенин бorшет /start. Бирок бир кыйла ыңгайлуу жолу бар - баскычтар. Баскычтардын эки түрү бар: киргизүү талаасынын астында пайда болгон баскычтар ReplyKeyboardMarkupжана алар байланыштырылган билдирүүнүн астында түз пайда болгон баскычтар InlineKeyboardMarkup. Документтерде сиз алардын сыпаттамасы менен кыскача тааныша аласыз. ReplyKeyboardMarkup. Негизинен бул баскыч массивдеринин массивдери, List<KeyboardRow<KeyboardButton>>. Бул жерде клавиатураны түзгөн мисал code
public synchronized void setButtons(SendMessage sendMessage) {
        // Create a keyboard
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Create a list of keyboard strings
        List<KeyboardRow> keyboard = new ArrayList<>();

        // First line of the keyboard
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Add buttons to the first line of the keyboard
        keyboardFirstRow.add(new KeyboardButton(“Привет”));

        // Second line of the keyboard
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Add buttons to the second line of the keyboard
        keyboardSecondRow.add(new KeyboardButton(“Помощь”);

        // Add all keyboard strings to the list
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // and set this list to our keyboard
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
Методдо sendMsg()биз бул ыкманы ага билдирүү өткөрүү менен чакырабыз, ошентип ошол билдирүү үчүн баскычтопту орнотобуз. Бул билдирүүнү колдонуучуга жөнөткөнүбүздө, ал биз койгон билдирүү текстин, ошондой эле бири-биринин жанында "Салам" жана "Жардам" деген 2 баскычты көрөт. Бул баскычтарды басуу менен ботко билдирүү жөнөтүлөт, анын тексти баскычта жазылган. Башкача айтканда, кардар "Жардам" баскычын чыкылдатса, бот "Жардам" тексти менен билдирүү алат. Ал үчүн кардар өзү "Жардам" текстин жазып, ага жөнөткөндөй. Анда сиз мындай билдирүүлөрдү иштетесиз. InlineKeyboardMarkup Бул дагы массивдердин массиви, ал мурунку белгилөөгө окшош, бирок бул жерде иштөө логикасы бир аз башкача. Мындай клавиатура белгилүү бир билдирүүгө байланган жана ал үчүн гана бар. Бул жерде Inline баскычтопту орнотуу ыкмасы
private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText(“Кнопка“).setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
Listичинде түзүңүз List, биринчи сапка Inline баскычын кошуңуз. Мындай баскычта URL, каналга шилтеме же CallbackQueryмен бир аздан кийин жазам. Бул жерде биз колдонуучу көрө турган баскычыбыздын текстин коюп, анан ботко жөнөтүлө турган маалыматтарды орнотобуз. Биздин мисалда колдонуучу "Салам" дегенди көрөт жана басылганда ботко 17 саны жөнөтүлөт, бул биздин CallbackQuery. жөнүндө бир нече сөз CallbackQuery. Объекттен мындай маалыматтарды алуу үчүн, Updateсиз аткарышыңыз керек update.getCallbackQuery(), бул ыкма кайтып келет CallbackQuery, андан сиз ботко өткөрүлүп берилген маалыматтарды ала аласыз. Бул маалыматтарды метод аркылуу алууга аракет кылуунун кереги жок update.getMessage().getText(), алуу NullPointerException.
@Override
    public void onUpdateReceived(Update update) {
        if(update.hasMessage()) {
            ThreadClass thread = new ThreadClass(update.getMessage());
        } else  if(update.hasCallbackQuery()) {
            AnswerCallbackThread answerThread = new AnswerCallbackThread(update.getCallbackQuery());
        }
    }
Эгерде билдирүү болсо, биз билдирүүнү жаңы жипке иштетүүгө жөнөтөбүз, эгер кабар болсо CallbackQuery, биз аны тиешелүү жипке иштетүүгө жөнөтөбүз. Сиз CallbackQueryжооп жөнөтө аласыз. Telegramдагы ар бир an objectтин өзүнүн идентификатору бар. Белгилүү бир жоопту жөнөтүү үчүн, CallbackQueryанын идентификаторун гана бorшибиз керек, аны биз тиешелүү an objectтен алабыз. Жооп жөнөтүү үчүн бул ыкманы чакырыңыз:
public synchronized void answerCallbackQuery(String callbackId, String message) {
        AnswerCallbackQuery answer = new AnswerCallbackQuery();
        answer.setCallbackQueryId(callbackId);
        answer.setText(message);
        answer.setShowAlert(true);
        try {
            answerCallbackQuery(answer);
        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }
МААНИЛҮҮ:Жооптогу текст CallbackQuery200 белгиден ашпашы керек! Мындай жоопту жөнөтүүдө кардар билдирүү жазыла турган калкыма терезени алат. Мындай терезе пайда болгондон кийин бир нече секунддан кийин жоголуп кетиши мүмкүн же колдонуучу OK баскычын баскыча orп коюшу мүмкүн. Бул режимдерди которуу үчүн биз answer.setShowAlert(true). trueТерезе ОК баскыча orнип турганда, ал false5 секунддан кийин жок болот. Негизи, булардын баары Telegram бот китепканасынын негизги өзгөчөлүктөрү. Кааласаңыз, documentациядан мультимедиа жөнөтүү, геолокация ж.б.у.с. Ботубузду хостингде жайылтууга өтөлү. Долбоорум үчүн мен Heroku тандадым, анткени менин оюмча, бул өзүнүн CLI бар кыйла ыңгайлуу хостинг. Бул бекер, бирок бул ылдамдыкта сиздин ботуңуз 30 мүнөттөн кийин эч кандай суроо-талаптар болбосо, күтүү режимине өтөт. Ага өтүнүч жөнөтүлгөндө, ал ойгонот. Бул абдан тез болот, сиз байкабай каласыз (эгер, албетте, маалымат базасына байланыш кайра түзүлбөсө). Акысыз пландын чеги - 5 МБ маалымат базасы, 100 МБ диск мейкиндиги, айына 2 ТБ трафик, 1 дино. Dino сиздин иштеп жаткан колдонмо болуп саналат. Мен дароо айтам, бул мен үчүн кыйынчылыктарды жараткан жайылтуу баскычы болду, анткени мен буга чейин тиркемелеримди эч качан жайгаштырган эмесмин. Жайгаштырууда Heroku Procfile аттуу файлды талап кылат (кеңейтүүсүз). Биз аны долбоордун тамырында түзөбүз, ошол жерге worker: sh target/bin/workerBot workerBot деп жазабыз - Maven плагини appassembler-maven-plugin аркылуу түзүлгөн sh скриптинде көрсөткөн ат pom.xml ишке киргизилет. Скрипт компиляцияланган банканы иштетүүнү сүрөттөйт. Ишке киргизиле турган класстын аты <mainClass></mainClass> ортосунда, скрипттин аты <name></name> pom.xml ортосунда көрсөтүлөт:
...
<build>
    <plugins>
        ...
       <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>1.1.1</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>com.home.server.TelegramBot</mainClass>
                        <name>workerBot</name>
                    </program>
                </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Бул процессти баштоодон мурун, сиз Heroku сайтында катталып, Git жана Heroku CLI орнотуп алышыңыз керек. Эгерде сиздин тиркемеңиз маалымат базасын талап кылса, анда жаңы тиркемени каттоодо керектүү маалымат базасын кошууну унутпаңыз. Андан кийин, сиз базаңыздын хостун, колдонуучу атын, сырсөзүн жана портун таап, андан кийин аны колдонмоңузда көрсөтүшүңүз керек. Андан кийин, жайылтуудан мурун, Maven аркылуу долбооруңузду куруңуз.
mvn clean install
Баштоо үчүн, биз долбоордун каталогуна барабыз, команда менен репозиторийди инициализациялайбызgit init Андан кийин биз долбоорубузду ушул репозиторийге кошобуз
git add .
Биз өзгөртүүлөрдү киргизгенден кийин
git commit -m “First commit in project”
Кийинки сиз герокуга кирүүңүз керек, буйрук сабына жазыңыз
heroku login
Каттоо учурунда көрсөтүлгөн маалыматтарыңызды киргизиңиз. Андан кийин Herokuдагы репозиторийиңиздин URL дарегин бorшиңиз керек, бул жөндөөлөрдөн жасалат. Анда жазабыз
git remote add heroku [url]
Heroku алыскы репозиторий сиздин репозиторийиңизге кошулат. Кийинки жазабыз
git push heroku master
Биз күтүп жатабыз... Эгерде тиркемени жайылтуу ийгorктүү болсо, биз буйрукту аткарабыз
heroku ps:scale worker=1
Мына ушундай, колдонмоңуз иштеп жатат. Эгер андай болбосо, журналдарды кылдаттык менен караңыз, балким, колдонмоңузда ката бар, бул анын бузулушуна алып келди. Ушундай узун макаланы окуганыңыз үчүн рахмат, кимдир бирөө аны пайдалуу деп таап, иштеп чыгуу учурунда мүдүрүлгөн жерлерде көп убакытты үнөмдөйт деп ишенем.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION