JavaRush /جاوا بلاگ /Random-UR /ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگ...

ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں! حصہ 1

گروپ میں شائع ہوا۔
میرا نام ولادیمیر ہے۔ میری عمر 43 سال ہے۔ اور اگر آپ، قارئین، 40 سے زائد ہیں، تو ہاں، 40 کے بعد آپ پروگرامر بن سکتے ہیں اگر آپ اسے پسند کریں۔ میرے کام کا پروگرامنگ سے کوئی تعلق نہیں ہے، میں آٹومیشن کے شعبے میں پروجیکٹ مینیجر ہوں اور یہ سب کچھ۔ لیکن میں اپنا پیشہ بدلنے کا سوچ رہا ہوں۔ اوہ، یہ نئے رجحانات... ہر 5-7 سال بعد اپنی سرگرمی کا میدان تبدیل کریں۔ تو : پراجیکٹ کافی بڑا نکلا، اس لیے کچھ نکات کو چھوڑنا پڑے گا یا مختصراً بات کرنا پڑے گی، اس امید پر کہ قاری گوگل کو کیسے جانتا ہے۔ انٹرنیٹ طویل پولنگ کے اصول پر کام کرنے والے ٹیلیگرام بوٹس کی اشاعتوں سے بھرا ہوا ہے۔ اور بہت کم ہیں جو Webhook اصول پر کام کرتے ہیں۔ یہ کیا ہے؟ طویل پولنگ - اس کا مطلب ہے کہ آپ کی ایپلی کیشن خود ہی ٹیلیگرام سرور کو ایک مخصوص فریکوئنسی پر آہستہ آہستہ پیغامات کے لیے پول کرے گی۔ ویب ہُک - کا مطلب ہے کہ ٹیلیگرام سرور فوری طور پر پیغامات کو آپ کے بتائے ہوئے سرور پر بھیج دے گا۔ ہمارے معاملے میں، ہیروکو سروس کے بشکریہ۔ آپ یقیناً ٹیلیگرام کی ویب سائٹ پر اس سب کے بارے میں اور عام طور پر بوٹ کے بارے میں مزید پڑھ سکتے ہیں - https://tlgrm.ru/docs/bots/api بوٹ کا انٹرفیس اس طرح لگتا ہے: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 1 میں اس ایپلی کیشن کو بالکل تربیت کے طور پر سمجھتا ہوں۔ پروجیکٹ اس وجہ سے کہ لکھتے وقت میں نے تربیت کے مقابلے میں اس بوٹ سے زیادہ معلومات سیکھیں۔ کیا آپ پروگرام سیکھنا چاہتے ہیں؟ کوڈ لکھنا شروع کریں !!! لیکن! گیتھب پر ایپلیکیشن اپ لوڈ کرنے یا ڈیٹا بیس بنانے کے طریقے کے بارے میں کوئی تفصیلی ہدایات نہیں ہوں گی۔ انٹرنیٹ پر اس کی کافی مقدار موجود ہے اور اسے بڑی تفصیل سے بیان کیا گیا ہے، اس کے علاوہ، یہ بہت طویل پڑھا جائے گا۔ ایپلیکیشن اس طرح کام کرے گی: ایونٹ کی تفصیل درج کریں، تقریب کی تاریخ اور وقت درج کریں، تعدد کو منتخب کریں (آپ اسے ایک بار کر سکتے ہیں، آپ کو ہر روز ایک مخصوص وقت پر یاد دہانی ہو سکتی ہے، آپ اسے ایک بار لے سکتے ہیں۔ ایک خاص وقت میں ایک مہینہ، یا سال میں ایک بار)۔ اطلاعات کے تغیرات کو لامتناہی طور پر شامل کیا جاسکتا ہے؛ میرے پاس بہت سارے خیالات ہیں۔ اس کے بعد، درج کردہ ڈیٹا کو ڈیٹا بیس میں محفوظ کیا جاتا ہے (ہیروکو پر بھی مفت میں تعینات کیا جاتا ہے، 10,000 قطاریں مفت ہوتی ہیں) پھر، ایک بار دن کے آغاز میں 0:00 سرور ٹائم پر، اسپرنگ ڈیٹا بیس سے تمام واقعات کو معیار کی بنیاد پر بازیافت کرتا ہے۔ جو اس دن فائر کرے اور انہیں مقررہ وقت پر پھانسی کے لیے بھیجے۔ توجہ!!! پروگرام کا یہ حصہ تجرباتی ہے! ایک ایسا عمل ہے جو زیادہ آسان اور سچ ہے! یہ خاص طور پر یہ دیکھنے کے لیے کیا گیا تھا کہ وقت کی کلاس کیسے کام کرتی ہے! آپ کارٹ میں @calendar_event_bot ٹائپ کرکے اپنے ہاتھوں سے کام کرنے والے بوٹ کو چھو سکتے ہیں، لیکن اس پر اعتماد نہ کریں، کیونکہ میں اب بھی اس کا مذاق اڑا رہا ہوں۔ کوڈ - https://github.com/papoff8295/webHookBotForHabr بنیادی طور پر، خود کو لانچ کرنے کے لیے آپ کو درج ذیل اقدامات کرنے کی ضرورت ہے: • @BotFather کے ساتھ رجسٹر ہوں ، یہ مشکل نہیں ہے، ایک ٹوکن اور نام حاصل کریں • گیتھب پر پروجیکٹ کو فورک کریں • رجسٹر کریں ہیروکو پر، ایک ایپلیکیشن بنائیں (ہم اسے مرحلہ وار دیکھیں گے)، اپنے ذخیرہ سے تعینات کریں۔ • ہیروکو پر ایک ڈیٹا بیس بنائیں • ریپوزٹری میں متعلقہ فیلڈز کو اپنے ساتھ تبدیل کریں (ٹوکن، اداروں میں ٹیبلز کا نام، ویب ہُک پاتھ، صارف کا نام، پاس ورڈ اور ڈیٹا بیس کا راستہ، یہ سب پارس ہو جائیں گے) • ہیروکو کو 24/ کام کریں 7 https:///uptimerobot.com/ کا استعمال کرتے ہوئے پروجیکٹ کا حتمی ڈھانچہ اس طرح ہے: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 2 آئیے https://start.spring.io میں ایک پروجیکٹ بنا کر شروع کریں جیسا کہ تصویر میں دکھایا گیا ہے ہمیں ضرورت کے مطابق انحصار کا انتخاب کریں: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 3اپنی مرضی کا انتخاب کریں۔ پروجیکٹ کے لیے نام اور جنریٹ پر کلک کریں ۔ اگلا آپ کو پروجیکٹ کو اپنی ڈسک میں محفوظ کرنے کا کہا جائے گا۔ آپ کے ترقیاتی ماحول سے pom.xm l فائل کو کھولنا باقی ہے۔ آپ کے سامنے ایک مکمل پروجیکٹ ہے۔ اب ہمیں صرف اپنی مرکزی لائبریری کو شامل کرنے کی ضرورت ہے۔ میں نے لائبریری کو https://github.com/rubenlagus/TelegramBots سے استعمال کیا عام طور پر، آپ الجھن میں پڑ سکتے ہیں اور اس کے بغیر کر سکتے ہیں۔ سب کے بعد، کام کا پورا نقطہ یو آر ایل کو اس طرح جوڑنا ہے: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548 کو تھوڑا سا دیکھیں۔ : https://api.telegram.org – ٹیلیگرام سرور۔ bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - لفظ بوٹ کے بعد ایک خفیہ ٹوکن ہے جو آپ کو بوٹ رجسٹر کرتے وقت موصول ہوتا ہے۔ setWebhook?url=https://e9c658b548aa.ngrok.io – طریقہ کار کا نام اور اس کے پیرامیٹرز۔ اس صورت میں، ہم آپ کا ویب ہک سرور انسٹال کرتے ہیں، تمام پیغامات اس پر بھیجے جائیں گے۔ عام طور پر، میں نے فیصلہ کیا کہ یہ پروجیکٹ اشاعت کے لیے بہت چھوٹا نہیں ہے، لیکن دستی عمل درآمد کے ساتھ یہ عام طور پر پڑھے جانے کے قابل نہیں ہوگا۔ تو، pom فائل کی آخری شکل یہ ہے:
<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelversion>4.0.0</modelversion>
   <parent>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-parent</artifactid>
      <version>2.5.0</version>
      <relativepath> <!-- lookup parent from repository -->
   </relativepath></parent>
   <groupid>ru.popov</groupid>
   <artifactid>telegrambot</artifactid>
   <version>0.0.1-SNAPSHOT</version>
   <name>telegrambot</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-web</artifactid>
      </dependency>

      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-data-jpa</artifactid>
      </dependency>

      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-test</artifactid>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact/org.telegram/telegrambots-spring-boot-starter -->
      <dependency>
         <groupid>org.telegram</groupid>
         <artifactid>telegrambots-spring-boot-starter</artifactid>
         <version>5.2.0</version>
      </dependency>

      <dependency>
         <groupid>org.projectlombok</groupid>
         <artifactid>lombok</artifactid>
         <version>1.18.16</version>
      </dependency>

      <dependency>
         <groupid>org.postgresql</groupid>
         <artifactid>postgresql</artifactid>
         <scope>runtime</scope>
      </dependency>

   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-maven-plugin</artifactid>
         </plugin>
      </plugins>
   </build>

