Skip to main content

Messenger Check

524 words·3 mins
NICK
Author
NICK

Role: Developer
Domain: Communication

                           - Stack -

Python3, Threading, AsyncIO, Telethon lib

                      - Project Overview -

Messenger Check is a Python-based program designed to process a list of phone numbers, verify their existence on messaging platforms such as Telegram and WhatsApp, and store the results in a structured JSON file. In case of a large dataset of phone numbers the program adheres to incremental processing of data without excessive memory consumption.

Initially, this program was developed as a component of a larger OSINT-based project. However, as the client’s requirements evolved, it became an auxiliary tool for a spammer program. In a turn of events, the developer embraced this new direction. The feature is straightforward: it sorts through the potential dataset for the spammer, ensuring content delivery by confirming the existence of the intended recipients.

                   - Challenges & Solutions -

One key challenge was to maintain high modularity, allowing users to integrate multiple messenger APIs (both synchronous and asynchronous) as needed without worrying about mixing sync and async code. While it’s not the ideal practice, it achieves the goal.

Pipeline and Observer Pattern:

  • Pipeline Pattern: The code creates a processing pipeline: Reader feeds data to observers, which in turn pass processed data to the handlers. This structure enables an efficient and scalable workflow by distributing tasks asynchronously or synchronously as required.
  • Observer Pattern: With observer pattern where data is distributed to relevant handlers based on observer type.

Threading and Asynchronous Execution:

  • Thread Management: Asynchronous tasks run in a separate thread, while other synchronous tasks are managed within the main thread.
  • Async Task Queue maintains a task queue for asynchronous API calls, using an event loop to process data without blocking other threads.

Overall, the code incorporates several OOP Principles and Patterns, SOLID Principles, though there’s still room for improvement.

                   - Reflections & Takeaways -
  1. Architectural Choice:
  • Reflection: The design decision did not involve a multiprocessing architecture. After thorough evaluation, it was observed that a multiprocessing approach might have provided better performance or efficiency.

  • Takeaway: Careful consideration of architectural patterns is crucial, as choosing the right one can significantly impact performance and scalability. Reevaluating initial choices and staying open to improvements can lead to more optimal solutions in the long run.

  1. Flexibility:
  • Reflection: The architecture’s decoupled observers and handlers provided significant adaptability. This flexibility allowed to incorporate various APIs and change communication modes without needing substantial refactoring.

  • Takeaway: A design that prioritizes decoupling makes future development and integration smoother, emphasizing the value of maintainable and adaptable systems.

  1. Efficiency:
  • Reflection: Utilizing asynchronous processing proved efficient in handling numerous I/O tasks, while multithreading contributed to overall performance optimization. This approach ensured smooth system operations without bottlenecks.

  • Takeaway: Balancing asynchronous and multithreaded approaches can be highly effective in achieving performance goals, particularly in scenarios involving heavy I/O operations and data processing.

  1. Scalability:
  • Reflection: The system’s modular design supported future growth by allowing the addition of new services and functionalities with minimal disruption to the existing setup.

  • Takeaway: Designing with scalability in mind from the outset enables seamless expansion, which is crucial for systems expected to grow or evolve. This strategic foresight can prevent significant redevelopment costs down the road.