mirror of
https://github.com/Maks1mS/nestjs-telegraf.git
synced 2024-12-23 22:52:59 +03:00
initial commit
This commit is contained in:
parent
1bb274e8e2
commit
2d23eba148
26
.eslintrc.js
26
.eslintrc.js
@ -1,26 +0,0 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
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/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
},
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { SceneOptions } from 'telegraf/typings/scenes/base';
|
||||
import { SceneMetadata } from '../../interfaces';
|
||||
import { SCENE_METADATA } from '../../telegraf.constants';
|
||||
|
||||
export const Scene = (
|
||||
sceneId: string,
|
||||
options?: SceneOptions<any>,
|
||||
): ClassDecorator =>
|
||||
SetMetadata<string, SceneMetadata>(SCENE_METADATA, {
|
||||
sceneId,
|
||||
type: 'base',
|
||||
options,
|
||||
});
|
@ -1,14 +0,0 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { SceneOptions } from 'telegraf/typings/scenes/base';
|
||||
import { SceneMetadata } from '../../interfaces';
|
||||
import { SCENE_METADATA } from '../../telegraf.constants';
|
||||
|
||||
export const Wizard = (
|
||||
sceneId: string,
|
||||
options?: SceneOptions<any>,
|
||||
): ClassDecorator =>
|
||||
SetMetadata<string, SceneMetadata>(SCENE_METADATA, {
|
||||
sceneId,
|
||||
type: 'wizard',
|
||||
options,
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling callback_data actions with regular expressions.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=action
|
||||
*/
|
||||
export const Action = createListenerDecorator('action');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Cashtag handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=cashtag
|
||||
*/
|
||||
export const Cashtag = createListenerDecorator('cashtag');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with email entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-email
|
||||
*/
|
||||
export const Email = createListenerDecorator('email');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Hashtag handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=hashtag
|
||||
*/
|
||||
export const Hashtag = createListenerDecorator('hashtag');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Handler for /help command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=help
|
||||
*/
|
||||
export const Help = createListenerDecorator('help');
|
@ -1,18 +0,0 @@
|
||||
export * from './on.decorator';
|
||||
export * from './use.decorator';
|
||||
export * from './action.decorator';
|
||||
export * from './cashtag.decorator';
|
||||
export * from './command.decorator';
|
||||
export * from './game-query.decorator';
|
||||
export * from './hashtag.decorator';
|
||||
export * from './hears.decorator';
|
||||
export * from './help.decorator';
|
||||
export * from './inline-query.decorator';
|
||||
export * from './mention.decorator';
|
||||
export * from './phone.decorator';
|
||||
export * from './settings.decorator';
|
||||
export * from './start.decorator';
|
||||
export * from './email.decorator';
|
||||
export * from './url.decorator';
|
||||
export * from './text-link.decorator';
|
||||
export * from './text-mention.decorator';
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Mention handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=mention
|
||||
*/
|
||||
export const Mention = createListenerDecorator('mention');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Phone number handling.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=phone
|
||||
*/
|
||||
export const Phone = createListenerDecorator('phone');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Handler for /settings command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=settings
|
||||
*/
|
||||
export const Settings = createListenerDecorator('settings');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Handler for /start command.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=start
|
||||
*/
|
||||
export const Start = createListenerDecorator('start');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with text_link entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-textlink
|
||||
*/
|
||||
export const TextLink = createListenerDecorator('textLink');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with text_mention entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-textlink
|
||||
*/
|
||||
export const TextMention = createListenerDecorator('textMention');
|
@ -1,8 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
|
||||
/**
|
||||
* Registers middleware for handling messages with url entity.
|
||||
*
|
||||
* @see https://telegraf.js.org/#/?id=telegraf-url
|
||||
*/
|
||||
export const Url = createListenerDecorator('url');
|
@ -1,3 +0,0 @@
|
||||
export * from './scene-enter.decorator';
|
||||
export * from './scene-leave.decorator';
|
||||
export * from './wizard-step.decorator';
|
@ -1,5 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
import { Scenes } from 'telegraf';
|
||||
|
||||
export const SceneEnter =
|
||||
createListenerDecorator<Scenes.BaseScene<never>>('enter');
|
@ -1,5 +0,0 @@
|
||||
import { createListenerDecorator } from '../../utils';
|
||||
import { Scenes } from 'telegraf';
|
||||
|
||||
export const SceneLeave =
|
||||
createListenerDecorator<Scenes.BaseScene<never>>('leave');
|
@ -1,6 +0,0 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
import { WizardStepMetadata } from '../../interfaces';
|
||||
import { WIZARD_STEP_METADATA } from '../../telegraf.constants';
|
||||
|
||||
export const WizardStep = (step: number) =>
|
||||
SetMetadata<string, WizardStepMetadata>(WIZARD_STEP_METADATA, { step });
|
@ -1,11 +0,0 @@
|
||||
import { SceneOptions } from 'telegraf/typings/scenes/base';
|
||||
|
||||
export interface SceneMetadata {
|
||||
sceneId: string;
|
||||
type: 'base' | 'wizard';
|
||||
options?: SceneOptions<any>;
|
||||
}
|
||||
|
||||
export interface WizardStepMetadata {
|
||||
step: number;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import {
|
||||
SCENE_METADATA,
|
||||
LISTENERS_METADATA,
|
||||
UPDATE_METADATA,
|
||||
WIZARD_STEP_METADATA,
|
||||
} from '../telegraf.constants';
|
||||
import {
|
||||
ListenerMetadata,
|
||||
SceneMetadata,
|
||||
WizardStepMetadata,
|
||||
} from '../interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class MetadataAccessorService {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
|
||||
isUpdate(target: Function): boolean {
|
||||
if (!target) return false;
|
||||
return !!this.reflector.get(UPDATE_METADATA, target);
|
||||
}
|
||||
|
||||
isScene(target: Function): boolean {
|
||||
if (!target) return false;
|
||||
return !!this.reflector.get(SCENE_METADATA, target);
|
||||
}
|
||||
|
||||
getListenerMetadata(target: Function): ListenerMetadata[] | undefined {
|
||||
return this.reflector.get(LISTENERS_METADATA, target);
|
||||
}
|
||||
|
||||
getSceneMetadata(target: Function): SceneMetadata | undefined {
|
||||
return this.reflector.get(SCENE_METADATA, target);
|
||||
}
|
||||
|
||||
getWizardStepMetadata(target: Function): WizardStepMetadata | undefined {
|
||||
return this.reflector.get(WIZARD_STEP_METADATA, target);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Provider } from '@nestjs/common';
|
||||
import { Scenes } from 'telegraf';
|
||||
import { TELEGRAF_STAGE } from './telegraf.constants';
|
||||
|
||||
export const telegrafStageProvider: Provider = {
|
||||
provide: TELEGRAF_STAGE,
|
||||
useClass: Scenes.Stage,
|
||||
};
|
@ -1,16 +0,0 @@
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { TelegrafModuleOptions } from '../interfaces';
|
||||
|
||||
export async function createBotFactory(
|
||||
options: TelegrafModuleOptions,
|
||||
): Promise<Telegraf<any>> {
|
||||
const bot = new Telegraf<any>(options.token, options.options);
|
||||
|
||||
bot.use(...(options.middlewares ?? []));
|
||||
|
||||
if (options.launchOptions !== false) {
|
||||
await bot.launch(options.launchOptions);
|
||||
}
|
||||
|
||||
return bot;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
ECHO_BOT_TOKEN=
|
||||
GREETER_BOT_TOKEN=
|
@ -1,24 +0,0 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
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',
|
||||
},
|
||||
};
|
398
sample/01-complete-app/.gitignore
vendored
398
sample/01-complete-app/.gitignore
vendored
@ -1,398 +0,0 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
### VisualStudio template
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
coverage/
|
||||
|
||||
### macOS template
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
=======
|
||||
# Local
|
||||
.env
|
||||
dist
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"json"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
"testRegex": "/src/.*\\.(test|spec).(ts|tsx|js)$",
|
||||
"collectCoverageFrom" : ["src/**/*.{js,jsx,tsx,ts}", "!**/node_modules/**", "!**/vendor/**"],
|
||||
"coverageReporters": ["json", "lcov"]
|
||||
}
|
15862
sample/01-complete-app/package-lock.json
generated
15862
sample/01-complete-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
{
|
||||
"name": "nest-typescript-starter",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "Nest TypeScript starter repository",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"prebuild": "rimraf dist",
|
||||
"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": "8.0.9",
|
||||
"@nestjs/core": "8.0.9",
|
||||
"@nestjs/platform-express": "8.0.9",
|
||||
"dotenv": "10.0.0",
|
||||
"nestjs-telegraf": "2.4.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rimraf": "3.0.2",
|
||||
"telegraf": "4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "8.2.8",
|
||||
"@nestjs/schematics": "8.0.5",
|
||||
"@nestjs/testing": "8.0.9",
|
||||
"@types/express": "4.17.13",
|
||||
"@types/jest": "27.4.0",
|
||||
"@types/node": "16.11.22",
|
||||
"@types/supertest": "2.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "5.11.0",
|
||||
"@typescript-eslint/parser": "5.11.0",
|
||||
"eslint": "8.8.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-prettier": "4.0.0",
|
||||
"jest": "27.5.1",
|
||||
"prettier": "2.5.1",
|
||||
"supertest": "6.2.2",
|
||||
"ts-jest": "27.1.3",
|
||||
"ts-loader": "9.2.6",
|
||||
"ts-node": "10.5.0",
|
||||
"tsconfig-paths": "3.12.0",
|
||||
"typescript": "4.4.4"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"json",
|
||||
"ts"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"testRegex": ".*\\.spec\\.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"collectCoverageFrom": [
|
||||
"**/*.(t|j)s"
|
||||
],
|
||||
"coverageDirectory": "../coverage",
|
||||
"testEnvironment": "node"
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export const HELLO_SCENE_ID = 'HELLO_SCENE_ID';
|
||||
|
||||
export const GreeterBotName = 'greeter';
|
@ -1,26 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TelegrafModule } from 'nestjs-telegraf';
|
||||
import { EchoModule } from './echo/echo.module';
|
||||
import { GreeterModule } from './greeter/greeter.module';
|
||||
import { sessionMiddleware } from './middleware/session.middleware';
|
||||
import { GreeterBotName } from './app.constants';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TelegrafModule.forRoot({
|
||||
token: process.env.ECHO_BOT_TOKEN,
|
||||
include: [EchoModule],
|
||||
}),
|
||||
TelegrafModule.forRootAsync({
|
||||
botName: GreeterBotName,
|
||||
useFactory: () => ({
|
||||
token: process.env.GREETER_BOT_TOKEN,
|
||||
middlewares: [sessionMiddleware],
|
||||
include: [GreeterModule],
|
||||
}),
|
||||
}),
|
||||
EchoModule,
|
||||
GreeterModule,
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
@ -1,7 +0,0 @@
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
import { TelegrafExecutionContext } from 'nestjs-telegraf';
|
||||
|
||||
export const UpdateType = createParamDecorator(
|
||||
(_, ctx: ExecutionContext) =>
|
||||
TelegrafExecutionContext.create(ctx).getContext().updateType,
|
||||
);
|
@ -1,13 +0,0 @@
|
||||
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';
|
||||
import { TelegrafArgumentsHost } from 'nestjs-telegraf';
|
||||
import { Context } from '../../interfaces/context.interface';
|
||||
|
||||
@Catch()
|
||||
export class TelegrafExceptionFilter implements ExceptionFilter {
|
||||
async catch(exception: Error, host: ArgumentsHost): Promise<void> {
|
||||
const telegrafHost = TelegrafArgumentsHost.create(host);
|
||||
const ctx = telegrafHost.getContext<Context>();
|
||||
|
||||
await ctx.replyWithHTML(`<b>Error</b>: ${exception.message}`);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
||||
import { TelegrafExecutionContext, TelegrafException } from 'nestjs-telegraf';
|
||||
import { Context } from '../../interfaces/context.interface';
|
||||
|
||||
@Injectable()
|
||||
export class AdminGuard implements CanActivate {
|
||||
private readonly ADMIN_IDS = [];
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const ctx = TelegrafExecutionContext.create(context);
|
||||
const { from } = ctx.getContext<Context>();
|
||||
|
||||
const isAdmin = this.ADMIN_IDS.includes(from.id);
|
||||
if (!isAdmin) {
|
||||
throw new TelegrafException('You are not admin 😡');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import {
|
||||
CallHandler,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
NestInterceptor,
|
||||
} from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class ResponseTimeInterceptor implements NestInterceptor {
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||
console.log('Before...');
|
||||
|
||||
const start = Date.now();
|
||||
return next
|
||||
.handle()
|
||||
.pipe(tap(() => console.log(`Response time: ${Date.now() - start}ms`)));
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Injectable, PipeTransform } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class ReverseTextPipe implements PipeTransform {
|
||||
transform(value: string): string {
|
||||
return value.split('').reverse().join('');
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { EchoUpdate } from './echo.update';
|
||||
import { EchoService } from './echo.service';
|
||||
import { RandomNumberScene } from '../greeter/scenes/random-number.scene';
|
||||
|
||||
@Module({
|
||||
providers: [EchoUpdate, EchoService, RandomNumberScene],
|
||||
})
|
||||
export class EchoModule {}
|
@ -1,8 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class EchoService {
|
||||
echo(text: string): string {
|
||||
return `Echo: ${text}`;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { UseFilters, UseGuards, UseInterceptors } from '@nestjs/common';
|
||||
import {
|
||||
Help,
|
||||
InjectBot,
|
||||
On,
|
||||
Message,
|
||||
Start,
|
||||
Update,
|
||||
Command,
|
||||
} from 'nestjs-telegraf';
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { EchoService } from './echo.service';
|
||||
import { GreeterBotName } from '../app.constants';
|
||||
import { Context } from '../interfaces/context.interface';
|
||||
import { ReverseTextPipe } from '../common/pipes/reverse-text.pipe';
|
||||
import { ResponseTimeInterceptor } from '../common/interceptors/response-time.interceptor';
|
||||
import { AdminGuard } from '../common/guards/admin.guard';
|
||||
import { TelegrafExceptionFilter } from '../common/filters/telegraf-exception.filter';
|
||||
|
||||
@Update()
|
||||
@UseInterceptors(ResponseTimeInterceptor)
|
||||
@UseFilters(TelegrafExceptionFilter)
|
||||
export class EchoUpdate {
|
||||
constructor(
|
||||
@InjectBot(GreeterBotName)
|
||||
private readonly bot: Telegraf<Context>,
|
||||
private readonly echoService: EchoService,
|
||||
) {}
|
||||
|
||||
@Start()
|
||||
async onStart(): Promise<string> {
|
||||
const me = await this.bot.telegram.getMe();
|
||||
return `Hey, I'm ${me.first_name}`;
|
||||
}
|
||||
|
||||
@Help()
|
||||
async onHelp(): Promise<string> {
|
||||
return 'Send me any text';
|
||||
}
|
||||
|
||||
@Command('admin')
|
||||
@UseGuards(AdminGuard)
|
||||
onAdminCommand(): string {
|
||||
return 'Welcome judge';
|
||||
}
|
||||
|
||||
@On('text')
|
||||
onMessage(
|
||||
@Message('text', new ReverseTextPipe()) reversedText: string,
|
||||
): string {
|
||||
return this.echoService.echo(reversedText);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { GreeterUpdate } from './greeter.update';
|
||||
import { RandomNumberScene } from './scenes/random-number.scene';
|
||||
|
||||
@Module({
|
||||
providers: [GreeterUpdate, RandomNumberScene],
|
||||
})
|
||||
export class GreeterModule {}
|
@ -1,26 +0,0 @@
|
||||
import { Command, Ctx, Hears, Start, Update, Sender } from 'nestjs-telegraf';
|
||||
import { UpdateType as TelegrafUpdateType } from 'telegraf/typings/telegram-types';
|
||||
import { Context } from '../interfaces/context.interface';
|
||||
import { HELLO_SCENE_ID } from '../app.constants';
|
||||
import { UpdateType } from '../common/decorators/update-type.decorator';
|
||||
|
||||
@Update()
|
||||
export class GreeterUpdate {
|
||||
@Start()
|
||||
onStart(): string {
|
||||
return 'Say hello to me';
|
||||
}
|
||||
|
||||
@Hears(['hi', 'hello', 'hey', 'qq'])
|
||||
onGreetings(
|
||||
@UpdateType() updateType: TelegrafUpdateType,
|
||||
@Sender('first_name') firstName: string,
|
||||
): string {
|
||||
return `Hey ${firstName}`;
|
||||
}
|
||||
|
||||
@Command('scene')
|
||||
async onSceneCommand(@Ctx() ctx: Context): Promise<void> {
|
||||
await ctx.scene.enter(HELLO_SCENE_ID);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import { Scene, SceneEnter, SceneLeave, Command } from 'nestjs-telegraf';
|
||||
import { HELLO_SCENE_ID } from '../../app.constants';
|
||||
import { Context } from '../../interfaces/context.interface';
|
||||
|
||||
@Scene(HELLO_SCENE_ID)
|
||||
export class RandomNumberScene {
|
||||
@SceneEnter()
|
||||
onSceneEnter(): string {
|
||||
console.log('Enter to scene');
|
||||
return 'Welcome on scene ✋';
|
||||
}
|
||||
|
||||
@SceneLeave()
|
||||
onSceneLeave(): string {
|
||||
console.log('Leave from scene');
|
||||
return 'Bye Bye 👋';
|
||||
}
|
||||
|
||||
@Command(['rng', 'random'])
|
||||
onRandomCommand(): number {
|
||||
console.log('Use "random" command');
|
||||
return Math.floor(Math.random() * 11);
|
||||
}
|
||||
|
||||
@Command('leave')
|
||||
async onLeaveCommand(ctx: Context): Promise<void> {
|
||||
await ctx.scene.leave();
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
import { Scenes } from 'telegraf';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface Context extends Scenes.SceneContext {}
|
@ -1,8 +0,0 @@
|
||||
import 'dotenv/config';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
await NestFactory.createApplicationContext(AppModule);
|
||||
}
|
||||
bootstrap();
|
@ -1,3 +0,0 @@
|
||||
import { session } from 'telegraf';
|
||||
|
||||
export const sessionMiddleware = session();
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es2017",
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": "./src",
|
||||
"incremental": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
export * from './update.decorator';
|
||||
export * from './scene.decorator';
|
||||
export * from './wizard.decorator';
|
||||
export * from './inject-bot.decorator';
|
||||
export * from './inject-all-bots.decorator';
|
@ -1,9 +1,9 @@
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { Bot } from 'grammy';
|
||||
|
||||
import { getAllBotsToken } from '../../utils/get-all-bots-token.util';
|
||||
|
||||
export type AllBotsMap = Map<string, Telegraf<any>>;
|
||||
export type AllBotsMap = Map<string, Bot<any>>;
|
||||
|
||||
export const InjectAllBots = (): ParameterDecorator =>
|
||||
Inject(getAllBotsToken());
|
@ -1,4 +1,3 @@
|
||||
export * from './core';
|
||||
export * from './listeners';
|
||||
export * from './scene';
|
||||
export * from './params';
|
6
src/decorators/listeners/index.ts
Normal file
6
src/decorators/listeners/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './on.decorator';
|
||||
export * from './use.decorator';
|
||||
export * from './command.decorator';
|
||||
export * from './game-query.decorator';
|
||||
export * from './hears.decorator';
|
||||
export * from './inline-query.decorator';
|
@ -1,6 +1,6 @@
|
||||
import { ParamData } from '@nestjs/common';
|
||||
import { ParamsFactory } from '@nestjs/core/helpers/external-context-creator';
|
||||
import { Context } from 'telegraf';
|
||||
import { Context } from 'grammy';
|
||||
import { TelegrafParamtype } from '../enums/telegraf-paramtype.enum';
|
||||
|
||||
export class TelegrafParamsFactory implements ParamsFactory {
|
@ -1,4 +1,3 @@
|
||||
export * from './telegraf-options.interface';
|
||||
export * from './listener-metadata.interface';
|
||||
export * from './scene-metadata.interface';
|
||||
export * from './telegraf-exception-filter.interface';
|
@ -1,11 +1,11 @@
|
||||
import { ModuleMetadata, Type } from '@nestjs/common/interfaces';
|
||||
import { Middleware, Telegraf } from 'telegraf';
|
||||
import { Middleware, PollingOptions, BotConfig } from 'grammy';
|
||||
|
||||
export interface TelegrafModuleOptions {
|
||||
token: string;
|
||||
config?: BotConfig<any>;
|
||||
pollingOptions?: PollingOptions | false;
|
||||
botName?: string;
|
||||
options?: Partial<Telegraf.Options<any>>;
|
||||
launchOptions?: Telegraf.LaunchOptions | false;
|
||||
include?: Function[];
|
||||
middlewares?: ReadonlyArray<Middleware<any>>;
|
||||
}
|
@ -5,7 +5,7 @@ import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import { Module } from '@nestjs/core/injector/module';
|
||||
import { ParamMetadata } from '@nestjs/core/helpers/interfaces';
|
||||
import { ExternalContextCreator } from '@nestjs/core/helpers/external-context-creator';
|
||||
import { Composer, Context, Scenes, Telegraf } from 'telegraf';
|
||||
import { Composer, Context, Bot } from 'grammy';
|
||||
|
||||
import { MetadataAccessorService } from './metadata-accessor.service';
|
||||
import {
|
||||
@ -25,11 +25,9 @@ export class ListenersExplorerService
|
||||
implements OnModuleInit
|
||||
{
|
||||
private readonly telegrafParamsFactory = new TelegrafParamsFactory();
|
||||
private bot: Telegraf<any>;
|
||||
private bot: Bot;
|
||||
|
||||
constructor(
|
||||
@Inject(TELEGRAF_STAGE)
|
||||
private readonly stage: Scenes.Stage<any>,
|
||||
@Inject(TELEGRAF_MODULE_OPTIONS)
|
||||
private readonly telegrafOptions: TelegrafModuleOptions,
|
||||
@Inject(TELEGRAF_BOT_NAME)
|
||||
@ -45,10 +43,9 @@ export class ListenersExplorerService
|
||||
}
|
||||
|
||||
onModuleInit(): void {
|
||||
this.bot = this.moduleRef.get<Telegraf<any>>(this.botName, {
|
||||
this.bot = this.moduleRef.get<Bot>(this.botName, {
|
||||
strict: false,
|
||||
});
|
||||
this.bot.use(this.stage.middleware());
|
||||
|
||||
this.explore();
|
||||
}
|
||||
@ -60,7 +57,6 @@ export class ListenersExplorerService
|
||||
);
|
||||
|
||||
this.registerUpdates(modules);
|
||||
this.registerScenes(modules);
|
||||
}
|
||||
|
||||
private registerUpdates(modules: Module[]): void {
|
||||
@ -70,28 +66,6 @@ export class ListenersExplorerService
|
||||
updates.forEach((wrapper) => this.registerListeners(this.bot, wrapper));
|
||||
}
|
||||
|
||||
private registerScenes(modules: Module[]): void {
|
||||
const scenes = this.flatMap<InstanceWrapper>(modules, (wrapper) =>
|
||||
this.filterScenes(wrapper),
|
||||
);
|
||||
scenes.forEach((wrapper) => {
|
||||
const { sceneId, type, options } = this.metadataAccessor.getSceneMetadata(
|
||||
wrapper.instance.constructor,
|
||||
);
|
||||
const scene =
|
||||
type === 'base'
|
||||
? new Scenes.BaseScene<any>(sceneId, options || ({} as any))
|
||||
: new Scenes.WizardScene<any>(sceneId, options || ({} as any));
|
||||
this.stage.register(scene);
|
||||
|
||||
if (type === 'base') {
|
||||
this.registerListeners(scene, wrapper);
|
||||
} else {
|
||||
this.registerWizardListeners(scene as Scenes.WizardScene<any>, wrapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private filterUpdates(wrapper: InstanceWrapper): InstanceWrapper<unknown> {
|
||||
const { instance } = wrapper;
|
||||
if (!instance) return undefined;
|
||||
@ -102,16 +76,6 @@ export class ListenersExplorerService
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private filterScenes(wrapper: InstanceWrapper): InstanceWrapper<unknown> {
|
||||
const { instance } = wrapper;
|
||||
if (!instance) return undefined;
|
||||
|
||||
const isScene = this.metadataAccessor.isScene(wrapper.metatype);
|
||||
if (!isScene) return undefined;
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private registerListeners(
|
||||
composer: Composer<any>,
|
||||
wrapper: InstanceWrapper<unknown>,
|
||||
@ -123,60 +87,6 @@ export class ListenersExplorerService
|
||||
);
|
||||
}
|
||||
|
||||
private registerWizardListeners(
|
||||
wizard: Scenes.WizardScene<any>,
|
||||
wrapper: InstanceWrapper<unknown>,
|
||||
): void {
|
||||
const { instance } = wrapper;
|
||||
const prototype = Object.getPrototypeOf(instance);
|
||||
|
||||
type WizardMetadata = { step: number; methodName: string };
|
||||
const wizardSteps: WizardMetadata[] = [];
|
||||
const basicListeners = [];
|
||||
|
||||
this.metadataScanner.scanFromPrototype(
|
||||
instance,
|
||||
prototype,
|
||||
(methodName) => {
|
||||
const methodRef = prototype[methodName];
|
||||
const metadata = this.metadataAccessor.getWizardStepMetadata(methodRef);
|
||||
if (!metadata) {
|
||||
basicListeners.push(methodName);
|
||||
return undefined;
|
||||
}
|
||||
wizardSteps.push({ step: metadata.step, methodName });
|
||||
},
|
||||
);
|
||||
|
||||
for (const methodName of basicListeners) {
|
||||
this.registerIfListener(wizard, instance, prototype, methodName);
|
||||
}
|
||||
|
||||
const group = wizardSteps
|
||||
.sort((a, b) => a.step - b.step)
|
||||
.reduce<{ [key: number]: WizardMetadata[] }>(
|
||||
(prev, cur) => ({
|
||||
...prev,
|
||||
[cur.step]: [...(prev[cur.step] || []), cur],
|
||||
}),
|
||||
{},
|
||||
);
|
||||
|
||||
wizard.steps = Object.values(group).map((stepsMetadata) => {
|
||||
const composer = new Composer();
|
||||
stepsMetadata.forEach((stepMethod) => {
|
||||
this.registerIfListener(
|
||||
composer,
|
||||
instance,
|
||||
prototype,
|
||||
stepMethod.methodName,
|
||||
[{ method: 'use', args: [] }],
|
||||
);
|
||||
});
|
||||
return composer.middleware();
|
||||
});
|
||||
}
|
||||
|
||||
private registerIfListener(
|
||||
composer: Composer<any>,
|
||||
instance: any,
|
18
src/services/metadata-accessor.service.ts
Normal file
18
src/services/metadata-accessor.service.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { LISTENERS_METADATA, UPDATE_METADATA } from '../telegraf.constants';
|
||||
import { ListenerMetadata } from '../interfaces';
|
||||
|
||||
@Injectable()
|
||||
export class MetadataAccessorService {
|
||||
constructor(private readonly reflector: Reflector) {}
|
||||
|
||||
isUpdate(target: Function): boolean {
|
||||
if (!target) return false;
|
||||
return !!this.reflector.get(UPDATE_METADATA, target);
|
||||
}
|
||||
|
||||
getListenerMetadata(target: Function): ListenerMetadata[] | undefined {
|
||||
return this.reflector.get(LISTENERS_METADATA, target);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { Provider } from '@nestjs/common';
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { Bot } from 'grammy';
|
||||
import { TELEGRAF_ALL_BOTS } from './telegraf.constants';
|
||||
|
||||
export const allBotsMap = new Map<string, Telegraf<any>>();
|
||||
export const allBotsMap = new Map<string, Bot<any>>();
|
||||
|
||||
export const telegrafAllBotsProvider: Provider = {
|
||||
provide: TELEGRAF_ALL_BOTS,
|
@ -18,7 +18,6 @@ import {
|
||||
TELEGRAF_MODULE_OPTIONS,
|
||||
} from './telegraf.constants';
|
||||
import { ListenersExplorerService, MetadataAccessorService } from './services';
|
||||
import { telegrafStageProvider } from './stage.provider';
|
||||
import {
|
||||
allBotsMap,
|
||||
telegrafAllBotsProvider,
|
||||
@ -61,13 +60,11 @@ export class TelegrafCoreModule implements OnApplicationShutdown {
|
||||
provide: TELEGRAF_MODULE_OPTIONS,
|
||||
useValue: options,
|
||||
},
|
||||
telegrafStageProvider,
|
||||
telegrafBotNameProvider,
|
||||
telegrafBotProvider,
|
||||
telegrafAllBotsProvider,
|
||||
],
|
||||
exports: [
|
||||
telegrafStageProvider,
|
||||
telegrafBotNameProvider,
|
||||
telegrafBotProvider,
|
||||
telegrafAllBotsProvider,
|
||||
@ -101,13 +98,11 @@ export class TelegrafCoreModule implements OnApplicationShutdown {
|
||||
imports: options.imports,
|
||||
providers: [
|
||||
...asyncProviders,
|
||||
telegrafStageProvider,
|
||||
telegrafBotNameProvider,
|
||||
telegrafBotProvider,
|
||||
telegrafAllBotsProvider,
|
||||
],
|
||||
exports: [
|
||||
telegrafStageProvider,
|
||||
telegrafBotNameProvider,
|
||||
telegrafBotProvider,
|
||||
telegrafAllBotsProvider,
|
@ -6,10 +6,10 @@ import {
|
||||
} from './interfaces';
|
||||
|
||||
@Module({})
|
||||
export class TelegrafModule {
|
||||
export class GrammyModule {
|
||||
public static forRoot(options: TelegrafModuleOptions): DynamicModule {
|
||||
return {
|
||||
module: TelegrafModule,
|
||||
module: GrammyModule,
|
||||
imports: [TelegrafCoreModule.forRoot(options)],
|
||||
exports: [TelegrafCoreModule],
|
||||
};
|
||||
@ -19,7 +19,7 @@ export class TelegrafModule {
|
||||
options: TelegrafModuleAsyncOptions,
|
||||
): DynamicModule {
|
||||
return {
|
||||
module: TelegrafModule,
|
||||
module: GrammyModule,
|
||||
imports: [TelegrafCoreModule.forRootAsync(options)],
|
||||
exports: [TelegrafCoreModule],
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import { Composer, Middleware } from 'telegraf';
|
||||
import { Composer, Middleware } from 'grammy';
|
||||
|
||||
export type Filter<T extends any[], F> = T extends []
|
||||
? []
|
16
src/utils/create-bot-factory.util.ts
Normal file
16
src/utils/create-bot-factory.util.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Bot } from 'grammy';
|
||||
import { TelegrafModuleOptions } from '../interfaces';
|
||||
|
||||
export async function createBotFactory(
|
||||
options: TelegrafModuleOptions,
|
||||
): Promise<Bot> {
|
||||
const bot = new Bot(options.token, options.config);
|
||||
|
||||
bot.use(...(options.middlewares ?? []));
|
||||
|
||||
if (options.pollingOptions !== false) {
|
||||
bot.start(options.pollingOptions);
|
||||
}
|
||||
|
||||
return bot;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Composer } from 'telegraf';
|
||||
import { Composer } from 'grammy';
|
||||
import { ComposerMethodArgs, OnlyFunctionPropertyNames } from '../types';
|
||||
import { LISTENERS_METADATA } from '../telegraf.constants';
|
||||
import { ListenerMetadata } from '../interfaces';
|
9
tsconfig.lib.json
Normal file
9
tsconfig.lib.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"outDir": "../../dist/libs/grammy"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user