</project>
ہماری بوٹ لکھنے کے لیے سب کچھ تیار ہے۔ آئیے TelegramBot کلاس بنائیں ۔ میں فولڈرز کے نام نہیں لکھوں گا، آپ انہیں اوپر کے پروجیکٹ ڈھانچے میں دیکھ سکتے ہیں۔
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramBot extends SpringWebhookBot {
    String botPath;
    String botUsername;
    String botToken;

    private TelegramFacade telegramFacade;

    public TelegramBot(TelegramFacade telegramFacade, DefaultBotOptions options, SetWebhook setWebhook) {
        super(options, setWebhook);
        this.telegramFacade = telegramFacade;
    }
    public TelegramBot(TelegramFacade telegramFacade, SetWebhook setWebhook) {
        super(setWebhook);
        this.telegramFacade = telegramFacade;
    }

    @Override
    public BotApiMethod<!--?--> onWebhookUpdateReceived(Update update) {
        return telegramFacade.handleUpdate(update);
    }
}
کلاس ہماری ٹیلیگرام لائبریری سے SpringWebhookBot کو بڑھاتی ہے، اور ہمیں صرف ایک طریقہ کو نافذ کرنے کی ضرورت ہے، onWebhookUpdateReceived ۔ یہ تجزیہ شدہ JSON کو اپ ڈیٹ آبجیکٹ کے طور پر قبول کرتا ہے اور ٹیلی گرام سرور ہم سے "سننا" چاہتا ہے اسے واپس کرتا ہے۔ یہاں ہمارے پاس لومبوک لائبریری سے تشریحات ہیں ۔ لومبوک – ایک پروگرامر کی زندگی کو آسان بنانا!! ٹھیک ہے، یہ ہے. ہمیں حاصل کرنے والوں اور سیٹرز کو دوبارہ متعین کرنے کی ضرورت نہیں ہے، Lombok یہ ہمارے لیے کرتا ہے، اور ہمیں رسائی کی سطح کا شناخت کنندہ لکھنے کی بھی ضرورت نہیں ہے۔ اب یہ لکھنے کے قابل نہیں ہے کہ یہ تشریحات @Getter, @Setter, @FieldDefaults کے ذریعہ کیا گیا ہے بوٹ پاتھ فیلڈ کا مطلب ہے ہمارا ویب ہک ایڈریس، جو ہمیں بعد میں ہیروکو پر موصول ہوگا۔ botUsername فیلڈ کا مطلب ہمارے بوٹ کا نام ہے، جو ہمیں ٹیلی گرام میں اپنے بوٹ کو رجسٹر کرنے پر موصول ہوگا۔ بوٹ ٹوکن فیلڈ ہمارا ٹوکن ہے، جو ہمیں ٹیلی گرام میں اپنے بوٹ کو رجسٹر کرنے پر موصول ہوگا۔ ٹیلیگرام فیکیڈ فیلڈ ہماری کلاس ہے جہاں میسج پروسیسنگ ہوگی، ہم تھوڑی دیر بعد اس پر واپس جائیں گے، اسے ابھی سرخ رہنے دیں۔ اب وقت آگیا ہے کہ ہم @BotFather سے رابطہ کریں اور مائشٹھیت botToken اور botUsername حاصل کریں۔ ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 4بس اسے ٹیلیگرام پر لکھیں اور وہ آپ کو سب کچھ بتا دے گا۔ ہم ڈیٹا کو اپنی application.properties میں لکھتے ہیں، آخر میں یہ اس طرح نظر آئے گا:
server#server.port=5000

