An event-driven architecture wrapper for Wechaty that applies the CQS principle by using separate Query and Command messages to retrieve and modify the bot state, respectively.

Overview

CQRS Wechaty

NPM Version NPM Ducksify Extension ES Modules

An event-driven architecture wrapper for Wechaty that applies the CQS principle by using separate Query and Command messages to retrieve and modify the bot state, respectively.

Command Query Responsibility Segregation (CQRS) Wechaty

Image source: Introducing Derivative Event Sourcing

Command Query Responsibility Separation (CQRS)

Command query responsibility separation (CQRS) generalises CQS to message-driven and event-driven architectures: it applies the CQS principle by using separate Query and Command messages to retrieve and modify data, respectively.

Wikipedia: Command–query separation

Command Query Responsibility Segregation (CQRS) Pattern

Image source: CQRS (command query responsibility segregation)

Motivation

Can we use Wechaty by only sending / receiving the Plain Old JavaScript Object (POJO)?

That's an Event-driven way, which will give us the following benifites:

  1. Better integration with Domain-driven Design (DDD)
  2. Decouple the sub-systems with the Wechaty instance completely
  3. Enable using Wechaty with Microservices
  4. Make it possible for providing an API endpoint with JSON request/responses
  5. etc.

So we decided to support the Event-driven Architecture by enabling the Event-driven Programming with Wechaty by publishing the wechaty-cqrs NPM module.

Features

  1. Convert Wechaty instance to a messaging bus$ with the from() function.
  2. Well-defined commands, queries, responses, and events payload creators.
  3. A great execute$() helper function for sending the events to the bus and get back the response.
  4. Well-defined events$ for the Wechaty events
  5. Well-defined sayables for build all the message contents
  6. Static typing with TypeScript with all events & streams
  7. Working perfect with the powerful RxJS

Usage

Install

npm install wechaty-cqrs wechaty

Quick start

Here's the CQRS version of the Wechaty ding/dong bot:

import * as CQRS    from 'wechaty-cqrs'
import * as WECHATY from 'wechaty'
import { filter, map, mergeMap }  from 'rxjs/operators'

const wechaty = WECHATY.WechatyBuilder.build()
await wechaty.init()

const bus$ = CQRS.from(wechaty)

bus$.pipe(
  filter(CQRS.isActionOf(CQRS.actions.messageReceivedEvent)),
  // MessageReceivedEvent -> Sayable
  map(messageId => CQRS.duck.actions.getSayablePayloadQuery(
    messageReceivedEvent.meta.puppetId,
    messageId,
  )),
  mergeMap(CQRS.execute$(bus$)(CQRS.duck.actions.getSayablePayloadQueryResponse)),
  // Log `sayable` to console
).subscribe(sayable =>
  console.info('Sayable:', sayable),
)

bus$.next(CQRS.duck.actions.startCommand(wechaty.puppet.id))

Getting Started

Here's a video introduction for CQRS Wechaty with live demo, presented by Huan:

CQRS Wechaty Getting Started

YouTube: https://youtu.be/kauxyPVa0jo

The getting started ding-dong-bot.ts in the video: https://github.com/wechaty/getting-started/blob/main/examples/cqrs/ding-dong-bot.ts

Diagrams

CQRS Events Structure

graph LR
  classDef event fill:DarkGoldenRod
  classDef command fill:blue
  classDef query fill:green

  subgraph Command
    C(VerbNounCommand):::command
  end

  subgraph Response
    RC(VerbNounCommandResponse)
    RQ(GetNounQueryResponse)
  end
    
  subgraph Query
    Q(GetNounQuery):::query
  end

  subgraph Event
    ER(ReceivedEvent):::event
  end

  C-->RC

  ER-->ER

  Q-->RQ

Command

sequenceDiagram
    participant Bus
    participant Redux
    participant Wechaty

    Bus->>Redux: ExecuteCommand
    Redux->>Wechaty: Call
    Wechaty->>Redux: Call Return (void)
    Redux->>Bus: ExecuteCommandResponse

Query

sequenceDiagram
    participant Bus
    participant Redux
    participant Wechaty

    Bus->>Redux: GetNounQuery
    Redux->>Wechaty: Call
    Wechaty->>Redux: Call Return (value)
    Redux->>Bus: GetNounQueryResponse

Event

sequenceDiagram
    participant Bus
    participant Redux
    participant Wechaty

    Wechaty->>Redux: ReceivedEvent
    Redux->>Bus: ReceivedEvent

API Reference

Read CQRS Wechaty API Reference at: https://paka.dev/npm/wechaty-cqrs

Blogs

Resources

History

main

v0.10 (Mar 17) Beta release

  • v0.9 (Mar 17,2022): Refactoring(clean) module exports
  • v0.7 (Mar 16, 2022): Refactoring execute$ with duck.actions builders.
  • v0.6 (Mar 13, 2022): Alpha release.
  • v0.4 (Mar 13, 2022): CQRS Ding/Dong BOT works as expected.
  • v0.2 (Mar 11, 2022): Unit tests all passed, DevOps enabled.
  • v0.0.1 (Mar 6, 2022): Init README & Draft design.

Author

Huan LI (李卓桓), Microsoft Regional Director, [email protected]

Profile of Huan LI (李卓桓) on StackOverflow

