"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > रास्पबेरी पाई पर एक डिस्कोर्ड बॉट चलाना

रास्पबेरी पाई पर एक डिस्कोर्ड बॉट चलाना

2024-11-07 को प्रकाशित
ब्राउज़ करें:708

अनस्प्लैश पर डैनियल टैफजॉर्ड द्वारा कवर फ़ोटो

मैंने हाल ही में एक सॉफ्टवेयर इंजीनियरिंग बूटकैंप पूरा किया है, लीटकोड के आसान प्रश्नों पर काम करना शुरू किया है और मुझे लगा कि अगर मुझे प्रश्नों को हल करने के लिए दैनिक अनुस्मारक मिले तो इससे मुझे जवाबदेह बने रहने में मदद मिलेगी। मैंने इसे 24 घंटे के शेड्यूल पर चलने वाले एक डिसॉर्डर बॉट का उपयोग करके लागू करने का निर्णय लिया (बेशक, मेरे भरोसेमंद रास्पबेरी पाई पर) जो निम्नलिखित कार्य करेगा:

  • आसान लेटकोड प्रश्नों के पूर्वनिर्धारित डेटाबैंक पर जाएं
  • एक ऐसा प्रश्न लें जो डिसॉर्डर चैनल पर पोस्ट नहीं किया गया है
  • लीटकोड प्रश्न को डिसॉर्डर चैनल में एक थ्रेड के रूप में पोस्ट करें (ताकि आप आसानी से अपना समाधान जोड़ सकें)
  • चैनल पर दोबारा पोस्ट करने से बचने के लिए प्रश्न को पोस्ट किया गया के रूप में चिह्नित किया गया है

Running a Discord Bot on Raspberry Pi

मुझे एहसास है कि केवल लीटकोड पर जाना और एक दिन में एक प्रश्न हल करना आसान हो सकता है लेकिन मुझे इस मिनी-प्रोजेक्ट पर चैटजीपीटी की मदद से पायथन और डिस्कॉर्ड के बारे में बहुत कुछ सीखने को मिला। स्केचनोटिंग में भी यह मेरा पहला प्रयास है, इसलिए कृपया धैर्य रखें

Running a Discord Bot on Raspberry Pi

स्थापित करना

1. पायथन वर्चुअल वातावरण का उपयोग करें
2. निर्भरताएँ स्थापित करें
3. लीटकोड आसान प्रश्न डेटाबेस सेट करें
4. पर्यावरण चर सेट करें
5. डिस्कॉर्ड ऐप बनाएं
6. बॉट चलाएँ!

1. पायथन आभासी वातावरण का प्रयोग करें

मैं एक पायथन वर्चुअल वातावरण के उपयोग की अनुशंसा करता हूं क्योंकि जब मैंने शुरुआत में उबंटू 24.04 पर इसका परीक्षण किया, तो मुझे नीचे दी गई त्रुटि का सामना करना पड़ा

Running a Discord Bot on Raspberry Pi

इसे सेट करना अपेक्षाकृत आसान है, बस निम्नलिखित कमांड चलाएं और वॉइला, आप एक पायथन आभासी वातावरण में हैं!

python3 -m venv ~/py_envs
ls ~/py_envs  # to confirm the environment was created
source ~/py_envs/bin/activate

2. निर्भरताएँ स्थापित करें

निम्नलिखित निर्भरताएँ आवश्यक हैं:

  • एडब्ल्यूएस सीएलआई

निम्नलिखित चलाकर AWS CLI स्थापित करें:

curl -O 'https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip'
unzip awscli-exe-linux-aarch64.zip 
sudo ./aws/install
aws --version

फिर आवश्यक क्रेडेंशियल जोड़ने के लिए awsconfig चलाएँ। AWS CLI दस्तावेज़ कॉन्फ़िगर करें देखें।

  • पिप निर्भरताएं

निम्नलिखित पाइप निर्भरता को pip install -r require.txt चलाकर एक आवश्यकता फ़ाइल के साथ स्थापित किया जा सकता है।

# requirements.txt