telegrambot.userName=@calendar_event_bot
telegrambot.botToken=1731265488:AAFDjUSk3vu5SFfgdfh556gOOFmuml7SqEjwrmnEF5Ak
#telegrambot.webHookPath=https://telegrambotsimpl.herokuapp.com/
telegrambot.webHookPath=https://f5d6beeb7b93.ngrok.io


telegrambot.adminId=39376213

eventservice.period =600000

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/telegramUsers
spring.datasource.username=postgres
spring.datasource.password=password

#spring.datasource.url=jdbc:postgresql:ec2-54-247-158-179.eu-west-1.compute.amazonaws.com:5432/d2um126le5notq?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.NonValidatingFactory
#spring.datasource.username=ulmbeywyhvsxa
#spring.datasource.password=4c7646c69dbbgeacb98fa96e8daa6d9b1bl4894e67f3f3ddd6a27fe7b0537fd
یہ ترتیب مقامی ڈیٹا بیس کے ساتھ کام کرنے کے لیے ترتیب دی گئی ہے؛ بعد میں ہم ضروری تبدیلیاں کریں گے۔ botToken اور صارف نام کو اپنے سے تبدیل کریں ۔ ایپلی کیشن میں براہ راست application.properties سے ڈیٹا استعمال کرنا اچھا نہیں ہے۔ آئیے اس ڈیٹا سے بین یا ریپر کلاس بنائیں۔
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
یہاں @Value تشریح application.properties فائل سے متعلقہ لائنوں کو شروع کرتی ہے، جس کے بارے میں بہار ڈیفالٹ جانتا ہے۔ اور @Component تشریح ہمارے لیے ایک بین بناتی ہے جب ایپلیکیشن شروع ہوتی ہے۔ آئیے اب اسپرنگ کنفیگریشن فائل کو دیکھتے ہیں:
@Configuration
public class AppConfig {
    private final TelegramBotConfig botConfig;

