Initial commit
This commit is contained in:
1
.env.example
Normal file
1
.env.example
Normal file
@@ -0,0 +1 @@
|
|||||||
|
BOT_TOKEN=YOUR_BOT_TOKEN_HERE
|
||||||
25
.eslintrc.js
Normal file
25
.eslintrc.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
module.exports = {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
parserOptions: {
|
||||||
|
project: 'tsconfig.json',
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||||
|
extends: [
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
jest: true,
|
||||||
|
},
|
||||||
|
ignorePatterns: ['.eslintrc.js'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
},
|
||||||
|
};
|
||||||
56
.gitignore
vendored
Normal file
56
.gitignore
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/node_modules
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
/coverage
|
||||||
|
/.nyc_output
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# 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
|
||||||
4
.prettierrc
Normal file
4
.prettierrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
CMD ["npm", "run", "start:prod"]
|
||||||
99
README.md
Normal file
99
README.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" 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" alt="Donate us"/></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" alt="Follow us on Twitter"></a>
|
||||||
|
</p>
|
||||||
|
<!--[](https://opencollective.com/nest#backer)
|
||||||
|
[](https://opencollective.com/nest#sponsor)-->
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compile and run the project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# development
|
||||||
|
$ npm run start
|
||||||
|
|
||||||
|
# watch mode
|
||||||
|
$ npm run start:dev
|
||||||
|
|
||||||
|
# production mode
|
||||||
|
$ npm run start:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# unit tests
|
||||||
|
$ npm run test
|
||||||
|
|
||||||
|
# e2e tests
|
||||||
|
$ npm run test:e2e
|
||||||
|
|
||||||
|
# test coverage
|
||||||
|
$ npm run test:cov
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information.
|
||||||
|
|
||||||
|
If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install -g mau
|
||||||
|
$ mau deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
Check out a few resources that may come in handy when working with NestJS:
|
||||||
|
|
||||||
|
- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
|
||||||
|
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
|
||||||
|
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
|
||||||
|
- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks.
|
||||||
|
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
|
||||||
|
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
|
||||||
|
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
|
||||||
|
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
|
||||||
|
|
||||||
|
## 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).
|
||||||
|
|
||||||
|
## Stay in touch
|
||||||
|
|
||||||
|
- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||||
|
- Website - [https://nestjs.com](https://nestjs.com/)
|
||||||
|
- Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
|
||||||
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
container_name: mental_health_bot
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./src/data:/app/dist/data
|
||||||
|
- ./src/quotes.json:/app/dist/quotes.json
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
11
nest-cli.json
Normal file
11
nest-cli.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/nest-cli",
|
||||||
|
"collection": "@nestjs/schematics",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"compilerOptions": {
|
||||||
|
"deleteOutDir": true,
|
||||||
|
"assets": [
|
||||||
|
"**/*.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
10168
package-lock.json
generated
Normal file
10168
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
74
package.json
Normal file
74
package.json
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"name": "mental_health",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"author": "",
|
||||||
|
"private": true,
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nest build",
|
||||||
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
|
"start": "nest start",
|
||||||
|
"start:dev": "nest start --watch",
|
||||||
|
"start:debug": "nest start --debug --watch",
|
||||||
|
"start:prod": "node dist/main",
|
||||||
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch",
|
||||||
|
"test:cov": "jest --coverage",
|
||||||
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nestjs/common": "^10.0.0",
|
||||||
|
"@nestjs/core": "^10.0.0",
|
||||||
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
|
"@nestjs/schedule": "^6.0.1",
|
||||||
|
"@prisma/client": "^6.19.0",
|
||||||
|
"nestjs-telegraf": "^2.9.1",
|
||||||
|
"reflect-metadata": "^0.2.0",
|
||||||
|
"rxjs": "^7.8.1",
|
||||||
|
"telegraf": "^4.16.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nestjs/cli": "^10.0.0",
|
||||||
|
"@nestjs/schematics": "^10.0.0",
|
||||||
|
"@nestjs/testing": "^10.0.0",
|
||||||
|
"@types/express": "^5.0.0",
|
||||||
|
"@types/jest": "^29.5.2",
|
||||||
|
"@types/node": "^20.3.1",
|
||||||
|
"@types/supertest": "^6.0.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
|
"eslint": "^8.0.0",
|
||||||
|
"eslint-config-prettier": "^9.0.0",
|
||||||
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
|
"jest": "^29.5.0",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"prisma": "^6.19.0",
|
||||||
|
"source-map-support": "^0.5.21",
|
||||||
|
"supertest": "^7.0.0",
|
||||||
|
"ts-jest": "^29.1.0",
|
||||||
|
"ts-loader": "^9.4.3",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"tsconfig-paths": "^4.2.0",
|
||||||
|
"typescript": "^5.1.3"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
|
"rootDir": "src",
|
||||||
|
"testRegex": ".*\\.spec\\.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
},
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"**/*.(t|j)s"
|
||||||
|
],
|
||||||
|
"coverageDirectory": "../coverage",
|
||||||
|
"testEnvironment": "node"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/app.controller.spec.ts
Normal file
22
src/app.controller.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { AppController } from './app.controller';
|
||||||
|
import { AppService } from './app.service';
|
||||||
|
|
||||||
|
describe('AppController', () => {
|
||||||
|
let appController: AppController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const app: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [AppController],
|
||||||
|
providers: [AppService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
appController = app.get<AppController>(AppController);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('root', () => {
|
||||||
|
it('should return "Hello World!"', () => {
|
||||||
|
expect(appController.getHello()).toBe('Hello World!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
12
src/app.controller.ts
Normal file
12
src/app.controller.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Controller, Get } from '@nestjs/common';
|
||||||
|
import { AppService } from './app.service';
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
export class AppController {
|
||||||
|
constructor(private readonly appService: AppService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
getHello(): string {
|
||||||
|
return this.appService.getHello();
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/app.module.ts
Normal file
21
src/app.module.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TelegrafModule } from 'nestjs-telegraf';
|
||||||
|
import { ScheduleModule } from '@nestjs/schedule';
|
||||||
|
import { UsersModule } from './users/users.module';
|
||||||
|
import { QuotesModule } from './quotes/quotes.module';
|
||||||
|
import { BotModule } from './bot/bot.module';
|
||||||
|
import { SchedulerModule } from './scheduler/scheduler.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
ScheduleModule.forRoot(),
|
||||||
|
TelegrafModule.forRoot({
|
||||||
|
token: process.env.BOT_TOKEN || 'YOUR_BOT_TOKEN_HERE',
|
||||||
|
}),
|
||||||
|
UsersModule,
|
||||||
|
QuotesModule,
|
||||||
|
BotModule,
|
||||||
|
SchedulerModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
8
src/app.service.ts
Normal file
8
src/app.service.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AppService {
|
||||||
|
getHello(): string {
|
||||||
|
return 'Hello World!';
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/bot/bot.module.ts
Normal file
9
src/bot/bot.module.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { BotService } from './bot.service';
|
||||||
|
import { UsersModule } from '../users/users.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [UsersModule],
|
||||||
|
providers: [BotService],
|
||||||
|
})
|
||||||
|
export class BotModule { }
|
||||||
26
src/bot/bot.service.ts
Normal file
26
src/bot/bot.service.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Update, Ctx, Start, Help, On, Message } from 'nestjs-telegraf';
|
||||||
|
import { Context } from 'telegraf';
|
||||||
|
import { UsersService } from '../users/users.service';
|
||||||
|
|
||||||
|
@Update()
|
||||||
|
export class BotService {
|
||||||
|
constructor(private readonly usersService: UsersService) { }
|
||||||
|
|
||||||
|
@Start()
|
||||||
|
async start(@Ctx() ctx: Context) {
|
||||||
|
const user = ctx.from;
|
||||||
|
if (user) {
|
||||||
|
this.usersService.create({
|
||||||
|
id: user.id,
|
||||||
|
fullName: `${user.first_name} ${user.last_name || ''}`.trim(),
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
await ctx.reply(`Welcome, ${user.first_name}! You have been registered for motivational quotes.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Help()
|
||||||
|
async help(@Ctx() ctx: Context) {
|
||||||
|
await ctx.reply('I will send you a motivational quote every 3 hours.');
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/data/users.json
Normal file
1
src/data/users.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
8
src/main.ts
Normal file
8
src/main.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await NestFactory.create(AppModule);
|
||||||
|
await app.listen(process.env.PORT ?? 3000);
|
||||||
|
}
|
||||||
|
bootstrap();
|
||||||
677
src/quotes.json
Normal file
677
src/quotes.json
Normal file
@@ -0,0 +1,677 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Единственный способ делать великие дела — любить то, что вы делаете.",
|
||||||
|
"author": "Стив Джобс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Верь, что ты можешь, и ты уже прошел половину пути.",
|
||||||
|
"author": "Теодор Рузвельт"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не важно, как медленно ты идешь, главное — не останавливаться.",
|
||||||
|
"author": "Конфуций"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твое время ограничено, не трать его, живя чужой жизнью.",
|
||||||
|
"author": "Стив Джобс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Лучший способ предсказать будущее — создать его.",
|
||||||
|
"author": "Питер Друкер"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Успех — это не финал, неудача — это не фатально: главное — это мужество продолжать.",
|
||||||
|
"author": "Уинстон Черчилль"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Трудности часто готовят обычных людей к необычной судьбе.",
|
||||||
|
"author": "К.С. Льюис"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Верь в себя и во все, что ты есть. Знайте, что внутри вас есть что-то большее, чем любое препятствие.",
|
||||||
|
"author": "Кристиан Д. Ларсон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не смотри на часы; делай то, что делают они. Продолжай идти.",
|
||||||
|
"author": "Сэм Левенсон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Никогда не поздно поставить новую цель или обрести новую мечту.",
|
||||||
|
"author": "К.С. Льюис"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты сильнее, чем ты думаешь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Все будет хорошо. Просто дыши."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты справляешься лучше, чем тебе кажется."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не забывай заботиться о себе."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твои чувства важны."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Это всего лишь плохой день, а не плохая жизнь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты заслуживаешь счастья и покоя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Маленькие шаги тоже ведут к цели."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Позволь себе отдохнуть."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты не одинок в своих переживаниях."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Счастье можно найти даже в самые темные времена, если не забывать обращаться к свету.",
|
||||||
|
"author": "Альбус Дамблдор"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Неудача — это просто возможность начать снова, но уже более мудро.",
|
||||||
|
"author": "Генри Форд"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Наша величайшая слава не в том, чтобы никогда не падать, а в том, чтобы подниматься каждый раз, когда мы падаем.",
|
||||||
|
"author": "Конфуций"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — автор своей жизни. Пиши так, как хочешь ты."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Даже самая темная ночь закончится и взойдет солнце.",
|
||||||
|
"author": "Виктор Гюго"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Сделай сегодня что-то, за что твое будущее «я» скажет тебе спасибо."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ошибки — это доказательство того, что ты пытаешься."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь собой, все остальные роли уже заняты.",
|
||||||
|
"author": "Оскар Уайльд"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Секрет того, чтобы добиться чего-то — начать.",
|
||||||
|
"author": "Марк Твен"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты важен. Твоя жизнь имеет значение."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не позволяй вчерашнему дню занимать слишком много сегодняшнего.",
|
||||||
|
"author": "Уилл Роджерс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жизнь — это то, что с тобой происходит, пока ты строишь другие планы.",
|
||||||
|
"author": "Джон Леннон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Через год ты пожалеешь, что не начал сегодня.",
|
||||||
|
"author": "Карен Лэмб"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся отказаться от хорошего, чтобы пойти за великим.",
|
||||||
|
"author": "Джон Д. Рокфеллер"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Я не потерпел неудачу. Я просто нашел 10 000 способов, которые не работают.",
|
||||||
|
"author": "Томас Эдисон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Если ты проходишь через ад, продолжай идти.",
|
||||||
|
"author": "Уинстон Черчилль"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Никто не может заставить вас почувствовать себя неполноценным без вашего согласия.",
|
||||||
|
"author": "Элеонора Рузвельт"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Лучшая месть — это огромный успех.",
|
||||||
|
"author": "Фрэнк Синатра"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты можешь все, если поверишь в это."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Помни, зачем ты начал."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Каждый день — это новый шанс."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь добр к себе."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твой потенциал безграничен."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Сфокусируйся на прогрессе, а не на совершенстве."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты делаешь мир лучше просто тем, что ты в нем есть."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не сравнивай свое начало с чьей-то серединой."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Вдох-выдох. Ты справишься."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Иногда нужно просто остановиться и посмотреть, как далеко ты уже зашел."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя улыбка может изменить чей-то день."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся просить о помощи. Это признак силы, а не слабости."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жизнь на 10% состоит из того, что с нами происходит, и на 90% из того, как мы на это реагируем.",
|
||||||
|
"author": "Чарльз Свиндолл"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ограничения живут только в нашей голове. Но если мы используем наше воображение, наши возможности становятся безграничными.",
|
||||||
|
"author": "Джейми Паолинетти"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Логика приведет вас из пункта А в пункт Б. Воображение приведет вас куда угодно.",
|
||||||
|
"author": "Альберт Эйнштейн"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не ждите. Время никогда не будет «самым подходящим».",
|
||||||
|
"author": "Наполеон Хилл"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Все, что вы можете представить — реально.",
|
||||||
|
"author": "Пабло Пикассо"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Стремитесь не к успеху, а к ценностям, которые он дает.",
|
||||||
|
"author": "Альберт Эйнштейн"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Два самых важных дня в твоей жизни: день, когда ты появился на свет, и день, когда понял зачем.",
|
||||||
|
"author": "Марк Твен"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Начинай там, где ты есть. Используй то, что у тебя есть. Делай то, что можешь.",
|
||||||
|
"author": "Артур Эш"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Падать — часть жизни, подниматься — ее суть."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — это не твои ошибки."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Сегодня — отличный день, чтобы начать."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя скорость не имеет значения, вперед — есть вперед."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Поверь в магию новых начал."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты достоин любви и уважения."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Слушай свое сердце."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — уникален, и это твоя суперсила."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не позволяй страху решать за тебя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Каждая проблема — это замаскированная возможность.",
|
||||||
|
"author": "Джон Адамс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Счастье — это не что-то готовое. Оно происходит от ваших собственных действий.",
|
||||||
|
"author": "Далай Лама"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Чтобы дойти до цели, надо прежде всего идти.",
|
||||||
|
"author": "Оноре де Бальзак"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Великие дела нужно совершать, а не обдумывать их бесконечно.",
|
||||||
|
"author": "Юлий Цезарь"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Победа над самим собой — единственная торжественная победа.",
|
||||||
|
"author": "Платон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Кто хочет — ищет возможности, кто не хочет — ищет причины.",
|
||||||
|
"author": "Сократ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жизнь прекрасна, когда ты создаешь ее сам.",
|
||||||
|
"author": "Софи Марсо"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойтесь расти медленно, бойтесь оставаться неизменными.",
|
||||||
|
"author": "Китайская пословица"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Лучшее время, чтобы посадить дерево, было 20 лет назад. Следующее лучшее время — сегодня.",
|
||||||
|
"author": "Китайская пословица"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты можешь изменить свой мир, изменив свои мысли."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя энергия — это твоя валюта. Трать ее мудро."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь причиной, по которой кто-то сегодня улыбнется."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не забывай хвалить себя за маленькие победы."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — достаточно хорош."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Мир нуждается в том, что можешь дать только ты."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Свет есть даже в самой темной комнате, если зажечь свечу."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя жизнь — это твое искусство."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не позволяй никому тушить твой свет."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты сильнее любой бури."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Вселенная любит тебя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Доверяй процессу."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты находишься именно там, где должен быть."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Отпусти то, что ты не можешь контролировать."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Каждый закат — это доказательство того, что финалы тоже могут быть красивыми."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — чудо."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Люби себя в первую очередь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты заслуживаешь всего самого лучшего."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не сдавайся. Чудеса случаются каждый день."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя история важна."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь смелым."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Мечтай по-крупному."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — вдохновение."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Делай то, что можешь, с тем, что имеешь, там, где ты есть.",
|
||||||
|
"author": "Теодор Рузвельт"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Гений — это 1% таланта и 99% труда.",
|
||||||
|
"author": "Томас Эдисон"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Неудача — это приправа, которая придает успеху его вкус.",
|
||||||
|
"author": "Трумен Капоте"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Если вы думаете, что вы способны на что-то, вы правы; если вы думаете, что у вас ничего не получится, вы тоже правы.",
|
||||||
|
"author": "Генри Форд"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Лучший способ взяться за что-то — перестать говорить и начать делать.",
|
||||||
|
"author": "Уолт Дисней"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Пессимист видит трудность в каждой возможности; оптимист видит возможность в каждой трудности.",
|
||||||
|
"author": "Уинстон Черчилль"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не позволяйте шуму чужих мнений заглушить ваш внутренний голос.",
|
||||||
|
"author": "Стив Джобс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "То, что нас не убивает, делает нас сильнее.",
|
||||||
|
"author": "Фридрих Ницше"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будьте переменой, которую вы хотите видеть в мире.",
|
||||||
|
"author": "Махатма Ганди"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Счастье не зависит от того, кто вы есть или что у вас есть; оно зависит исключительно от того, что вы думаете.",
|
||||||
|
"author": "Дейл Карнеги"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Единственный человек, которым вы должны стараться быть, — это тот, кем вы были вчера.",
|
||||||
|
"author": "Зигмунд Фрейд"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жизнь — это 10% того, что с нами происходит, и 90% того, как мы на это реагируем.",
|
||||||
|
"author": "Чарльз Свиндолл"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ваше время ограничено, не тратьте его, живя чужой жизнью.",
|
||||||
|
"author": "Стив Джобс"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Сложнее всего начать действовать, все остальное зависит только от упорства.",
|
||||||
|
"author": "Амелия Эрхарт"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жизнь — это либо дерзкое приключение, либо ничего.",
|
||||||
|
"author": "Хелен Келлер"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Вы никогда не пересечете океан, если не наберетесь смелости потерять из виду берег.",
|
||||||
|
"author": "Христофор Колумб"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Два самых важных дня в твоей жизни: день, когда ты родился, и день, когда понял, зачем.",
|
||||||
|
"author": "Марк Твен"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Человек, который никогда не совершал ошибок, никогда не пробовал ничего нового.",
|
||||||
|
"author": "Альберт Эйнштейн"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Образование — это самое мощное оружие, которое вы можете использовать, чтобы изменить мир.",
|
||||||
|
"author": "Нельсон Мандела"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Секрет успеха — это знать то, что никто другой не знает.",
|
||||||
|
"author": "Аристотель Онассис"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойтесь совершенства. Вам его никогда не достичь.",
|
||||||
|
"author": "Сальвадор Дали"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Успех — это способность идти от неудачи к неудаче, не теряя энтузиазма.",
|
||||||
|
"author": "Уинстон Черчилль"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Мечты не работают, пока не работаешь ты."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты способен на большее, чем можешь себе представить."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Каждый шаг вперед приближает тебя к цели."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не останавливайся, пока не будешь гордиться собой."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя настойчивость окупится."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Верь в свою интуицию."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — кузнец своего счастья."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся быть новичком."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Все великое начинается с малого."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя жизнь — это твой холст."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Рискуй, или упустишь шанс."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Слушай себя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — свет."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не позволяй никому говорить, что ты не можешь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя сила внутри тебя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь благодарен за каждый день."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ищи радость в мелочах."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — подарок этому миру."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся перемен."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Все происходит вовремя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — хозяин своей судьбы."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не оглядывайся назад, ты идешь не туда."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твоя улыбка — твое оружие."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь добрым, это всегда модно."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — вдохновение для других."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся мечтать."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твои мечты важны."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — уникален."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Люби жизнь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Живи моментом."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — достаточно сильный."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не сдавайся перед трудностями."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — победитель."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Верь в чудеса."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — любовь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Свети ярко."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — надежда."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь собой."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — радость."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся быть счастливым."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — мир."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Все будет хорошо."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — гармония."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Люби себя."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — красота."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Не бойся жить."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — свобода."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — мудрость."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — сила."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — добро."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — свет."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — любовь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — жизнь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — вселенная."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — бесконечность."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — вечность."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — сейчас."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — здесь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ты — есть."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Просто будь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Дыши."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Живи."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Люби."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Твори."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Мечтай."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Верь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Надейся."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Жди."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Иди."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Беги."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Лети."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Сияй."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Гори."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Свети."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Звучи."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Пой."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Танцуй."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Смейся."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Радуйся."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Улыбайся."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Плачь."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Чувствуй."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Будь."
|
||||||
|
}
|
||||||
|
]
|
||||||
8
src/quotes/quotes.module.ts
Normal file
8
src/quotes/quotes.module.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { QuotesService } from './quotes.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [QuotesService],
|
||||||
|
exports: [QuotesService],
|
||||||
|
})
|
||||||
|
export class QuotesModule { }
|
||||||
30
src/quotes/quotes.service.ts
Normal file
30
src/quotes/quotes.service.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export interface Quote {
|
||||||
|
text: string;
|
||||||
|
author?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class QuotesService {
|
||||||
|
private readonly filePath = path.resolve(__dirname, '..', 'quotes.json');
|
||||||
|
|
||||||
|
private readQuotes(): Quote[] {
|
||||||
|
if (!fs.existsSync(this.filePath)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const data = fs.readFileSync(this.filePath, 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRandomQuote(): Quote {
|
||||||
|
const quotes = this.readQuotes();
|
||||||
|
if (quotes.length === 0) {
|
||||||
|
return { text: 'No quotes available.', author: 'System' };
|
||||||
|
}
|
||||||
|
const randomIndex = Math.floor(Math.random() * quotes.length);
|
||||||
|
return quotes[randomIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/scheduler/scheduler.module.ts
Normal file
10
src/scheduler/scheduler.module.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { SchedulerService } from './scheduler.service';
|
||||||
|
import { UsersModule } from '../users/users.module';
|
||||||
|
import { QuotesModule } from '../quotes/quotes.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [UsersModule, QuotesModule],
|
||||||
|
providers: [SchedulerService],
|
||||||
|
})
|
||||||
|
export class SchedulerModule { }
|
||||||
53
src/scheduler/scheduler.service.ts
Normal file
53
src/scheduler/scheduler.service.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { Cron, CronExpression } from '@nestjs/schedule';
|
||||||
|
import { InjectBot } from 'nestjs-telegraf';
|
||||||
|
import { Context, Telegraf } from 'telegraf';
|
||||||
|
import { UsersService } from '../users/users.service';
|
||||||
|
import { QuotesService } from '../quotes/quotes.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SchedulerService {
|
||||||
|
private readonly logger = new Logger(SchedulerService.name);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly usersService: UsersService,
|
||||||
|
private readonly quotesService: QuotesService,
|
||||||
|
@InjectBot() private readonly bot: Telegraf<Context>,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
// Run every 3 hours
|
||||||
|
@Cron('0 */3 * * *')
|
||||||
|
handleCron() {
|
||||||
|
this.logger.debug('Cron job triggered. Scheduling random quote...');
|
||||||
|
|
||||||
|
// Random delay between 0 and 3 hours (in milliseconds)
|
||||||
|
// 3 hours = 3 * 60 * 60 * 1000 = 10800000 ms
|
||||||
|
// We'll use slightly less than 3 hours to avoid overlap, e.g., 2.5 hours
|
||||||
|
const maxDelay = 2.5 * 60 * 60 * 1000;
|
||||||
|
const delay = Math.floor(Math.random() * maxDelay);
|
||||||
|
|
||||||
|
this.logger.debug(`Quote scheduled in ${delay / 1000 / 60} minutes.`);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.sendQuoteToAllUsers();
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async sendQuoteToAllUsers() {
|
||||||
|
this.logger.debug('Sending quotes to all users...');
|
||||||
|
const users = this.usersService.findAll();
|
||||||
|
const quote = this.quotesService.getRandomQuote();
|
||||||
|
let message = `"${quote.text}"`;
|
||||||
|
if (quote.author) {
|
||||||
|
message += `\n\n- ${quote.author}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const user of users) {
|
||||||
|
try {
|
||||||
|
await this.bot.telegram.sendMessage(user.id, message);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Failed to send quote to user ${user.id}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/users/users.module.ts
Normal file
8
src/users/users.module.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { UsersService } from './users.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [UsersService],
|
||||||
|
exports: [UsersService],
|
||||||
|
})
|
||||||
|
export class UsersModule { }
|
||||||
39
src/users/users.service.ts
Normal file
39
src/users/users.service.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: number;
|
||||||
|
fullName: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UsersService {
|
||||||
|
private readonly filePath = path.resolve(__dirname, '..', 'data', 'users.json');
|
||||||
|
|
||||||
|
private readUsers(): User[] {
|
||||||
|
if (!fs.existsSync(this.filePath)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const data = fs.readFileSync(this.filePath, 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private writeUsers(users: User[]): void {
|
||||||
|
fs.writeFileSync(this.filePath, JSON.stringify(users, null, 2), 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
findAll(): User[] {
|
||||||
|
return this.readUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
create(user: User): void {
|
||||||
|
const users = this.readUsers();
|
||||||
|
const existingUser = users.find((u) => u.id === user.id);
|
||||||
|
if (!existingUser) {
|
||||||
|
users.push(user);
|
||||||
|
this.writeUsers(users);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
test/app.e2e-spec.ts
Normal file
24
test/app.e2e-spec.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { INestApplication } from '@nestjs/common';
|
||||||
|
import * as request from 'supertest';
|
||||||
|
import { AppModule } from './../src/app.module';
|
||||||
|
|
||||||
|
describe('AppController (e2e)', () => {
|
||||||
|
let app: INestApplication;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||||
|
imports: [AppModule],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
app = moduleFixture.createNestApplication();
|
||||||
|
await app.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('/ (GET)', () => {
|
||||||
|
return request(app.getHttpServer())
|
||||||
|
.get('/')
|
||||||
|
.expect(200)
|
||||||
|
.expect('Hello World!');
|
||||||
|
});
|
||||||
|
});
|
||||||
9
test/jest-e2e.json
Normal file
9
test/jest-e2e.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"moduleFileExtensions": ["js", "json", "ts"],
|
||||||
|
"rootDir": ".",
|
||||||
|
"testEnvironment": "node",
|
||||||
|
"testRegex": ".e2e-spec.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
tsconfig.build.json
Normal file
4
tsconfig.build.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||||
|
}
|
||||||
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"target": "ES2021",
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"incremental": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"strictBindCallApply": false,
|
||||||
|
"forceConsistentCasingInFileNames": false,
|
||||||
|
"noFallthroughCasesInSwitch": false
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user