discord.py
# must install this version of numpy to prevent conflict with
# pandas, both of which are required by leetscrape
numpy==1.26.4   
leetscrape
python-dotenv

3. लेटकोड आसान प्रश्न डेटाबेस सेट करें

लीटस्क्रेप इस कदम के लिए महत्वपूर्ण था। इसके बारे में अधिक जानने के लिए, लीट्सक्रैप दस्तावेज़ देखें।
मैं केवल लेटकोड के आसान प्रश्नों पर काम करना चाहता हूं (मेरे लिए, वे काफी कठिन भी हैं) इसलिए मैंने निम्नलिखित कार्य किया:

  • लीटस्क्रेप का उपयोग करके लेटकोड से सभी प्रश्नों की सूची प्राप्त करें और सूची को सीएसवी में सहेजें
from leetscrape import GetQuestionsList

ls = GetQuestionsList()
ls.scrape() # Scrape the list of questions
ls.questions.head() # Get the list of questions
ls.to_csv(directory="path/to/csv/file")
  • एक अमेज़ॅन डायनेमोडीबी तालिका बनाएं और इसे पिछले चरण में सहेजे गए सीएसवी से फ़िल्टर किए गए आसान प्रश्नों की सूची से भर दें।
import csv
import boto3
from botocore.exceptions import BotoCoreError, ClientError

# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')

def filter_and_format_csv_for_dynamodb(input_csv):
    result = []

    with open(input_csv, mode='r') as file:
        csv_reader = csv.DictReader(file)

        for row in csv_reader:
            # Filter based on difficulty and paidOnly fields
            if row['difficulty'] == 'Easy' and row['paidOnly'] == 'False':
                item = {
                    'QID': {'N': str(row['QID'])},  
                    'titleSlug': {'S': row['titleSlug']}, 
                    'topicTags': {'S': row['topicTags']},  
                    'categorySlug': {'S': row['categorySlug']},  
                    'posted': {'BOOL': False}  
                }
                result.append(item)

    return result

def upload_to_dynamodb(items, table_name):
    table = dynamodb.Table(table_name)

    try:
        with table.batch_writer() as batch:
            for item in items:
                batch.put_item(Item={
                    'QID': int(item['QID']['N']),  
                    'titleSlug': item['titleSlug']['S'],
                    'topicTags': item['topicTags']['S'],
                    'categorySlug': item['categorySlug']['S'],
                    'posted': item['posted']['BOOL']
                })
        print(f"Data uploaded successfully to {table_name}")

    except (BotoCoreError, ClientError) as error:
        print(f"Error uploading data to DynamoDB: {error}")

def create_table():
    try:
        table = dynamodb.create_table(
            TableName='leetcode-easy-qs',
            KeySchema=[
                {
                    'AttributeName': 'QID',
                    'KeyType': 'HASH'  # Partition key
                }
            ],
            AttributeDefinitions=[
                {
                    'AttributeName': 'QID',
                    'AttributeType': 'N'  # Number type
                }
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 5,
                'WriteCapacityUnits': 5
            }
        )

        # Wait until the table exists
        table.meta.client.get_waiter('table_exists').wait(TableName='leetcode-easy-qs')
        print(f"Table {table.table_name} created successfully!")

    except Exception as e:
        print(f"Error creating table: {e}")

# Call function to create the table
create_table()

# Example usage
input_csv = 'getql.pyquestions.csv'  # Your input CSV file
table_name = 'leetcode-easy-qs'      # DynamoDB table name

# Step 1: Filter and format the CSV data
questions = filter_and_format_csv_for_dynamodb(input_csv)

# Step 2: Upload data to DynamoDB
upload_to_dynamodb(questions, table_name)

4. पर्यावरण चर सेट करें

पर्यावरण चर संग्रहीत करने के लिए एक .env फ़ाइल बनाएं

DISCORD_BOT_TOKEN=*****

5. डिस्कॉर्ड ऐप बनाएं