    public AppConfig(TelegramBotConfig botConfig) {
        this.botConfig = botConfig;
    }

    @Bean
    public SetWebhook setWebhookInstance() {
        return SetWebhook.builder().url(botConfig.getWebHookPath()).build();
    }

    @Bean
    public TelegramBot springWebhookBot(SetWebhook setWebhook, TelegramFacade telegramFacade) {
        TelegramBot bot = new TelegramBot(telegramFacade, setWebhook);
        bot.setBotToken(botConfig.getBotToken());
        bot.setBotUsername(botConfig.getUserName());
        bot.setBotPath(botConfig.getWebHookPath());

        return bot;
    }
}
یہاں کوئی جادو نہیں ہے؛ آغاز پر، بہار ہمارے لیے SetWebhook اور TelegramBot اشیاء بناتی ہے۔ آئیے اب اپنے پیغامات کے لیے انٹری پوائنٹس بنائیں:
@RestController
public class WebhookController {

    private final TelegramBot telegramBot;

    public WebhookController(TelegramBot telegramBot) {
        this.telegramBot = telegramBot;
    }

// point for message
    @PostMapping("/")
    public BotApiMethod<!--?--> onUpdateReceived(@RequestBody Update update) {
        return telegramBot.onWebhookUpdateReceived(update);
    }

