Skip to content

Commit

Permalink
Merge pull request #24 from TogetherCrew/microservices
Browse files Browse the repository at this point in the history
Microservices
  • Loading branch information
cyri113 authored Apr 13, 2024
2 parents d18152d + 02d32df commit bcbc2b9
Show file tree
Hide file tree
Showing 110 changed files with 12,172 additions and 5,842 deletions.
34 changes: 17 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Production CI/CD Pipeline

on:
push:
branches:
- main
pull_request:
on: push
# push:
# branches:
# - main
# pull_request:

env:
REGISTRY: ghcr.io
Expand All @@ -17,20 +17,20 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'
- run: yarn install
- run: yarn run lint
node-version: 20
cache: 'npm'
- run: npm install --force
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'
- run: yarn install
- run: yarn run test
node-version: 20
cache: 'npm'
- run: npm install --force
- run: npm run test
# - run: yarn run test:e2e
coverage:
needs: [ test ]
Expand All @@ -39,14 +39,14 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'
- run: yarn install
node-version: 20
cache: 'npm'
- run: npm install --force
- uses: paambaati/codeclimate-action@v5.0.0
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: yarn run test:cov
coverageCommand: npm run test:cov
build-push:
needs: [ test, lint ]
runs-on: ubuntu-latest
Expand Down
22 changes: 20 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# compiled output
/dist
/node_modules
/build

# Logs
logs
Expand Down Expand Up @@ -34,5 +35,22 @@ lerna-debug.log*
!.vscode/launch.json
!.vscode/extensions.json

# ENV
.env
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# temp directory
.temp
.tmp

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"jest.enable": false
}
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ FROM node:alpine AS development

WORKDIR /usr/src/app

RUN apk update
RUN apk add --update --no-cache python3 make g++

COPY package*.json ./

RUN yarn install
RUN npm i --force

COPY . .

RUN yarn build
RUN npm run build

FROM node:alpine AS production

Expand All @@ -19,7 +22,7 @@ WORKDIR /usr/src/app

COPY package*.json ./

RUN yarn install --production
RUN npm i --production --force

COPY . .

Expand Down
56 changes: 21 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>

