Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xtcry/nestjs-vk
Modern VK API SDK module for NestJS
https://github.com/xtcry/nestjs-vk
nest nestjs vk vk-api vk-bot vk-io vk-sdk vkbot vkontakte
Last synced: about 1 month ago
JSON representation
Modern VK API SDK module for NestJS
- Host: GitHub
- URL: https://github.com/xtcry/nestjs-vk
- Owner: xTCry
- Created: 2021-08-02T17:26:49.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-09-05T19:29:09.000Z (about 1 year ago)
- Last Synced: 2024-10-09T18:21:34.482Z (about 1 month ago)
- Topics: nest, nestjs, vk, vk-api, vk-bot, vk-io, vk-sdk, vkbot, vkontakte
- Language: TypeScript
- Homepage:
- Size: 737 KB
- Stars: 15
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# NestJS VK
[![npm](https://img.shields.io/npm/v/nestjs-vk.svg?style=flat-square)](https://www.npmjs.com/package/nestjs-vk)
[![NPM](https://img.shields.io/npm/dt/nestjs-vk.svg?style=flat-square)](https://www.npmjs.com/package/nestjs-vk)
[![GitHub last commit](https://img.shields.io/github/last-commit/xtcry/nestjs-vk)](https://github.com/xtcry/nestjs-vk)**NestJS VK** – powerful solution for creating VK bots.
This package uses the best of the NodeJS world under the hood. [VK-IO](https://github.com/negezor/vk-io) is a powerful Node.js module that allows you to easily interact with the VK API and for creating bots, and [NestJS](https://github.com/nestjs) is a progressive framework for creating well-architectured applications.
This module provides a quick and easy way to interact with the VK API and create VK bots and deep integration with your NestJS application.
**Features**
- Simple. Easy to use.
- Ability to create custom decorators.
- Scenes support.
- Ability to run multiple bots simultaneously.
- Full support of NestJS guards, interceptors, filters and pipes!## Installation
#### NPM
```bash
$ npm i nestjs-vk vk-io
```#### Yarn
```bash
$ yarn add nestjs-vk vk-io
```## Usage
Once the installation process is complete, we can import the `VkModule` into the root `AppModule`:
```typescript
import { Module } from '@nestjs/common';
import { VkModule } from 'nestjs-vk';import { AppUpdate } from './app.update';
import { SimpleScene } from './scene/simple.scene';@Module({
imports: [
VkModule.forManagers({
useSessionManager: false,
useSceneManager: false,
useHearManager: false,
}),
VkModule.forRootAsync({
inject: [MainMiddleware],
useFactory: async (mainMiddleware: MainMiddleware) => ({
token: process.env.VK_BOT_TOKEN,
options: {
pollingGroupId: +process.env.VK_BOT_GROUP_ID,
apiMode: 'sequential',
},
// launchOptions: false,
// notReplyMessage: true,
middlewaresBefore: [mainMiddleware.middlewaresBefore],
middlewaresAfter: [mainMiddleware.middlewaresAfter],
}),
}),
// VkModule.forRoot({
// token: process.env.VK_BOT_TOKEN,
// options: {
// pollingGroupId: +process.env.VK_BOT_GROUP_ID,
// apiMode: 'sequential',
// },
// }),
],
providers: [MainMiddleware, AppUpdate, SimpleScene],
exports: [MainMiddleware],
})
export class AppModule {}
```Main middleware `main.middleware.ts`:
```typescript
import { Inject, Injectable } from '@nestjs/common';
import { VK_HEAR_MANAGER, VK_SCENE_MANAGER } from 'nestjs-vk';
import { MessageContext, Context, Composer } from 'vk-io';
import { HearManager } from '@vk-io/hear';
import { SessionManager } from '@vk-io/session';
import { SceneManager } from '@vk-io/scenes';@Injectable()
export class MainMiddleware {
private readonly sessionManager: SessionManager;
@Inject(VK_HEAR_MANAGER)
private readonly hearManagerProvider: HearManager;
@Inject(VK_SCENE_MANAGER)
private readonly sceneManager: SceneManager;constructor() {
this.sessionManager = new SessionManager({
// ...
});
}get middlewaresBefore() {
const composer = Composer.builder();composer.use(this.sessionManager.middleware);
composer.use(this.sceneManager.middleware);return composer.compose();
}get middlewaresAfter() {
const composer = Composer.builder();composer.use(this.hearManagerProvider.middleware);
return composer.compose();
}
}
```Then create `app.update.ts` file and add some decorators for handling VK bot API updates:
```typescript
import { InjectVkApi, Update, Ctx, Message, Hears, HearFallback } from 'nestjs-vk';
import { MessageContext, VK } from 'vk-io';import { AppService } from './app.service';
import { SIMPLE_SCENE } from './vk.constants';@Update()
export class AppUpdate {
public groupId: number;constructor(
@InjectVkApi()
private readonly vk: VK,
private readonly appService: AppService,
) {}async onModuleInit() {
try {
const [group] = await this.vk.api.groups.getById({});
this.groupId = group.id;
} catch (err) {
console.error(err);
}
}@Hears(/^\/?(start|старт)$/i)
async onStartCommand(@Ctx() ctx: MessageContext) {
await ctx.reply('Welcome');
}@Hears('hi')
async hearsHi(@Ctx() ctx: MessageContext) {
return 'Hey there';
}@Hears(/scene( ?(?[0-9]+))?$/i)
async hearsScene(@Ctx() ctx: MessageContext) {
const stateNumber = ((e) => (isNaN(Number(e)) ? null : Number(e)))(ctx.$match?.groups?.state);
ctx.scene.enter(SIMPLE_SCENE, { state: { stateNumber } });
}@Hears(['/sub', 'subscriber'])
async onSubscriberCommand(@Ctx() ctx: MessageContext) {
const isSib = await this.vk.api.groups.isMember({
group_id: String(this.groupId),
user_id: ctx.senderId,
});
return isSib ? 'So good!' : 'No sub';
}@HearFallback()
onHearFallback(@Ctx() ctx: MessageContext, @Message('text') text: string) {
if (text) {
return this.appService.echo(text);
} else if (ctx.hasAttachments('sticker')) {
ctx.send({ sticker_id: ctx.getAttachments('sticker')[0].id % 24 });
return;
}return 'What?..';
}
}
```For a simple scene, let's create an `simple.scene.ts` file and do a few steps for it:
```typescript
import { Scene, AddStep, Ctx, SceneEnter, SceneLeave } from 'nestjs-vk';
import { MessageContext } from 'vk-io';
import { IStepContext } from '@vk-io/scenes';import { SIMPLE_SCENE } from './vk.constants';
@Scene(SIMPLE_SCENE)
export class SimpleScene {
@SceneEnter()
async onSceneEnter(@Ctx() ctx: IStepContext) {
const { stateNumber } = ctx.scene.state;
await ctx.reply(
`Hello! I am a simple scene. Your state number is ${stateNumber}.\n` +
` You can send me a number and I will multiply it by 2.`,
);
}@SceneLeave()
async onSceneLeave(@Ctx() ctx: IStepContext) {
await ctx.reply('Bye!');
}// @Hears('exit')
// async onHearsExit(@Ctx() ctx: IStepContext) {
// await ctx.scene.leave();
// }@AddStep()
async onAddStep(@Ctx() ctx: IStepContext) {
let { stateNumber: number } = ctx.scene.state;if (!ctx.scene.step.firstTime) {
number = Number(ctx.text);
}if (ctx.scene.step.firstTime && number === null) {
await ctx.reply('Please send me a number.');
return;
}if (isNaN(number)) {
await ctx.reply('Wrong. Please send me a number.');
return;
}await ctx.reply(`Your number multiplied by 2 is ${number * 2}.`);
if (number > 20 && number % 2 === 0) {
await ctx.scene.leave();
}
}
}
```