    @GetMapping
    public ResponseEntity get() {
        return ResponseEntity.ok().build();
    }
}
ٹیلیگرام سرور POST طریقہ استعمال کرتے ہوئے رجسٹرڈ ویب ہک ایڈریس پر JSON فارمیٹ میں پیغامات بھیجتا ہے، ہمارا کنٹرولر انہیں وصول کرتا ہے اور اپ ڈیٹ آبجیکٹ کی شکل میں ٹیلیگرام لائبریری میں منتقل کرتا ہے۔ میں نے حاصل کرنے کا طریقہ بالکل اسی طرح کیا) اب ہمیں ٹیلیگرام فیکیڈ کلاس میں پیغامات اور جوابات پر کارروائی کرنے کے لیے کچھ منطق کو لاگو کرنے کی ضرورت ہے، میں اس کا مختصر کوڈ دوں گا تاکہ آپ ایپلی کیشن کو لانچ کر سکیں اور پھر اپنے طریقے سے چلیں یا تعیناتی پر سوئچ کریں۔ ہیروکو پر، پھر یہ مکمل ورژن ہوگا:
@Component
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramFacade {

    public BotApiMethod<!--?--> handleUpdate(Update update) {

        if (update.hasCallbackQuery()) {
            CallbackQuery callbackQuery = update.getCallbackQuery();
            return null;
        } else {

            Message message = update.getMessage();
            SendMessage sendMessage = new SendMessage();
            sendMessage.setChatId(String.valueOf(message.getChatId()));
            if (message.hasText()) {
                sendMessage.setText("Hello world");
                return sendMessage;
            }
        }
        return null;
    }

}
یہ طریقہ کسی بھی ہیلو ورلڈ کو جواب دے گا! اپنی ایپلیکیشن شروع کرنے کے لیے، ہمیں صرف اس بات کو یقینی بنانا ہوگا کہ ہم براہ راست IDEA سے اپنی درخواست کی جانچ کر سکیں۔ ایسا کرنے کے لیے ہمیں ngrok یوٹیلیٹی ڈاؤن لوڈ کرنے کی ضرورت ہے۔ https://ngrok.com/download یہ یوٹیلیٹی ایک کمانڈ لائن ہے جو ہمیں 2 گھنٹے کے لیے ایک عارضی پتہ دیتی ہے اور تمام پیغامات کو مقامی سرور کی مخصوص پورٹ پر بھیج دیتی ہے۔ ہم لائن میں ngrok http 5000 لانچ کرتے ہیں اور لکھتے ہیں (یا آپ اپنا پورٹ بتا سکتے ہیں): ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 5ہمیں نتیجہ ملتا ہے: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 6https://23b1a54ccbbd.ngrok.io - یہ ہمارا ویب ہک ایڈریس ہے۔ جیسا کہ آپ نے پراپرٹی فائل میں دیکھا ہوگا کہ ہم نے tomcat سرور کو شروع کرتے وقت server.port=5000 لکھا تھا، یہ پورٹ 5000 پر قبضہ کرے گا، یقینی بنائیں کہ یہ فیلڈز ایک جیسے ہیں۔ یہ بھی نہ بھولیں کہ پتہ دو گھنٹے کے لیے دیا جاتا ہے۔ کمانڈ لائن پر، اس کی نگرانی سیشن ایکسپائر فیلڈ کے ذریعے کی جاتی ہے۔ وقت ختم ہونے پر، آپ کو دوبارہ پتہ حاصل کرنا ہوگا اور اسے ٹیلی گرام پر رجسٹر کرنے کے طریقہ کار سے گزرنا ہوگا۔ اب ہم لائن لیتے ہیں https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io اور ہنر مندی کے ساتھ، ہم اپنے ماضی کے ہاتھ کی حرکتوں کو بدل دیتے ہیں۔ براؤزر میں نتیجے میں لائن اور درج کریں پر کلک کریں. آپ کو درج ذیل نتیجہ ملنا چاہیے: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 7بس، اب آپ ایپلیکیشن چلا سکتے ہیں: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 8چیک کریں کہ آپ کی کلاس مین طریقہ کے ساتھ اس طرح تھی:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
اگر آپ نے سب کچھ صحیح طریقے سے کیا تو اب آپ کا بوٹ کسی بھی پیغام کا جواب " Hello world" کے فقرے کے ساتھ دے گا ۔ پھر آپ اپنے راستے پر جا سکتے ہیں۔ اگر آپ میرے ساتھ ہیں اور آپ تمام مراحل سے گزرنے میں دلچسپی رکھتے ہیں، تو آئیے ڈیٹا بیس کے لیے ہستیوں کو لکھنا شروع کریں اور خود ڈیٹا بیس بنائیں۔ آئیے ڈیٹا بیس کے ساتھ شروع کرتے ہیں: جیسا کہ میں نے پہلے ہی کہا ہے، میں فرض کرتا ہوں کہ آپ کے پاس ڈیٹا بیس کے ساتھ کام کرنے میں پہلے سے ہی کم سے کم مہارت ہے، اور آپ کے پاس ایک مقامی postgreSQL ڈیٹا بیس انسٹال ہے ، اگر نہیں، تو اس راستے پر چلیں۔ https://www.postgresql.org/download/ application.properties فائل میں، ڈیٹا بیس لاگ ان اور پاس ورڈ کو اپنے سے تبدیل کریں۔ IDEA میں دائیں طرف ایک ڈیٹا بیس ٹیب ہے، اس میں آپ کو +/Data source/PostgreSQL پر کلک کرنے کی ضرورت ہے ۔ نتیجے کے طور پر، جب آپ ٹیسٹ کنکشن پر کلک کرتے ہیں تو آپ کو تسلی بخش نتیجہ ملنا چاہیے: ٹیلیگرام بوٹ - جاوا میں ویب ہُک کے ذریعے یاد دہانی یا گوگل کیلنڈر کو نہ کہیں!  - 9اب آپ ڈیولپمنٹ ماحول سے براہ راست ٹیبلز کے ساتھ ڈیٹا بیس بنا سکتے ہیں، یا آپ pgadmin ویب انٹرفیس استعمال کر سکتے ہیں ، جو اسٹارٹ مینو میں واقع ہے۔ ہمیں 3 میزوں کی ضرورت ہوگی:
CREATE TABLE users
(
    id               INTEGER PRIMARY KEY UNIQUE NOT NULL,
    name             VARCHAR,
    time_zone        INTEGER DEFAULT 0,
    on_off           BOOLEAN DEFAULT true
);

CREATE TABLE user_events
(
    user_id INTEGER ,
    time timestamp ,
    description varchar ,
    event_id serial,
    event_freq varchar default 'TIME',
    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);

