Skip to content

Commit

Permalink
feat(app update service): implement start command
Browse files Browse the repository at this point in the history
  • Loading branch information
havrydotdev committed Oct 12, 2023
1 parent fe30c3b commit b2e412e
Show file tree
Hide file tree
Showing 31 changed files with 397 additions and 24 deletions.
10 changes: 9 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
TELEGRAM_BOT_TOKEN='6462989888:AAG3LDyEjvtwmIYv2MQs9DEhxpELhfAH8Dg'
TELEGRAM_BOT_TOKEN='6462989888:AAG3LDyEjvtwmIYv2MQs9DEhxpELhfAH8Dg'
DB_TYPE="better-sqlite3"
DB_NAME='./dev.sqlite'
DB_LOGGING=true
DB_SYNCHRONIZE=true
AWS_REGION='eu-north-1'
AWS_ACCESS_KEY='AKIA43IVE7H4KK7ONQHK'
AWS_SECRET_ACCESS_KEY='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'
AWS_PUBLIC_BUCKET_NAME='chatgram'
41 changes: 41 additions & 0 deletions .github/workflows/nodejs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# The name of the workflow. GitHub displays the names of your workflows under your repository's "Actions" tab. If you omit `name`, GitHub displays the workflow file path relative to the root of the repository.
name: Node.js CI

# This example workflow assumes that the default branch for your repository is `main`. If the default branch has a different name, edit this example and add your repository's default branch.
on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
# <!-- This is a YAML comment for use in annotated code examples. -->
# You can run this workflow using a different operating systems.
#
# The starter workflow configures jobs to run on Linux, using the GitHub-hosted `ubuntu-latest` runners. You can change the `runs-on` key to run your jobs on a different operating system.
#
# For example, you can use the GitHub-hosted Windows runners by specifying `runs-on: windows-latest`. Or, you can run on the GitHub-hosted macOS runners using `runs-on: macos-latest`.
#
# You can also run jobs in Docker containers, or you can provide a self-hosted runner that runs on your own infrastructure. For more information, see "[AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on)."
runs-on: ubuntu-latest

# This job uses a matrix strategy to run the job four times, once for each specified Node version. For more information, see "[AUTOTITLE](/actions/using-jobs/using-a-matrix-for-your-jobs)."
strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
#
steps:
# This step uses the `actions/checkout` action to download a copy of your repository on the runner.
- uses: actions/checkout@v3
# This step uses the `actions/setup-node` action to set up Node.js for each version indicated by the `matrix.node-version` key above.
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
# This step runs `npm ci` to install any dependencies listed in your `package.json` file.
- run: npm ci
# This step runs the `build` script if there is one specified under the `scripts` key in your `package.json` file.
- run: npm run build --if-present
# This step runs the `test` script that is specified under the `scripts` key in your `package.json` file.
- run: npm test
Binary file added dev.sqlite
Binary file not shown.
51 changes: 51 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.0.0",
"@nestjs/typeorm": "^10.0.0",
"@telegraf/session": "^2.0.0-beta.6",
"better-sqlite3": "^8.7.0",
"kysely": "^0.23.5",
"nestjs-telegraf": "^2.7.0",
"pg": "^8.11.3",
"reflect-metadata": "^0.1.13",
Expand Down
7 changes: 6 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TelegramModule } from './services/telegram/telegram.module';
import { TelegramModule, UserModule } from './services';
import { AppUpdate } from './updates';
import { DatabaseModule } from './services';
import { UserUseCaseModule } from './use-cases/user';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TelegramModule,
DatabaseModule,
UserModule,
UserUseCaseModule,
],
controllers: [],
providers: [AppUpdate],
Expand Down
18 changes: 18 additions & 0 deletions src/core/abstracts/reply.abstract.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Telegram } from 'telegraf';
import { Context } from '../interfaces';
import ApiClient from 'telegraf/typings/core/network/client';

type Tail<T> = T extends [unknown, ...infer U] ? U : never;

type Shorthand<FName extends Exclude<keyof Telegram, keyof ApiClient>> = Tail<
Parameters<Telegram[FName]>
>;

abstract class IReplyService {
abstract sendMessage(
ctx: Context,
...args: Shorthand<'sendMessage'>
): Promise<void>;
}

export { IReplyService };
6 changes: 4 additions & 2 deletions src/core/abstracts/user.abstract.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { User } from '../entities';

abstract class IUserService {
abstract createUser(user: User): Promise<void>;
abstract create(user: User): Promise<User>;

abstract updateUser(user: User): Promise<void>;
abstract update(userId: number, user: User): Promise<User>;

abstract findByTgId(tgId: number): Promise<User>;
}

export { IUserService };
15 changes: 15 additions & 0 deletions src/core/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Markup } from 'telegraf';

const START_REPLY_MARKUP = Markup.keyboard([
[
Markup.button.callback('🇺🇦', 'lang_ua'),
Markup.button.callback('🇬🇧', 'lang_en'),
Markup.button.callback('🇷🇺', 'lang_ru'),
],
]).reply_markup;