[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest

<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
# Telegram Bot

## Description

[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
The official TogetherCrew focused around data ingestion.

## Installation

- Create a telegram bot using BotFather
- Add the bot token to your .env file
- Add your bot to your chat (NOTE: It must be an admin to capture reactions)
- Start docker compose (for mongodb + neo4j)

```bash
$ npm install
```
Expand All @@ -39,12 +22,17 @@ $ npm install
$ npm run start

# watch mode
$ npm run start:dev
$ npm run start:dev [service]

# production mode
$ npm run start:prod
$ npm run start:prod [service]
```

Note: There are 3 services:
- bot
- event-store (raw dump to mongo)
- graph-store (creates interactions in neo4j)

## Test

```bash
Expand All @@ -58,16 +46,14 @@ $ npm run test:e2e
$ npm run test:cov
```

## Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Features

## Stay in touch
- Listens to Telegram events
- Store raw events in mongo
- Store interactions in neo4j

- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
NOTE: The telegram bot api doesn't support listening to delete events at this time.

## License
## Improvement opportunities

Nest is [MIT licensed](LICENSE).
- Break the `REACTED_TO` edge into 3 cases. `REACTED_TO`, `EDITED_REACTION`, and `REMOVED_REACTION`.
21 changes: 21 additions & 0 deletions SCHEMA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(TGChat { id, title, type })
(TGUser { id })
(TGMessage { id, text })

(TGUser)-[:CREATED_MESSAGE { timestamp }]->(TGMessage)
(TGMessage)-[:MESSAGE_EDITED { timestamp }]->(TGMessage)
(TGMessage)-[:MENTIONED]->(User)
(TGUser)-[:REACTED_TO { timestamp, old_reaction, new_reaction }]->(TGMessage)
(TGMessage)-[:REPLIED]->(TGMessage)


(TGUser)-[:JOINED { timestamp }]->(TGChat)
(TGUser)-[:LEFT { timestamp }]->(TGChat)

## Actions

### Message

1. Create or update chat
2. Create or update user
3. Create message
25 changes: 25 additions & 0 deletions apps/bot/src/bot.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Module } from '@nestjs/common';
import { BotService } from './bot.service';
import { ConfigModule } from '@nestjs/config';
// import { BotUpdate } from './bot.update';
import {
schemaConfig,
telegramConfig,
rmqConfig,
RmqModule,
} from '@app/common';
import { Services } from '@app/common';

@Module({
imports: [
ConfigModule.forRoot({
validationSchema: schemaConfig,
load: [telegramConfig, rmqConfig],
isGlobal: true,
}),
RmqModule.register(Services.EventStore),
RmqModule.register(Services.GraphStore),
],
providers: [BotService],
})
export class BotModule {}
45 changes: 45 additions & 0 deletions apps/bot/src/bot.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// bot.service.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { BotService } from './bot.service';
import { Services } from '@app/common';
import { ConfigService } from '@nestjs/config';

describe('BotService', () => {
let service: BotService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
BotService,
{
provide: Services.EventStore.name,
useValue: {
emit: jest.fn(),
},
},
{
provide: Services.GraphStore.name,
useValue: {
emit: jest.fn(),
},
},
{
provide: ConfigService,
useValue: {
get: jest.fn((key) => {
if (key === 'telegram.token') return 'mocked value';
return null;
}),
},
},
],
}).compile();

service = module.get<BotService>(BotService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
39 changes: 39 additions & 0 deletions apps/bot/src/bot.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { IgnoreEvent, Services, UpdateEvent } from '@app/common';
import { Inject, Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ClientProxy } from '@nestjs/microservices';
import { API_CONSTANTS, Bot } from 'grammy';

@Injectable()
export class BotService implements OnModuleInit {
private bot: Bot;
private readonly logger = new Logger(BotService.name);

constructor(
@Inject(Services.EventStore.name) private readonly eventClient: ClientProxy,
@Inject(Services.GraphStore.name) private readonly graphClient: ClientProxy,
private readonly configService: ConfigService,
) {
this.bot = new Bot(configService.get<string>('telegram.token'));

Object.values(IgnoreEvent).map((event) => {
this.bot.on(event, () => {
this.logger.warn(`Ignoring ${event} event.`);
});
});

Object.values(UpdateEvent).map((event) => {
this.bot.on(event, (ctx) => {
this.logger.log(`Received ${event} from ${ctx.chat.id}`);
this.eventClient.emit(event, ctx);
this.graphClient.emit(event, ctx);
});
});
}

async onModuleInit() {
await this.bot.start({
allowed_updates: API_CONSTANTS.ALL_UPDATE_TYPES,
});
}
}
13 changes: 13 additions & 0 deletions apps/bot/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { NestFactory } from '@nestjs/core';
import { BotModule } from './bot.module';
import { RmqService, Services } from '@app/common';

async function bootstrap() {
// const app = await NestFactory.createMicroservice(BotModule);
const app = await NestFactory.create(BotModule);
const rmqService = app.get<RmqService>(RmqService);
app.connectMicroservice(rmqService.getOptions(Services.TelegramBot.queue));
await app.startAllMicroservices();
app.listen(3000);
}
bootstrap();
6 changes: 3 additions & 3 deletions test/app.e2e-spec.ts → apps/bot/test/app.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
import { BotModule } from './../src/bot.module';

describe('AppController (e2e)', () => {
describe('BotController (e2e)', () => {
let app: INestApplication;

beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
imports: [BotModule],
}).compile();

app = moduleFixture.createNestApplication();
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions apps/bot/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/bot"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
Loading

0 comments on commit bcbc2b9

Please sign in to comment.