CREATE TABLE event_cash
(
    time timestamp ,
    description varchar ,
    user_id INTEGER ,
    id serial
);
میں اس اسکرپٹ کو الگ سے بنانے کی تجویز کرتا ہوں؛ ہمیں ہیروکو پر ڈیٹا بیس بنانے کے لیے اس کی ضرورت ہوگی، تاکہ اسے دو بار نہ لکھا جائے۔ چلو تھوڑا چلتے ہیں۔ میں ابھی کہوں گا کہ ہیروکو کے ساتھ کام کرنے کے لیے ہمیں صرف ایونٹ_کیش ٹیبل کی ضرورت ہے کیونکہ اس کی تفصیلات اور ٹائم کلاس کے ساتھ کام کرنے کی میری غیر تسلی بخش خواہش ؛ یہ مقامی ورژن میں مفید نہیں ہوگا۔ یوزرز ٹیبل میں ہم ٹیلی گرام صارف کے اکاؤنٹ کی آئی ڈی ، اس کا نام، جو شاید موجود نہ ہو، صارف کے ٹائم زون کو نوٹیفیکیشنز کی درست بھیجنے کے ساتھ ساتھ نوٹیفیکیشن بھیجنے کے آن/آف اسٹیٹس کو بھی ریکارڈ کریں گے۔ ہم صارف کی شناخت ، اطلاع کا وقت، صارف_ایونٹس ٹیبل میں تفصیل ریکارڈ کریں گے، ایونٹ کے لیے خود بخود ایک آئی ڈی تیار کریں گے ، اور اطلاعات کی تعدد سیٹ کریں گے۔ ایونٹ_کیش ٹیبل اطلاع بھیجے جانے سے پہلے ریکارڈ کرے گا اور اگر بھیج دیا جائے تو اسے ٹیبل سے ہٹا دے گا۔ میزیں تیار ہیں، آئیے اب اداروں کو شامل کرتے ہیں۔
@Entity
@Table(name = "user_events")
@Getter
@Setter
public class Event {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = "event_id", columnDefinition = "serial")
    private int eventId;

    @Column(name = "time")
    @NotNull(message = "Need date!")
    private Date date;

    @Column(name = "description")
    @Size(min = 4, max = 200, message = "Description must be between 0 and 200 chars!")
    private String description;

    @Column(name = "event_freq", columnDefinition = "TIME")
    @Enumerated(EnumType.STRING)
    private EventFreq freq;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="user_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;

    public Event() {
    }

    public Event(int eventId,
                 @NotNull(message = "Need date!") Date date,
                 @Size(min = 4, max = 200, message = "Description must be between 0 and 200 chars!")
                         String description,
                 EventFreq freq, User user) {
        this.eventId = eventId;
        this.date = date;
        this.description = description;
        this.freq = freq;
        this.user = user;
    }
}
@Entity
@Table(name = "users")
@Getter
@Setter
public class User {

    @Id
    @Column(name = "id")
    private long id;

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

    @Column(name = "time_zone", columnDefinition = "default 0")
    //sets the broadcast time of events for your time zone
    private int timeZone;

    @OneToMany(mappedBy="user")
    private List<event> events;

    @Column(name = "on_off")
    // on/off send event
    private boolean on;

    public User() {
    }
}