START_REPLY_MARKUP.resize_keyboard = true;

const CLEAR_REPLY_MARKUP = Markup.removeKeyboard().reply_markup;

export { START_REPLY_MARKUP, CLEAR_REPLY_MARKUP };
4 changes: 2 additions & 2 deletions src/core/dtos/user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class CreateUserDto {
chatId: string;
userId: string;
chatId: number;
userId: number;
}

class UpdateUserDto implements Partial<CreateUserDto> {}
Expand Down
3 changes: 2 additions & 1 deletion src/core/entities/base.entity.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
BaseEntity,
CreateDateColumn,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';

abstract class IEntity {
abstract class IEntity extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;

Expand Down
4 changes: 2 additions & 2 deletions src/core/entities/user.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { Profile } from './profile.entity';
@Entity('users')
class User extends IEntity {
@Column()
userId: string;
userId: number;

@Column()
chatId: string;
chatId: number;

@OneToOne(() => Profile, (profile) => profile.user, {
nullable: true,
Expand Down
1 change: 1 addition & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './abstracts';
export * from './dtos';
export * from './entities';
export * from './interfaces';
10 changes: 10 additions & 0 deletions src/core/interfaces/context.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Context as TelegrafContext } from 'telegraf';
import { User } from '../entities';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Context extends TelegrafContext {
session: {
user?: User;
lang: 'ua' | 'en' | 'ru';
};
}
1 change: 1 addition & 0 deletions src/core/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './context.interface';
Empty file.
14 changes: 14 additions & 0 deletions src/frameworks/reply/telegraf/telegraf-reply.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { IReplyService } from 'src/core/abstracts/reply.abstract.service';
import { TelegrafReplyService } from './telegraf-reply.service';

@Module({
providers: [
{
provide: IReplyService,
useClass: TelegrafReplyService,
},
],
exports: [IReplyService],
})
export class TelegrafReplyModule {}
44 changes: 44 additions & 0 deletions src/frameworks/reply/telegraf/telegraf-reply.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Injectable } from '@nestjs/common';
import { Context } from 'src/core';
import { IReplyService } from 'src/core/abstracts/reply.abstract.service';
import {
ParseMode,
MessageEntity,
InlineKeyboardMarkup,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
ForceReply,
} from 'telegraf/typings/core/types/typegram';
import { FmtString } from 'telegraf/typings/format';

@Injectable()
class TelegrafReplyService implements IReplyService {
async sendMessage(
ctx: Context,
text: string | FmtString,
extra?: Omit<
{
chat_id: string | number;
message_thread_id?: number;
text: string;
parse_mode?: ParseMode;
entities?: MessageEntity[];
disable_web_page_preview?: boolean;
disable_notification?: boolean;
protect_content?: boolean;
reply_to_message_id?: number;
allow_sending_without_reply?: boolean;
reply_markup?:
| InlineKeyboardMarkup
| ReplyKeyboardMarkup
| ReplyKeyboardRemove
| ForceReply;
},
'chat_id' | 'text'
>,
): Promise<void> {
await ctx.reply(text, extra);
}
}

export { TelegrafReplyService };
1 change: 1 addition & 0 deletions src/frameworks/user/typeorm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './typeorm-user.module';
12 changes: 9 additions & 3 deletions src/frameworks/user/typeorm/typeorm-user.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { Module } from '@nestjs/common';
import { TypeOrmUserService } from './typeorm-user.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from 'src/core';
import { IUserService, User } from 'src/core';

@Module({
imports: [TypeOrmModule.forFeature([User])],
exports: [TypeOrmUserService],
providers: [TypeOrmUserService],
providers: [
TypeOrmUserService,
{
provide: IUserService,
useClass: TypeOrmUserService,
},
],
exports: [IUserService],
})
export class TypeOrmUserModule {}
22 changes: 18 additions & 4 deletions src/frameworks/user/typeorm/typeorm-user.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { IUserService, User } from 'src/core';
import { Repository } from 'typeorm';

@Injectable()
class TypeOrmUserService implements IUserService {
async createUser(user: User): Promise<void> {
throw new Error('Method not implemented.');
constructor(
@InjectRepository(User) private readonly userRepo: Repository<User>,
) {}

findByTgId(tgId: number): Promise<User> {
return this.userRepo.findOne({ where: { userId: tgId } });
}

async create(user: User): Promise<User> {
return this.userRepo.save(user);
}

async updateUser(user: User): Promise<void> {
throw new Error('Method not implemented.');
async update(userId: number, user: User): Promise<User> {
await this.userRepo.update(userId, user);

return this.userRepo.findOneBy({
id: user.id,
});
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/services/database/database.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
Expand All @@ -18,7 +18,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
};
},
inject: [ConfigModule],
inject: [ConfigService],
}),
],
})
Expand Down
3 changes: 3 additions & 0 deletions src/services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './database/database.module';
export * from './telegram/telegram.module';
export * from './user/user.module';
Loading

0 comments on commit b2e412e

Please sign in to comment.