Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

puregram

Package Overview
Dependencies
Maintainers
1
Versions
142
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

puregram - npm Package Compare versions

Comparing version 2.0.8-rc.1 to 2.0.8-rc.2

4

lib/interfaces.d.ts

@@ -14,7 +14,7 @@ /// <reference types="node" />

apiRetryLimit?: number;
/** How much will library wait for API to answer before aborting the request? */
/** How much will library wait for API to answer before aborting the request? In milliseconds */
apiTimeout?: number;
/** Headers of requests */
apiHeaders?: Record<string, string>;
/** How much will library wait before retrying to get updates? */
/** How much will library wait before retrying to get updates? In milliseconds */
apiWait?: number;

@@ -21,0 +21,0 @@ }

@@ -98,17 +98,10 @@ "use strict";

debug(`[${method}] Params: ${body}`);
let response;
try {
response = await node_fetch_1.default(url, {
agent: this.options.agent,
compress: false,
method: 'POST',
signal: controller.signal,
headers,
body
});
}
catch (e) {
debug(e);
/// TODO: request is invalid, what to do?
}
const response = await node_fetch_1.default(url, {
agent: this.options.agent,
compress: false,
method: 'POST',
signal: controller.signal,
headers,
body
});
debug(`[${method}] <- HTTP ${(_a = response === null || response === void 0 ? void 0 : response.status) !== null && _a !== void 0 ? _a : '[not set]'}`);

@@ -206,3 +199,3 @@ if (response !== undefined) {

}
// hack: remove 'media', 'photo', 'video' etc. keys from contextData
// hack: remove 'media' key from `contextData`
let { media: _, ...tempContextData } = contextData;

@@ -209,0 +202,0 @@ for (const tempValue of values) {

@@ -66,3 +66,3 @@ /// <reference types="node" />

private fetchUpdates;
updateHandler(update: TelegramUpdate): Promise<void>;
handleUpdate(update: TelegramUpdate): Promise<Context | undefined>;
getKoaMiddleware(): Function;

@@ -69,0 +69,0 @@ getWebhookMiddleware(): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;

@@ -206,2 +206,3 @@ "use strict";

this.isStarted = false;
this.retries = 0;
}

@@ -214,9 +215,19 @@ /** Start polling */

if (!this.telegram.options.token) {
debug('Bot token is not set. Perhaps you forgot to set it?');
throw new TypeError('Token is not set. Perhaps you forgot to set it?');
}
debug('Fetching bot data...');
const bot = new user_1.User(await this.telegram.api.getMe());
this.telegram.bot = bot;
debug('Telegram bot data fetched.');
debug(bot);
if (!this.telegram.bot) {
debug('Fetching bot data...');
let me;
try {
me = await this.telegram.api.getMe();
}
catch (error) {
debug('Unable to fetch bot info, stopping right away');
return this.stopPolling();
}
const bot = new user_1.User(me);
this.telegram.bot = bot;
debug('Bot data fetched successfully:');
debug(bot);
}
this.isStarted = true;