</event>
@Entity
@Table(name = "event_cash")
@Getter
@Setter
//serves to save unhandled events after rebooting heroku
public class EventCashEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = "id", columnDefinition = "serial")
    private long id;

    @Column(name = "time")
    private Date date;

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

    @Column(name = "user_id")
    private long userId;

    public EventCashEntity() {
    }

    public static EventCashEntity eventTo(Date date, String description, long userId) {
        EventCashEntity eventCashEntity = new EventCashEntity();
        eventCashEntity.setDate(date);
        eventCashEntity.setDescription(description);
        eventCashEntity.setUserId(userId);
        return eventCashEntity;
    }
}
آئیے اہم نکات پر تھوڑا سا چلتے ہیں۔ @Entity - ہمارے dada jpa کے لیے کلاس کو نشان زد کرتا ہے کہ یہ کلاس ڈیٹا بیس کے لیے ایک ہستی ہے، یعنی ڈیٹا بیس سے ڈیٹا بازیافت کرتے وقت، یہ ہمیں ایک ایونٹ، یوزر اور EventCashEntity آبجیکٹ کی شکل میں پیش کیا جائے گا۔ @ ٹیبل - ہم کہتے ہیں کہ ڈیٹا بیس میں ہمارے ٹیبل کو کیا کہتے ہیں۔ اس بات کو یقینی بنانے کے لیے کہ ٹیبل کا نام سرخ رنگ میں نہیں لکھا گیا ہے، ہمیں تجویز کردہ غلطی کی اصلاح کے اختیار کے ساتھ IDEA میں اتفاق کرنا ہوگا اور ڈیٹا کے ذرائع تفویض کریں پر کلک کرنا ہوگا۔ اور وہاں ہمارا بیس منتخب کریں۔ @id اور @GeneratedValue - اسپرنگ کے ذریعے ڈیٹا بیس بنانے کے لیے استعمال کیا جاتا ہے اگر یہ پہلے سے موجود نہیں ہے۔ @Column ٹیبل میں فیلڈز کے نام کی نشاندہی کرنے کے لیے استعمال کیا جاتا ہے اگر وہ مماثل نہیں ہیں، لیکن اچھے کوڈ کے اصول تجویز کرتے ہیں کہ آپ ہمیشہ یہ لکھیں۔ OneToMany رویہ - میں وقت گزارنے اور یہ جاننے کی تجویز کرتا ہوں کہ یہ یہاں کیا ہے https://en.wikibooks.org/wiki/Java_Persistence میں اسے زیادہ واضح طور پر بیان نہیں کرسکتا، بس مجھ پر یقین کریں۔ میں صرف اتنا کہوں کہ اس معاملے میں @OneToMany تشریح کہتی ہے کہ ایک صارف کے بہت سے واقعات ہوسکتے ہیں، اور وہ ہمیں فہرست کی شکل میں فراہم کیے جائیں گے۔ اب ہمیں میزوں سے ڈیٹا حاصل کرنے کی ضرورت ہے۔ SRING DATA JPA لائبریری میں ہمارے لیے سب کچھ پہلے سے ہی لکھا ہوا ہے، ہمیں صرف ہر ٹیبل کے لیے ایک انٹرفیس بنانا ہوگا اور اسے JpaRepository سے بڑھانا ہوگا۔
public interface EventRepository extends JpaRepository<event, long=""> {
    Event findByEventId(long id);
}
public interface UserRepository extends JpaRepository<user, long=""> {

    User findById(long id);
}
public interface EventCashRepository extends JpaRepository<eventcashentity, long=""> {
    EventCashEntity findById(long id);
}

</eventcashentity,></user,></event,>
ڈیٹا بیس کے ساتھ کام کرنے کے لیے بنیادی منطق ایک سروس، نام نہاد ڈیٹا ایکسیس آبجیکٹ (DAO) میں منتقل کی جاتی ہے:
@Service
public class UserDAO {

    private final UserRepository userRepository;

    @Autowired
    public UserDAO(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User findByUserId(long id) {
        return userRepository.findById(id);
    }

    public List<user> findAllUsers() {
        return userRepository.findAll();
    }

    public void removeUser(User user) {
        userRepository.delete(user);
    }


    public void save(User user) {
        userRepository.save(user);
    }

    public boolean isExist(long id) {
        User user = findByUserId(id);
        return user != null;
    }
}
@Service
public class EventDAO {

    private final UserRepository userRepository;
    private final EventRepository eventRepository;

    @Autowired
    public EventDAO(UserRepository userRepository, EventRepository eventRepository) {
        this.userRepository = userRepository;
        this.eventRepository = eventRepository;
    }

    public List<event> findByUserId(long userId) {
        User user = userRepository.findById(userId);
        return user.getEvents();
    }
    public List<event> findAllEvent() {
       return eventRepository.findAll();
    }

    public Event findByEventId(long eventId) {
        return eventRepository.findByEventId(eventId);
    }

    public void remove(Event event) {
        eventRepository.delete(event);
    }

    public void save(Event event) {
        eventRepository.save(event);
    }
}

</event></event></user>
@Service
//handles events not dispatched after reboot heroku
public class EventCashDAO {

    private EventCashRepository eventCashRepository;

    @Autowired
    public void setEventCashRepository(EventCashRepository eventCashRepository) {
        this.eventCashRepository = eventCashRepository;
    }

    public List<eventcashentity> findAllEventCash() {
        return eventCashRepository.findAll();
    }

    public void save(EventCashEntity eventCashEntity) {
        eventCashRepository.save(eventCashEntity);
    }

