Skip to content

Хранилища

Это специальные хранилища данных. Их основное применение — в плагинах (например, сессии).

Адаптеры

GramIO имеет множество готовых адаптеров, но вы также можете написать свой собственный!

Как написать свой собственный адаптер хранилища

Написать свой адаптер очень просто!

Достаточно вернуть объект с необходимыми методами и использовать методы выбранного вами решения для адаптера (например, ioredis).

ts
import type { Storage } from "@gramio/storage";
import ThirdPartyStorage, { type ThirdPartyStorageOptions } from "some-library";

export interface MyOwnStorageOptions extends ThirdPartyStorageOptions {
    /** добавить новое свойство в параметры */
    some?: number;
}

export function myOwnStorage(options: MyOwnStorageOptions = {}): Storage {
    const storage = new ThirdPartyStorage(options);

    return {
        async get(key) {
            const data = await storage.get(key);

            return data ? JSON.parse(data) : undefined;
        },
        async has(key) {
            return storage.has(key);
        },
        async set(key, value) {
            await storage.set(key, JSON.stringify(value));
        },
        async delete(key) {
            return storage.delete(key);
        },
    };
}

IMPORTANT

Если вы хотите опубликовать свой адаптер, мы рекомендуем следовать соглашению и назвать его начиная с gramio-storage и добавить ключевые слова gramio + gramio-storage в ваш package.json

Как использовать адаптеры хранилища в своем плагине

Работать с адаптерами хранилища в вашем плагине также очень просто!

Всё, что нам нужно, уже есть в @gramio/storage.

ts
import { Plugin } from "gramio";
import { type Storage, inMemoryStorage } from "@gramio/storage";

export interface MyOwnPluginOptions {
    storage?: Storage;
}

export function myOwnPlugin(options: MyOwnPluginOptions = {}) {
    // используем хранилище в памяти по умолчанию
    const storage = options.storage ?? inMemoryStorage();

    return new Plugin("gramio-example");
}

IMPORTANT

Вы можете создать шаблон этого примера с помощью create-gramio-plugin

Типобезопасное хранилище с дженериками

Все адаптеры хранилищ поддерживают параметр обобщенного типа Storage<Data>, который обеспечивает типобезопасность для ключей и значений. Это позволяет TypeScript автоматически определять правильный тип значения на основе ключа, к которому вы обращаетесь.

Базовое использование

ts
import { 
inMemoryStorage
} from "@gramio/storage";
interface UserData {
username
: string;
email
: string;
age
: number;
} const
storage
=
inMemoryStorage
<UserData>();
await
storage
.
set
("username", "john_doe");
await
storage
.
set
("email", "john@example.com");
const
username
= await
storage
.
get
("username"); // string | undefined

Шаблонные литеральные типы

Storage<Data> отлично работает с шаблонными литеральными типами TypeScript, позволяя определять динамические паттерны ключей:

ts
import { 
inMemoryStorage
} from "@gramio/storage";
type
Data
=
Record
<`user:${number}`, {
name
: string;
age
: number }> &
Record
<`session:${string}`, {
token
: string;
expires
: number }>;
const
storage
=
inMemoryStorage
<
Data
>();
await
storage
.
set
("user:1", {
name
: "Alice",
age
: 30 });
await
storage
.
set
("session:abc123", {
token
: "xyz",
expires
: 1234567890 });
const
user
= await
storage
.
get
("user:1"); // { name: string; age: number } | undefined
const
session
= await
storage
.
get
("session:abc123"); // { token: string; expires: number } | undefined

Сложные объединения типов

Вы можете комбинировать несколько типов записей для различных паттернов ключей:

ts
import { 
inMemoryStorage
} from "@gramio/storage";
type
StorageSchema
=
Record
<`counter:${string}`, number> &
Record
<`flag:${string}`, boolean> &
Record
<`data:${string}`, {
value
: string;
timestamp
: number }>;
const
storage
=
inMemoryStorage
<
StorageSchema
>();
await
storage
.
set
("counter:views", 42);
await
storage
.
set
("flag:enabled", true);
await
storage
.
set
("data:config", {
value
: "test",
timestamp
:
Date
.
now
() });
const
views
= await
storage
.
get
("counter:views"); // number | undefined

Эта типобезопасность работает во всех адаптерах хранилищ (в памяти, Redis, Cloudflare KV и т.д.) и помогает предотвратить ошибки во время выполнения, выявляя несоответствия типов на этапе компиляции.

Список

В памяти

npmnpm downloadsJSRJSR Score

Установка
bash
npm install @gramio/storage
bash
yarn add @gramio/storage
bash
pnpm add @gramio/storage
bash
bun install @gramio/storage
Использование
  1. С использованием стандартного Map
ts
import { 
inMemoryStorage
} from "@gramio/storage";
const
storage
=
inMemoryStorage
();
  1. Предоставление своего собственного Map
ts
import { 
inMemoryStorage
, type
InMemoryStorageMap
} from "@gramio/storage";
const
map
:
InMemoryStorageMap
= new
Map
();
const
storage
=
inMemoryStorage
(
map
);

Redis

npmnpm downloadsJSRJSR Score

Установка
bash
npm install @gramio/storage-redis
bash
yarn add @gramio/storage-redis
bash
pnpm add @gramio/storage-redis
bash
bun install @gramio/storage-redis
Использование
  1. Предоставление параметров ioredis для функции redisStorage
ts
import { 
redisStorage
} from "@gramio/storage-redis";
const
storage
=
redisStorage
({
host
:
process
.
env
.
REDIS_HOST
,
});
  1. Предоставление экземпляра ioredis для функции redisStorage
ts
import { 
redisStorage
} from "@gramio/storage-redis";
import {
Redis
} from "ioredis";
const
redis
= new
Redis
({
host
:
process
.
env
.
REDIS_HOST
,
}); const
storage
=
redisStorage
(
redis
);
Советы
  • Вы можете установить переменную окружения DEBUG в ioredis:* для вывода отладочной информации:
bash
DEBUG=ioredis:* npm run start

и это будет выглядеть так:

bash
  ioredis:redis write command[::1:6379]: 0 -> get([ '@gramio/scenes:617580375' ]) +187ms
  ioredis:redis write command[::1:6379]: 0 -> set([ '@gramio/scenes:617580375', '{"name":"scene-name","state":{},"stepId":0,"previousStepId":0,"firstTime":false}' ]) +1ms
  • Для проверки того, какие данные хранятся в Redis, мы рекомендуем использовать графические клиенты, такие как AnotherRedisDesktopManager.
AnotherRedisDesktopManager

Cloudflare KV

npmnpm downloadsJSRJSR Score

Установка
bash
npm install @gramio/storage-cloudflare
bash
yarn add @gramio/storage-cloudflare
bash
pnpm add @gramio/storage-cloudflare
bash
bun install @gramio/storage-cloudflare
Использование
  1. Настройте пространство имен Cloudflare KV

  2. Предоставьте пространство имен Cloudflare KV функции cloudflareStorage

ts
import { cloudflareStorage } from "@gramio/storage-cloudflare";

const storage = cloudflareStorage(Env.CLOUDFLARE_KV_NAMESPACE);
const username: string | undefined
const user: {
    name: string;
    age: number;
} | undefined
const session: {
    token: string;
    expires: number;
} | undefined
const views: number | undefined