@@ -226,22 +237,25 @@ try {

}
catch (e) {
catch (error) {
this.isStarted = false;
throw e;
throw error;
}
}
async startFetchLoop(options) {
while (this.isStarted) {
try {
try {
while (this.isStarted) {
await this.fetchUpdates(options);
}
catch (e) {
debug('startFetchLoop:', e);
if (this.retries === this.telegram.options.apiRetryLimit) {
return;
}
this.retries += 1;
await helpers_1.delay(this.telegram.options.apiWait);
this.stopPolling();
this.startPolling();
}
catch (error) {
debug(error);
if (this.retries === this.telegram.options.apiRetryLimit) {
debug(`Tried to reconnect ${this.retries} times, but it didn't work, cya next time`);
return;
}
this.retries += 1;
debug(`Trying to reconnect, ${this.retries}/${this.telegram.options.apiRetryLimit} try`);
await helpers_1.delay(this.telegram.options.apiWait);
// not this.stopPolling() because it resets this.retries
this.isStarted = false;
this.startPolling();
}

@@ -259,14 +273,22 @@ }

const updates = await this.telegram.api.getUpdates(params);
if (!updates.length)
if (!updates) {
/// Something is wrong with the internet connection I can feel it...
debug('`fetchUpdates` error: unable to get updates');
this.stopPolling();
this.startPolling();
return;
}
if (!updates || !updates.length)
return;
updates.forEach(async (update) => {
try {
await this.updateHandler(update);
await this.handleUpdate(update);
}
catch (e) {
debug('fetchUpdates:', e);
catch (error) {
debug('`fetchUpdates` error:');
debug(error);
}
});
}
async updateHandler(update) {
async handleUpdate(update) {
this.offset = update.update_id + 1;

@@ -277,6 +299,7 @@ const type = Object.keys(update)[1];

if (!UpdateContext) {
debug(`Unsupported context type ${type}`);
debug(`Unsupported context type \`${type}\``);
return;
}
debug('Update payload:', update[type]);
debug('Update payload:');
debug(update[type]);
let context = new UpdateContext({

@@ -303,2 +326,3 @@ telegram: this.telegram,

this.dispatchMiddleware(context);
return context;
}

@@ -314,3 +338,3 @@ getKoaMiddleware() {

context.set('connection', 'keep-alive');
setImmediate(() => this.updateHandler(update));
setImmediate(() => this.handleUpdate(update));
};

@@ -339,3 +363,3 @@ }

res.end();
setImmediate(() => this.updateHandler(update));
setImmediate(() => this.handleUpdate(update));
};

@@ -342,0 +366,0 @@ }

import http from 'http';
export declare const applyMixins: (derivedCtor: any, baseCtors: any[]) => void;
export declare const isPlainObject: (object: object) => boolean;
export declare const isPlainObject: (object: object) => object is Record<string, any>;
export declare const filterPayload: (payload: Record<string, any>) => Record<string, any>;

@@ -5,0 +5,0 @@ export declare const isParseable: (source: string) => boolean;

@@ -20,4 +20,3 @@ "use strict";

for (const [key, value] of Object.entries(payload)) {
const notEmpty = (value !== undefined
&& value !== null);
const notEmpty = value !== undefined && value !== null;
const isEmptyArray = (Array.isArray(value)

@@ -40,3 +39,2 @@ && value.length === 0);

JSON.parse(source);
return true;
}

@@ -46,7 +44,6 @@ catch (e) {

}
return true;
};
exports.isParseable = isParseable;
const delay = (delayed) => (new Promise((resolve) => {
setTimeout(resolve, delayed);
}));
const delay = (delayed) => (new Promise(resolve => setTimeout(resolve, delayed)));
exports.delay = delay;

@@ -53,0 +50,0 @@ const useLazyLoad = (fn) => {

{
"name": "puregram",
"version": "2.0.8-rc.1",
"description": "Powerful Node.js package written on TypeScript that allows you to work with Telegram API",
"version": "2.0.8-rc.2",
"description": "Powerful and modern Telegram Bot API SDK for Node.js and TypeScript 😁",
"main": "lib/index",

@@ -12,4 +12,4 @@ "author": "nitrojs",

"form-data": "^3.0.0",
"inspectable": "^1.0.0",
"middleware-io": "^2.5.0",
"inspectable": "^1.2.0",
"middleware-io": "^2.8.0",
"node-fetch": "^2.6.1"

@@ -19,10 +19,12 @@ },

"scripts": {
"build": "tsc --project tsconfig.json"
"clear-lib": "rm -rf lib/",
"build": "yarn clear-lib && tsc --project tsconfig.json"
},
"keywords": [
"telegram",
"api",
"sdk",
"node",
"js",
"telegram-api",
"telegram-bot-api",
"session",
"scenes",
"typescript",
"bot"

@@ -35,12 +37,4 @@ ],

"@types/debug": "^4.1.5",
"@types/node-fetch": "^2.5.7",
"@typescript-eslint/eslint-plugin": "^3.6.0",
"@typescript-eslint/parser": "^3.6.0",
"babel-jest": "^26.2.1",
"eslint": "^7.4.0",
"eslint-plugin-import": "^2.22.0",
"jest": "^26.2.1",
"ts-jest": "^26.1.4",
"ts-node": "github:TypeStrong/ts-node#master",
"typescript": "^4.3.2"
"@types/node-fetch": "^2.5.10",
"typescript": "^4.3.4"
},

@@ -53,8 +47,7 @@ "directories": {

"type": "git",
"url": "git+https://github.com/nitreojs/puregram.git"
"url": "git+https://github.com/nitreojs/puregram.git",
"directory": "packages/puregram"
},
"bugs": {
"url": "https://github.com/nitreojs/puregram/issues"
},
"bugs": "https://github.com/nitreojs/puregram/issues",
"homepage": "https://github.com/nitreojs/puregram#readme"
}

@@ -1,48 +0,107 @@

<p align='center'>
<img src='https://github.com/nitreojs/puregram/blob/master/docs/logo.png' />
</p>
<!-- Inspired by prisma.io & Telegraf docs -->
<div align='center'>
<img src='https://i.imgur.com/ZzjmE8i.png' />
</div>
<br />
<p align='center'>
<b>Powerful</b>
<a href='nodejs.org'>Node.js</a>
package that allows you to
<b>easily</b>
interact with
<a src='https://core.telegram.org/bots/api'>Telegram API</a>
🚀
Powerful and epic overall,
<code>puregram</code>
allows you to
<b>easily interact</b>
with
<a href='https://core.telegram.org/bots/api'>Telegram Bot API</a>
via
<a href='https://nodejs.org'>Node.js</a>/<a href='https://www.typescriptlang.org'>TypeScript</a>
😎👍
</p>
<table align='center'>
<tr>
<th>
<a href='https://github.com/nitreojs/puregram/tree/master/docs/examples'>
🤖 Examples
</a>
</th>
<th>
<a href='https://github.com/nitreojs/puregram/tree/master/docs'>
📖 Documentation
</a>
</th>
<th>
<a href='https://t.me/puregram_chat'>
💬 Chat
</a>
</th>
<th>
<a href='https://t.me/puregram_channel'>
💬 Channel
</a>
</th>
</tr>
</table>
<div align='center'>
<a href='https://github.com/nitreojs/puregram/tree/master/docs'><b>Docs</b></a>
<span>&nbsp;•&nbsp;</span>
<a href='https://github.com/nitreojs/puregram/tree/master/docs/examples'><b>Examples</b></a>
<span>&nbsp;•&nbsp;</span>
<a href='#typescript-usage'><b>TypeScript usage</b></a>
<span>&nbsp;•&nbsp;</span>
<a href='https://t.me/puregram_chat'><b>Chat</b></a>
<span>&nbsp;•&nbsp;</span>
<a href='https://t.me/puregram_channel'><b>Channel</b></a>
</div>
## Features
## Introduction
* 100% [**Telegram Bot API**](https://core.telegram.org/bots/api) coverage
* Works with JavaScript and TypeScript
**First, what are Telegram bots?** [Telegram][telegram] has their own [bot accounts][telegram/bots]. **Bots** are special Telegram accounts that can be only accessed via code and were designed to handle messages, inline queries and callback queries automatically. _Users can interact with bots by sending them messages, commands and inline requests._
## Installation
> **[Node.js](https://nodejs.org/) 12.0.0 or newer is required**
[telegram]: https://t.me
[telegram/bots]: https://core.telegram.org/bots
### Example
```js
const { Telegram } = require('puregram');
const bot = new Telegram({
token: process.env.TOKEN
});
bot.updates.on('message', context => context.reply('Hey!'));
bot.updates.on('callback_query', context => context.answerCallbackQuery());
bot.updates.startPolling();
```
More examples [here][examples]
[examples]: https://github.com/nitreojs/puregram/tree/master/docs/examples
---
## Table of Contents
- [Why `puregram`?](#why-puregram) _(very important!!)_
- [**Getting started**](#getting-started)
- [Getting token](#getting-token)
- [Installation](#installation)
- [Usage](#usage)
- [Calling API methods](#calling-api-methods)
- [Sending media](#sending-media)
- [Using markdown (`parse_mode`)](#using-markdown)
- [Keyboards (`reply_markup`)](#keyboards)
- [Bot information](#bot-information)
- [What are contexts?](#what-are-contexts)
- [`Context` and its varieties](#context-and-its-varieties)
- [Middlewares](#middlewares)
- [**TypeScript usage**](#typescript-usage)
- [**FAQ**](#faq)
---
## Why `puregram`?
- Written **by [nitreojs](https://github.com/nitreojs)** ⚠
- Very **cool** package name
- Package itself is **cool** _(at least I think so)_
- **Works** _(I guess)_
- I **understand** only about **20% of** my **code**
- Because **why not**?
That's why this package is **_epic_**
---
## Getting started
### Getting token
If you want to develop a bot, firstly you need to [create it][telegram/bots/botfather] via [@BotFather][botfather] and get token from it via `/newbot` command.
[telegram/bots/botfather]: https://core.telegram.org/bots#6-botfather
[botfather]: https://t.me/botfather
Token looks like this: `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`
### Installation
```sh

@@ -53,66 +112,519 @@ $ yarn add puregram

## Polling example
### Usage
#### Initializing `Telegram` instance
Let's start with creating a `Telegram` instance:
```js
import { Telegram } from 'puregram';
const { Telegram } = require('puregram');
const telegram = new Telegram({
token: process.env.TOKEN
const bot = new Telegram({
token: '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11'
});
```
// Message received
telegram.updates.on(
'message',
(context) => context.send('Hello, World!')
);
Now, we want to [get updates][getting-updates] from the bot. **How can we do it?**
// Inline button pressed
telegram.updates.on(
'callback_query',
(context) => (
context.message.editMessageText('*You just clicked the inline button!*', {
parse_mode: 'Markdown'
#### Getting updates
There are only **two ways** of getting updates right now:
1. Polling via [`getUpdates` method][getUpdates]... or just using `puregram`'s built-in polling logic:
```js
bot.updates.startPolling();
```
2. Setting up a Webhook via [`setWebhook` method][setWebhook]:
```js
const { createServer } = require('http');
// you need to send this request only once
bot.api.setWebhook({
url: 'https://www.example.com/'
});
const server = createServer(bot.updates.getWebhookMiddleware());
server.listen(8443, () => console.log('Started'));
```
Remember that there are only four accepted ports for now: `443`, `80`, `88` and `8443`. They are listed [here][setWebhook] under the **Notes** section.
More webhook examples are available [here][webhook-examples]
[getting-updates]: https://core.telegram.org/bots/api#getting-updates
[getUpdates]: https://core.telegram.org/bots/api#getupdates
[setWebhook]: https://core.telegram.org/bots/api#setwebhook
[webhook-examples]: https://github.com/nitreojs/puregram/tree/master/docs/examples/webhook
#### Handling updates
Now with this setup we can catch updates like this:
```js
bot.updates.on('message', context => context.reply('Yoooo!'));
```
_List of supported updates will be somewhere here when it's done_
#### Manual updates handling
_Available from 2.0.8-rc.2 and later_
If you want to handle updates by yourself, you can use `Updates.handleUpdate` method, which takes one argument and this argument is raw Telegram update:
```js
/** Let's pretend I am polling updates manually... */
const update = await getUpdate(...);
let context;
try {
context = await bot.updates.handleUpdate(update);
} catch (error) {
console.log('Update is not supported', update);
}
// Voila! Now you have the right context
// (or you don't if the event is not supported 😢)
```
### Calling API methods
There are **three ways** of calling Telegram Bot API methods:
1. Using the `bot.callApi(method, params?)` _(useful when new Bot API update is released and the package is not updated yet)_:
```js
const me = await bot.callApi('getMe');
```
2. Using `bot.api.method(params?)`:
```js
const me = await bot.api.getMe();
```
3. Using context methods:
```js
bot.updates.on('message', context => context.send('13² = 169! I mean 169, not 169!'));
```
### Sending media
`puregram` allows you to send your local media via path, `Buffer`, `Stream` and URLs.
```js
/** Let's imagine we have an image called puppy.jpg in this directory... */
const { createReadStream } = require('fs');
const path = './puppy.jpg';
const stream = createReadStream(path);
const buffer = getBuffer(path);
const url = 'https://puppies.com/random-puppy';
bot.updates.on('message', (context) => {
context.sendPhoto(path, { caption: 'Puppy via path!' });
context.sendDocument(stream, { caption: 'More puppies via stream!', filename: 'puppy.jpg' });
context.sendPhoto(buffer, { caption: 'One more puppy via buffer!' });
context.sendPhoto(url, { caption: 'Some random puppy sent using an URL!!!' });
});
```
This works for every method that can send media.
---
### Using markdown
If you want to use _Markdown_ or _HTML_, there are **two ways** of doing that:
1. Using built-in `HTML`, `Markdown` and `MarkdownV2` classes:
```js
const message = HTML.bold('Very bold, such HTML');
```
3. Writing tags manually as it is told [here][formatting-options]:
```js
const message = '*Very bold, such Markdown*';
```
[formatting-options]: https://core.telegram.org/bots/api#formatting-options
Anyways, after writing the text you **need** to add `parse_mode` field. There are also **two ways** of doing that _¯\\\_(ツ)\_/¯_:
3. Writing actual parse mode code _like a boss_:
```js
{ parse_mode: 'Markdown' }
```
7. Passing parse mode class _like a cheems_:
```js
{ parse_mode: HTML }
```
Final API request will look like this:
```js
const message = `Some ${HTML.bold('bold')} and ${HTML.italic('italic')} here`;
context.send(message, { parse_mode: HTML });
```
```js
context.send(`Imagine using _classes_ for parse mode, *lol*!`, { parse_mode: 'Markdown' });
```
<details>
<summary><i>The truth...</i></summary>
<br />
<img src="https://i.imgur.com/x6EFfCH.png" />
</details>
More markdown examples are available [here][markdown]
[markdown]: https://github.com/nitreojs/puregram/tree/master/docs/examples/markdown
---
### Keyboards
`puregram` has built-in classes for creating basic, inline, force-reply etc. keyboards. They are pretty much easy to use and are definitely more comfortable than building a JSON.
#### `InlineKeyboard`, `Keyboard` and so on
To create a keyboard, you need to call `keyboard` method from the keyboard class you chose. This method accepts an array of button rows.
```js
const { InlineKeyboard, Keyboard } = require('puregram');
const keyboard = InlineKeyboard.keyboard([
[ // first row
InlineKeyboard.textButton({ // first row, first button
text: 'Some text here',
payload: 'Such payload'
}),
InlineKeyboard.textButton({ // first row, second button
text: 'Some more text here',
payload: { json: true }
})
)
],
[ // second row
InlineKeyboard.urlButton({ // second row, first button
text: 'Some URL button',
url: 'https://example.com'
})
]
]);
```
```js
// one-row keyboard with two buttons, no brackets for rows needed
const keyboard = Keyboard.keyboard([
Keyboard.textButton('Some one-row keyboard'),
Keyboard.textButton('with some buttons')
]);
```
#### Keyboard builders
There are also keyboard **builders** which are designed to be building a keyboard step by step:
```js
const { KeyboardBuilder } = require('puregram');
const keyboard = new KeyboardBuilder()
.textButton('First row, first button')
.row()
.textButton('Second row, first button')
.textButton('Second row, second button')
.resize(); // keyboard will be much smaller
```
#### Sending keyboards
To send keyboard, you simply need to pass the generated value in `reply_markup` field:
```js
context.send('Look, here\'s a keyboard!', { reply_markup: keyboard });
```
More keyboards examples are available [here][keyboards]
[keyboards]: https://github.com/nitreojs/puregram/tree/master/docs/examples/keyboards
---
## Bot information
If you are using `puregram`'s built-in polling logic, after `Updates.startPolling()` is called you have access to `Telegram.bot` property:
```js
bot.updates.startPolling().then(
() => console.log(`@${bot.bot.username} started polling!`)
// yeah, `bot.bot` ¯\_(ツ)_/¯
// that's why I prefer naming `telegram` instead of `bot`
);
```
telegram.updates.startPolling().catch(console.error);
---
## What are contexts?
Context is a class, containing current `update` object and it's payload _(via `update[updateType]`)_. It is loaded with a ton of useful _(maybe?)_ getters and methods that were made to shorten your code while being same efficient and executing the same code.
```js
bot.updates.on('message', (context) => {
const id = context.senderId;
// is the same as
const id = context.from?.id;
});
bot.updates.on('message', (context) => {
context.send('Hey!');
// equals to
bot.api.sendMessage({
chat_id: context.chat?.id,
text: 'Hey!'
});
});
```
## Webhook example (express)
Every context has `telegram` property, so you can call API methods almost everywhere if you have a context nearby.
```js
import express from 'express';
import { Telegram } from 'puregram';
bot.updates.on('message', async (context) => {
const me = await context.telegram.api.getMe();
});
```
const telegram = new Telegram({
token: process.env.TOKEN
---
## `Context` and its varieties
Every update in `puregram` is handled by a special context, which is detected via the update key.
Every context _(except for manually created ones and some that were created after methods like `sendMessage`)_ will have `updateId` and `update` properties.
| Property | Required | Description |
| ---------- | -------- | ----------------------------------------------------------------------------- |
| `updateId` | _No_ | Unique update ID. Used as an offset when getting new updates |
| `update` | _No_ | Update object. Current context was created via `this.update[this.updateType]` |
For example, if we have the `message` update, we will get `MessageContext` on this update, `CallbackQueryContext` for `callback_query` update and so on.
Every context requires **one argument**:
```ts
interface ContextOptions {
// main Telegram instance
telegram: Telegram;
// update type, e.g. 'message', 'callback_query'
updateType: UpdateName;
// whole update object
// optional, allows user to do the `context.update` to get the whole update object
update?: TelegramUpdate;
// update ID, located at TelegramUpdate
// optional, allows user to get this update's ID
updateId?: number;
}
```
You can also create any context manually:
```js
const { MessageContext } = require('puregram');
const update = await getUpdate();
const context = new MessageContext({
telegram: bot,
update,
updateType: 'message',
updateId: update.update_id
});
```
const app = express();
Every context is listed [here][contexts]
app.use(bodyParser.json());
app.use(telegram.updates.getWebhookMiddleware());
[contexts]: https://github.com/nitreojs/puregram/tree/master/packages/puregram/src/contexts
telegram.updates.on(
'message',
(context) => context.send('Hello, World!')
);
---
// Available ports: 80, 88, 443, 8443
app.listen(443, () => console.log('Webhook started handling!'));
## Middlewares
`puregram` uses middlewares, so you can use them to expand your `context` variables or measure other middlewares.
- `next()` is used to call the next middleware on the chain and wait until it's done
Measuring the time it takes to proceed the update:
```js
bot.updates.use(async (context, next) => {
const start = Date.now();
await next(); // next() is async, so we need to await it
const end = Date.now();
console.log(`${context.updateId ?? '[unknown]'} proceeded in ${end - start}ms`);
});
```
[**🤖 Click to see more examples!**](https://github.com/nitreojs/puregram/tree/master/docs/examples)
Extending the context:
```js
bot.updates.use((context, next) => {
context.user = await getUser(context.senderId);
return next();
});
bot.updates.on('message', (context) => {
// here we can access property we made in the middleware
return context.send(`Hey, ${context.user.name}!`);
});
```
---
## TypeScript usage
### Importing Telegram interfaces
All Telegram interfaces and method types are auto-generated and put in different files: `telegram-interfaces.ts` for interfaces and `methods.ts` + `api-methods.ts` for API methods. They all exist at the path `puregram/lib/`.
```ts
import { TelegramUpdate, TelegramMessage } from 'puregram/lib/telegram-interfaces';
import { SendDocumentParams } from 'puregram/lib/methods';
```
### Extending contexts
Surely enough, you can extend contexts with extra fields and properties you need by intersectioning base context with new properties.
```ts
interface ExtraData {
name: string;
id?: number;
}
/** ... */
bot.updates.use((context, next) => {
const user = await getUser(context.senderId);
bot.name = user.name;
bot.id = user.id;
return next();
});
/**
* There are 2 ways of updating context's type:
* 1. External type override:
* `(context: MessageContext & ExtraData) => ...`
* 2. Using generics:
* `bot.updates.on<ExtraData>(...)`
*
* Below I will be using the second way.
*/
bot.updates.on<ExtraData>('message', (context) => {
assert(context.name !== undefined);
});
```
---
## FAQ
### `TypeError: Cannot read property '__scene' of undefined`
You are trying to use [`@puregram/scenes`][@scenes] or [`@puregram/hear`][@hear] with [`@puregram/session`][@session], but you're the confusing middlewares order.
You should firstly initialize `@puregram/session`'s middleware and only then initialize other middlewares, depending on it:
```js
const sessionManager = new SessionManager();
const hearManager = new HearManager();
// 1. Session middleware first
bot.updates.on('message', sessionManager.middleware);
// 2. Hear middleware second
bot.updates.on('message', hearManager.middleware);
```
### How do I enable debugging?
If you want to inspect out- and ingoing requests made by `puregram`, you will need to enable `DEBUG` environment variable so the package understands you are ready for logs.
#### How to enable `DEBUG`
| Type | Example (Unix) | Description |
| --------- | ------------------------ | ----------------------------------------------- |
| `api` | `DEBUG=puregram:api` | Enables debugging API out- and ingoing requests |
| `updates` | `DEBUG=puregram:updates` | Enables debugging ingoing updates |
| `*` | `DEBUG=puregram:*` | Enables debugging all of the listed types above |
##### cmd
```cmd
> set "DEBUG=puregram:*" & node index
```
##### PowerShell
```ps
> $env:DEBUG = "puregram:*"; node index
```
##### Linux
```sh
$ DEBUG=puregram:* node index
```
---
## Community
### Packages that might be useful to you
These packages are created by the `puregram` community _(and not only)_ and are expanding packages functionality _(I guess)_.
- [**@puregram/hear**](https://github.com/nitreojs/puregram/tree/master/packages/hear): Simple implementation of hear system
- [**@puregram/scenes**](https://github.com/nitreojs/puregram/tree/master/packages/scenes): Simple implementation of middleware-based scene management
- [**@puregram/session**](https://github.com/nitreojs/puregram/tree/master/packages/session): Simple implementation of sessions
- [**@puregram/utils**](https://github.com/nitreojs/puregram/tree/master/packages/utils): _Almost_ useful utilities
### Some official packages
- [`@puregram/hear`][@hear]: Simple implementation of hear system
- [`@puregram/scenes`][@scenes]: Simple implementation of middleware-based scene management
- [`@puregram/session`][@session]: Simple implementation of sessions
- [`@puregram/utils`][@utils]: _Almost_ useful utilities
[@hear]: https://github.com/nitreojs/puregram/tree/master/packages/hear
[@scenes]: https://github.com/nitreojs/puregram/tree/master/packages/scenes
[@session]: https://github.com/nitreojs/puregram/tree/master/packages/session
[@utils]: https://github.com/nitreojs/puregram/tree/master/packages/utils
### Non-official ones
_Oh no, it's empty there..._ Maybe _you_ could add _your_ community package here?
---
## Thanks to
Biggest thanks to [Negezor](https://github.com/negezor) for his [vk-io](https://github.com/negezor/vk-io) library that helped me with this package!
- [Negezor][negezor] ([negezor/vk-io][negezor/vk-io]) — for inspiration, package idea (!) and some code and implementation ideas
[negezor]: https://github.com/negezor
[negezor/vk-io]: https://github.com/negezor/vk-io
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc