NUS Hackers Wiki
NUS Hackers Wiki
  • NUS Hackers Wiki
  • Hackerschool
    • Virtual Machines and Linux
    • Beginners' Guide to the Terminal
      • Introduction to the Terminal
      • Modern Shell Tools
      • Shell Scripting
      • Real World Scripting
      • Resources
    • Self-Hosting: Three Easy Pieces
      • 1. Setting up your server
      • 2. Running Services
      • 3. Monitoring your server
    • Vim
    • Introduction to Zig
      • Language Basics
      • Error Handling
      • Memory Management
      • Working with C
      • Exploring comptime
    • CI/CD with Github Actions
      • Background
      • Basics of Github Actions
        • Target workflow
        • Running unit tests
        • Linting code
        • Deploying to Github Pages
      • Advanced use cases
        • Pollers
        • Github script
        • Executing third-party scripts
        • Reusable workflows
      • Cookbook
    • Lightning Git
      • Git Concepts
      • Getting Started with Git
      • Making your first commit
      • Branching
      • Merge Conflicts
      • Integrating remote repositories
      • Collaborative Workflows
      • Commit Manipulation and Reflog
      • Interactive rebasing
      • filter-repo
  • Orbital
    • JavaScript
      • Browser Developer Tools
      • Getting Started
      • Datatypes
      • Operators and Operations
      • Loops and Conditions
      • Functions
      • Strings
      • Arrays
      • HTML
        • Getting Started
        • Tag Attributes
        • HTML Forms
        • Browser Inspector
      • CSS
        • Selectors
        • Colors in CSS
        • Measurements in CSS
        • The Box Model
        • Adding Styles - Part 1
        • Adding Styles - Part 2
      • Working with the DOM
        • Querying the DOM - Selectors
        • Querying the DOM - Element Attributes
        • Querying the DOM - Element Styles
        • Events with JS and HTML
        • Exercise: Click Counter
        • Editing the DOM
        • Fetch Requests
        • Exercise: The NUSMods API
    • React
      • Setup
      • State
    • React Native
      • Setup
      • Intro to JSX
      • Basic Syntax
      • Handling UI
      • Props
      • State Management
    • Git
      • Setup
      • Command Glossary
      • Fundamental Concepts
        • Getting Started
        • Integrating Remote Repositories
        • Branching
        • Merge Conflicts
      • Collaborative Workflows
        • Fork and PR Workflow
        • Branch and PR Workflow
      • Advanced Concepts
        • Ignoring Files
        • Commit Message Conventions
        • Github Collaborators
        • CI/CD with Github Actions
        • Advanced Git Commands
      • FAQ
    • Telegram Bot
      • Creating a TeleBot
      • API Calls
      • Telebot Basics
      • Integrating API's
    • Relational Database
      • Database Overview
      • Database Design
      • Entity Relationship Diagram
      • SQL Basics & PostgreSQL
    • TypeScript
      • Types and Interfaces
      • Utility Types
      • Typing Component Props, Events, and Hooks
      • Why You Should Avoid Using any (and What to Do Instead)
      • TypeScript Tricks You’ll Use All the Time in React
Powered by GitBook
On this page
Edit on GitHub
Export as PDF
  1. Orbital
  2. Telegram Bot

Integrating API's

If you are a CS student, you may start to think about the different Focus Areas and what you may want to take.

Let's create a telebot that does the following.

  1. Shows us what Focus Areas there are in CS

  2. What modules are associated with the respective Focus Areas

  3. Retrieve information about the module

First, import the following packages

import asyncio
import nest_asyncio
from typing import Final
from telegram import (Update, InlineKeyboardButton, InlineKeyboardMarkup)
from telegram.ext import (Application, CallbackQueryHandler, CommandHandler,
                          MessageHandler, filters, ContextTypes)
from telegram.constants import ParseMode
import requests

nest_asyncio.apply()

Next, we replace the Token with our unique token ID

TOKEN: Final = '' # NEVER SHARE THIS PUBLICLY

We create an immutable list with each sublist representing a focus area

PRIMARIES_LIST: Final = [
    ['CS3230', 'CS3231', 'CS3236', 'CS4231', 'CS4234'],            # Algo
    ['CS2109S', 'CS3263', 'CS3264', 'CS4243', 'CS4246', 'CS4248'], # AI
    ['CS3241', 'CS3242', 'CS3247', 'CS4247', 'CS4350'],            # Games
    ['CS2107', 'CS3235', 'CS4236', 'CS4230', 'CS4238', 'CS4239'],  # Security
    ['CS2102', 'CS3223', 'CS4221', 'CS4224', 'CS4225'],            # Database
    ['CS2108', 'CS3245', 'CS4242', 'CS4248', 'CS4347'],            # MIR
    ['CS2105', 'CS3103', 'CS4222', 'CS4226', 'CS4231'],            # Networks
    ['CS3210', 'CS3211', 'CS4231', 'CS4223'],                      # Parallel
    ['CS2104', 'CS3211', 'CS4212', 'CS4215'],                      # Languages
    ['CS2103T', 'CS3213', 'CS3219', 'CS4211', 'CS4218', 'CS4239']  # SWE
]

If I want the query the title of a module from the module code, how would I do this?

In this instance, we set {acadYear} as 2023-2024, and the user will input their module code.

def get_mod_title(module_code: str) -> str:
    endpoint = f'https://api.nusmods.com/v2/2023-2024/'
                                 f'modules/{module_code}.json'
    response = requests.get(endpoint)
    description = response.json()
    title = description['title']
    return title

Inline Keyboard Buttons

Let's say we want to see all the focus areas via INLINE KEYBOARD AREAS

  1. Define the the function

  2. Create the Keyboard via a 2D list of of InLineKeyboardButtonobjects -> The number of InLineKeyboardButton() elements in a sublist represents the number of buttons in a row

async def focusarea(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:

    keyboard = [
        [   # 4 Buttons in a row
            InlineKeyboardButton(text="Algo & Theory", callback_data="Algorithms and Theory"),
            InlineKeyboardButton(text="AI", callback_data="Artificial Intelligence"),
            InlineKeyboardButton(text="G & G", callback_data="Computer Graphics and Games"),
        ],
        [
            InlineKeyboardButton(text="Security", callback_data="Computer Security"),
            InlineKeyboardButton(text="DB", callback_data="Database Systems"),
            InlineKeyboardButton(text="MIR", callback_data="Multimedia Information Retrieval"),
        ],
        [   # 4 buttons in a row
            InlineKeyboardButton(text="Networks", callback_data="Networking and Distributed Systems"),
            InlineKeyboardButton(text="Parallel", callback_data="Parallel Computing"),
            InlineKeyboardButton(text="Prog Langs", callback_data="Programming Languages"),
            InlineKeyboardButton(text="SWE", callback_data="Software Engineering"),
        ]
    ]

    reply_markup = InlineKeyboardMarkup(keyboard)

    await update.message.reply_text(text="Please choose a focus area: ", reply_markup=reply_markup)
  1. Inline Keyboard Markup that displays how the keyboard is displayed

  2. Sending the message "Please choose a focus area: "

    reply_markup = InlineKeyboardMarkup(keyboard)
    
    await update.message.reply_text(text="Please choose a focus area: ", reply_markup=reply_markup)

The user clicks on one of the buttons.

We want the message to change and reflect the user's chosen focus area and it's primaries. Let's create a helper function get_primaries()

  • Note: we have previously created a function get_primaries_text()

def get_primaries(focus_area_title: str) -> str:
    primaries_list = []
    match focus_area_title:
        case "Algorithms and Theory":
            primaries_list = PRIMARIES_LIST[0]
        case "Artificial Intelligence":
            primaries_list = PRIMARIES_LIST[1]
        case "Computer Graphics and Games":
            primaries_list = PRIMARIES_LIST[2]
        case "Computer Security":
            primaries_list = PRIMARIES_LIST[3]
        case "Database Systems":
            primaries_list = PRIMARIES_LIST[4]
        case "Multimedia Information Retrieval":
            primaries_list = PRIMARIES_LIST[5]
        case "Networking and Distributed Systems":
            primaries_list = PRIMARIES_LIST[6]
        case "Parallel Computing":
            primaries_list = PRIMARIES_LIST[7]
        case "Programming Languages":
            primaries_list = PRIMARIES_LIST[8]
        case "Software Engineering":
            primaries_list = PRIMARIES_LIST[9]
        case _:
            primaries_list = []

    return get_primaries_text(primaries_list)

Create the display_focus_area() function

async def display_focus_area(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    # The Inline Keyboard Provides a Callback Query that waits for the user's answer
    query = update.callback_query
    await query.answer()

    # Obtains the primaries text based on the data provided by the Query
    focus_area_primaries = get_primaries(query.data)

    # Changes the 'Please select' message to:
    await query.edit_message_text(text=f"Selected option: <b>{query.data}</b>\n"
                                       f"Enter '(MODULE_CODE)' to find out more:\n\n"
                                       f"Primaries: \n{focus_area_primaries}",
                                  parse_mode=ParseMode.HTML)

Explanation

  • query = update.callback_query

    Retrieve the callback query (info) from the update (i.e. the button the user clicked on)

  •  await query.answer()

    Informs telegram that the query has been received

  • focus_area_primaries = get_primaries(query.data)

    Obtains the text of primaries based on data from query

  • await query.edit_message_text(text=f"Selected option: <b>{query.data}</b>\n"
                                           f"Enter '(MODULE_CODE)' to find out more:\n\n"
                                           f"Primaries: \n{focus_area_primaries}",
                                      parse_mode=ParseMode.HTML)

    Changes the original message that contained the inline keyboard to -> Show the user's selected option in bold -> Prompt the user to enter a module code -> Show the primary modules in that focus area

The user inputs a module code.

def display_module(module_json) -> str:
    # Extract fields from the JSON object
    module_code = module_json.get('moduleCode', 'N/A')
    module_title = module_json.get('title', 'No Title')
    module_description = module_json.get('description', 'No Description')
    module_credits = module_json.get('moduleCredit', 'N/A')
    module_prereqs = module_json.get('prerequisite', 'None')
    module_sems = ", ".join(map(str, module_json.get('semesterData', [])))

    # Construct the message
    message = f'{module_code} {module_title}\n'
    message += f'{module_credits} MCs awarded\n'
    message += f'Semesters: {module_sems}\n'
    message += f'Prerequisites: {module_prereqs}\n'
    message += f'\nAbout: {module_description}\n'

    return message

PreviousTelebot BasicsNextRelational Database

Last updated 11 months ago

We will make use of the NUSMods API:

https://api.nusmods.com/v2/