पर्याप्त अनुमतियों के साथ एक डिस्कॉर्ड ऐप और बॉट बनाने के लिए डिस्कॉर्ड डेवलपर डॉक्स में दिए गए निर्देशों का पालन करें। बॉट को कम से कम निम्नलिखित OAuth अनुमतियों के साथ अधिकृत करना सुनिश्चित करें:

  • संदेश भेजें
  • सार्वजनिक थ्रेड बनाएं
  • थ्रेड्स में संदेश भेजें

6. बॉट चलाएँ!

नीचे बॉट के लिए कोड है जिसे Python3 discord-leetcode-qs.py कमांड के साथ चलाया जा सकता है।

import os
import discord
import boto3
from leetscrape import GetQuestion
from discord.ext import tasks
from dotenv import load_dotenv
import re
load_dotenv()

# Discord bot token
TOKEN = os.getenv('DISCORD_TOKEN')

# Set the intents for the bot
intents = discord.Intents.default()
intents.message_content = True # Ensure the bot can read messages

# Initialize the bot
bot = discord.Client(intents=intents)
# DynamoDB setup
dynamodb = boto3.client('dynamodb')

TABLE_NAME = 'leetcode-easy-qs'
CHANNEL_ID = 1211111111111111111  # Replace with the actual channel ID

# Function to get the first unposted item from DynamoDB
def get_unposted_item():
    response = dynamodb.scan(
        TableName=TABLE_NAME,
        FilterExpression='posted = :val',
        ExpressionAttributeValues={':val': {'BOOL': False}},
    )
    items = response.get('Items', [])
    if items:
        return items[0]
    return None

# Function to mark the item as posted in DynamoDB
def mark_as_posted(qid):
    dynamodb.update_item(
        TableName=TABLE_NAME,
        Key={'QID': {'N': str(qid)}},
        UpdateExpression='SET posted = :val',
        ExpressionAttributeValues={':val': {'BOOL': True}}
    )

MAX_MESSAGE_LENGTH = 2000
AUTO_ARCHIVE_DURATION = 2880

# Function to split a question into words by spaces or newlines
def split_question(question, max_length):
    parts = []
    while len(question) > max_length:
        split_at = question.rfind(' ', 0, max_length)
        if split_at == -1:
            split_at = question.rfind('\n', 0, max_length)
        if split_at == -1:
            split_at = max_length

        parts.append(question[:split_at].strip())
        # Continue with the remaining text
        question = question[split_at:].strip()

    if question:
        parts.append(question)

    return parts

def clean_question(question):
    first_line, _, remaining_question = message.partition('\n')
    return re.sub(r'\n{3,}', '\n', remaining_question)

def extract_first_line(question):
    lines = question.splitlines()
    return lines[0] if lines else ""

# Task that runs on a schedule
@tasks.loop(minutes=1440) 
async def scheduled_task():
    channel = bot.get_channel(CHANNEL_ID)
    item = get_unposted_item()

    if item:
        title_slug = item['titleSlug']['S']
        qid = item['QID']['N']
        question = "%s" % (GetQuestion(titleSlug=title_slug).scrape())

        first_line = extract_first_line(question)
        cleaned_question = clean_message(question)
        parts = split_message(cleaned_question, MAX_MESSAGE_LENGTH)

        thread = await channel.create_thread(
            name=first_line, 
            type=discord.ChannelType.public_thread
        )

        for part in parts:
            await thread.send(part)

        mark_as_posted(qid)
    else:
        print("No unposted items found.")

@bot.event
async def on_ready():
    print(f'{bot.user} has connected to Discord!')
    scheduled_task.start()

@bot.event
async def on_thread_create(thread):
    await thread.send("\nYour challenge starts here! Good Luck!")

# Run the bot
bot.run(TOKEN)

बॉट चलाने के लिए कई विकल्प हैं। अभी, मैं इसे केवल tmux शेल में चला रहा हूं, लेकिन आप इसे डॉकर कंटेनर में या AWS, Azure, DigitalOcean या अन्य क्लाउड प्रदाताओं के VPC पर भी चला सकते हैं।

अब मुझे वास्तव में लेटकोड प्रश्नों को हल करने का प्रयास करना है...

विज्ञप्ति वक्तव्य यह आलेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/beretests/running-a-discord-bot-on-raspberry-pi-4la4?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3