Copyright & License

  • Code & Docs © 2022 Huan (李卓桓) <[email protected]>
  • Code released under the Apache-2.0 License
  • Docs released under Creative Commons
You might also like...

Examples of how to do query, style, dom, ajax, event etc like jQuery with plain javascript.

You (Might) Don't Need jQuery Frontend environments evolve rapidly nowadays and modern browsers have already implemented a great deal of DOM/BOM APIs

Dec 24, 2022

Automaticly parses known pocket ips patch resources, scans folders or zip files for matching roms and applies the patches.

Pocket Automaton Automaticly parses known pocket ips patch resources, scans folders or zip files for matching roms and applies the patches. Usage pock

Nov 27, 2022

Chrome extension that applies phrase-based line breaking and visible phrase boundaries to the current page.

Chrome extension that applies phrase-based line breaking and visible phrase boundaries to the current page.

BudouX Chrome Extension This extension applies the phrase-based line breaking or the Japanese Wakachi-gaki style line breaking to the current page. Pl

Nov 18, 2022

A solid create-remix app, that applies best practices into a clean, batteries included template. SQLite version. Deploys to Fly.io

A solid create-remix app, that applies best practices into a clean, batteries included template. SQLite version. Deploys to Fly.io

Remix Barebones Stack npx create-remix --template dev-xo/barebones-stack A solid create-remix app, that follows community guidelines and applies best

Dec 30, 2022

An event emitter that allows you to manage your global state

Thor Event Emitter Event emitter to manage your state. An event emitter that allows you to manage your global state. Instead of using global giant obj

Apr 18, 2022

💊 Event-driven DOM programming in a new style

Capsule v0.5.3 Event-driven DOM programming in a new style Features Supports event-driven style of frontend programming in a new way. Supports event d

Oct 1, 2022

A chat logs online saver for discord bots to save messages history & cleared messages online

A chat logs online saver for discord bots to save messages history & cleared messages online

Chat Logs NPM package that saves messages online to view it later Useful for bots where users can save messages history & cleared messages online Supp

Dec 28, 2022

Firebase Storage with Angular 14 example: Upload File, Retrieve, Display, Download Url & Delete using @angular/fire AngularFireStorage

Firebase Storage with Angular 14 example: Upload File, Retrieve, Display, Download Url & Delete using @angular/fire AngularFireStorage

Angular 14 File Upload to Firebase Storage example I will show you how to make Angular 14 Firebase Storage: File Upload/Display/Delete Application usi

Sep 7, 2022

A simple to do list webpage where you can log the daily tasks you have to do, mark them as checked, modify them, reorder them and remove them. Made using HTML, CSS and JavaScript.

A simple to do list webpage where you can log the daily tasks you have to do, mark them as checked, modify them, reorder them and remove them.  Made using HTML, CSS and JavaScript.

To-Do-List This Webpage is for an app called To-Do-List which helps you add, remove or check tasks you have to do. It is a simple web page which conta

Mar 12, 2022
Comments
  • Compatible with Class events with NestJS

    Compatible with Class events with NestJS

    In NestJS, all Data Transfer Object (DTO) is a Class, and it uses decorators to deal with those event classes.

    Wechaty CQRS should have an interface to be compatible with the NestJS DTO Classes.

    ~~It seems that https://github.com/typestack/class-transformer will be a solution.~~

    ClassTransformer is not necessary and does not fit our requirements. use an Object.setPrototype() to link a plain object to the class as an instance object.

    enhancement 
    opened by huan 1
Owner
Wechaty
Conversational RPA SDK for Chatbot Makers
Wechaty
'event-driven' library aims to simplify building backends in an event driven style

'event-driven' library aims to simplify building backends in an event driven style(event driven architecture). For message broker, light weight Redis Stream is used and for event store, the well known NoSQL database, MongoDB, is used.

Sihoon Kim 11 Jan 4, 2023
adds the *scrollin* and *scrollout* events to jquery, which will fire when any given element becomes (respectively) visible and invisible in the browser viewpori

jQuery.scrolling This plugin adds the scrollin and scrollout events to jquery: these events will fire when any given element becomes visible/invisible

Dark 5 Apr 7, 2021
A simple cli-app that allows you to divide a YouTube video into multiple separate videos base on a video's time stamps. Powered by pkg and yt-scissors library.

YouTube-Scissors CLI A simple CLI app that allows you to divide a YouTube video into multiple separate videos base on a video's time stamps. This proj

Gabe 23 Nov 8, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A simple query builder, it will helps to develop DSL query for Elasticsearch

Elasticsearch Dynamic Query Builder A simple query builder, it will helps to develop DSL query for elasticsearch Installation You can start it from np

Hashemi Rafsan 4 Nov 20, 2022
Get-A-Room example application using Domain Driven Design and Clean Architecture. Written in TypeScript and deployed to AWS with a serverless stack.

Domain Driven Microservices on AWS in Practice This project provides a Domain Driven Design & Clean Architecture-informed, multi-service event-driven

Mikael Vesavuori 5 Dec 31, 2022
awsrun 189 Jan 3, 2023
An AWS Cloud Native application using CDK that defines a Serverless Event Driven application for interacting with Twitter and utilising Machine Learning / AI as a Service.

AWS Serverless Event Driven Twitter Bot An AWS Cloud Native application using CDK (Written in TypeScript) that defines a Serverless Event Driven appli

null 4 Dec 18, 2022