    public void delete(long id) {
        eventCashRepository.deleteById(id);
    }
}

</eventcashentity>
اس صورت میں، ہمارے پاس کوئی ڈیٹا پروسیسنگ نہیں ہے، ہم صرف میزوں سے ڈیٹا کو بازیافت کرتے ہیں۔ ہم سب T elegramFacade کلاس کا مکمل کوڈ فراہم کرنے کے لیے تیار ہیں اور منطق کا تجزیہ کرنا شروع کر دیتے ہیں۔
@Component
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramFacade {

    final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;

    @Value("${telegrambot.adminId}")
    int adminId;


    public TelegramFacade(MessageHandler messageHandler, CallbackQueryHandler callbackQueryHandler, BotStateCash botStateCash) {
        this.messageHandler = messageHandler;
        this.callbackQueryHandler = callbackQueryHandler;
        this.botStateCash = botStateCash;
    }

    public BotApiMethod<!--?--> handleUpdate(Update update) {

        if (update.hasCallbackQuery()) {
            CallbackQuery callbackQuery = update.getCallbackQuery();
            return callbackQueryHandler.processCallbackQuery(callbackQuery);
        } else {

            Message message = update.getMessage();
            if (message != null && message.hasText()) {
                return handleInputMessage(message);
            }
        }
        return null;
    }

    private BotApiMethod<!--?--> handleInputMessage(Message message) {
        BotState botState;
        String inputMsg = message.getText();
        //we process messages of the main menu and any other messages
        //set state
        switch (inputMsg) {
            case "/start":
                botState = BotState.START;
                break;
            case "Мои напоминания":
                botState = BotState.MYEVENTS;
                break;
            case "Создать напоминание":
                botState = BotState.CREATE;
                break;
            case "Отключить напоминания":
            case "Включить напоминания":
                botState = BotState.ONEVENT;
                break;
            case "All users":
                if (message.getFrom().getId() == adminId)
                botState = BotState.ALLUSERS;
                else botState = BotState.START;
                break;
            case "All events":
                if (message.getFrom().getId() == adminId)
                botState = BotState.ALLEVENTS;
                else botState = BotState.START;
                break;
            default:
                botState = botStateCash.getBotStateMap().get(message.getFrom().getId()) == null?
                        BotState.START: botStateCash.getBotStateMap().get(message.getFrom().getId());
        }
        //we pass the corresponding state to the handler
        //the corresponding method will be called
        return messageHandler.handle(message, botState);

    }
}
آئیے دیکھتے ہیں کہ کن فیلڈز کی ضرورت ہے۔
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
اگر ہم سب ایک کلاس میں کوڈ کرتے ہیں، تو ہم چاند کے لیے ایک فٹ کلاتھ کے ساتھ ختم ہوں گے؛ اس لیے، ہم MessageHandler کلاس کو ٹیکسٹ میسجز کے ساتھ کام کرنے کے لیے منطق اور CallbackQueryHandler کلاس کو کال بیککوری پیغامات کے ساتھ کام کرنے کی منطق تفویض کرتے ہیں ۔ یہ معلوم کرنے کا وقت ہے کہ allbackquery کیا ہے اور کس قسم کے مینو ہیں۔ ایسا کرنے کے لیے، میں آپ کو بوٹ کے انٹرفیس کی ایک اور تصویر دوں گا: Telegram bot — напоминалка через webHook на Java or скажи нет Google-календарю! - 10مینیو کی دو قسمیں ہیں۔ وہ جو ونڈو کے نچلے حصے سے منسلک ہیں - مین مینو، اور وہ جو پیغام کو تفویض کیے گئے ہیں، مثال کے طور پر، بیلٹ کے بٹن کو حذف کریں، ترمیم کریں، تبدیل کریں۔ جب آپ مین مینو بٹن پر کلک کرتے ہیں، تو اسی نام کا پیغام بھیجا جاتا ہے، مثال کے طور پر، جب آپ "My Reminders" پر کلک کرتے ہیں، تو "My Reminders" کا متن بس بھیج دیا جائے گا ۔ اور کال بیک کیوری کی بورڈ انسٹال کرتے وقت ہر بٹن کے لیے ایک مخصوص ویلیو سیٹ کی جاتی ہے اور اس کی ویلیو اسکرین پر دکھائے بغیر بھیجی جائے گی۔ اگلا ہمارے پاس BotStateCash فیلڈ ہے ۔ یہ ایک خاص طور پر بنائی گئی کلاس ہے جو بوٹ کی حالت اور توجہ کی نگرانی کرے گی، یہ ایک پیچیدہ عنصر ہے، آپ کو دباؤ ڈالنے کی ضرورت ہے۔ حروف کی تعداد حد سے تجاوز کر گئی تھی، جو ویسے کہیں نہیں لکھی گئی))۔ تو حصہ دو کا لنک یہ ہے۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION