@imessaging/core 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.ts +4 -1
- package/src/peer-key.ts +7 -1
- package/src/types.ts +60 -1
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { MemoryPeerStore } from "./memory-peer-store";
|
|
2
2
|
export { createPeerKey } from "./peer-key";
|
|
3
|
-
export { canEdit } from "./types";
|
|
3
|
+
export { canEdit, isTelegramRecipient } from "./types";
|
|
4
|
+
export type { ButtonPress, ButtonPressTransport } from "./types";
|
|
4
5
|
export type {
|
|
5
6
|
EditableMessage,
|
|
6
7
|
EditableMessageTransport,
|
|
7
8
|
EditResult,
|
|
9
|
+
EmailRecipient,
|
|
8
10
|
MessageRecipient,
|
|
9
11
|
MessageTransport,
|
|
10
12
|
OutboundButton,
|
|
@@ -13,5 +15,6 @@ export type {
|
|
|
13
15
|
ResolvedPeer,
|
|
14
16
|
SendResult,
|
|
15
17
|
TelegramPeerStore,
|
|
18
|
+
TelegramRecipient,
|
|
16
19
|
TransportStatus,
|
|
17
20
|
} from "./types";
|
package/src/peer-key.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { isTelegramRecipient, type MessageRecipient } from "./types";
|
|
2
2
|
|
|
3
3
|
function normalizeUsername(username: string): string {
|
|
4
4
|
return username.trim().replace(/^@/, "").toLowerCase();
|
|
@@ -10,6 +10,12 @@ export function createPeerKey(accountId: string, recipient: MessageRecipient): s
|
|
|
10
10
|
throw new Error("accountId must not be empty");
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// Кеш пиров — телеграмный. Адрес почты сюда не кладут: ключ вида `telegram-peer:…:email:…`
|
|
14
|
+
// выглядел бы настоящим и молча жил бы в хранилище, ничего не адресуя.
|
|
15
|
+
if (!isTelegramRecipient(recipient)) {
|
|
16
|
+
throw new Error("peer key is Telegram-only and cannot be built for an email recipient");
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
if (recipient.type === "username") {
|
|
14
20
|
const username = normalizeUsername(recipient.username);
|
|
15
21
|
if (!username) {
|
package/src/types.ts
CHANGED
|
@@ -9,7 +9,36 @@ export type TelegramIdRecipient = {
|
|
|
9
9
|
username?: string;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Получатель письма.
|
|
14
|
+
*
|
|
15
|
+
* Адрес — самостоятельный вид получателя, а не telegram-имя с собачкой. Соблазн подставить почту
|
|
16
|
+
* в `UsernameRecipient` велик (поле тоже строковое), но тогда `createPeerKey` завёл бы для письма
|
|
17
|
+
* ключ telegram-пира, а mtproto-транспорт попытался бы разрешить адрес как @username и упал бы с
|
|
18
|
+
* сообщением про Telegram. Отдельный вариант заставляет каждый транспорт сказать вслух, работает
|
|
19
|
+
* он с этим получателем или нет.
|
|
20
|
+
*/
|
|
21
|
+
export type EmailRecipient = {
|
|
22
|
+
type: "email";
|
|
23
|
+
address: string;
|
|
24
|
+
/** Отображаемое имя: `Имя <адрес>`. Необязательно — без него уходит голый адрес. */
|
|
25
|
+
name?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type MessageRecipient = UsernameRecipient | TelegramIdRecipient | EmailRecipient;
|
|
29
|
+
|
|
30
|
+
/** Получатель, адресуемый в Telegram. Сужение для транспортов, которые кроме него ничего не умеют. */
|
|
31
|
+
export type TelegramRecipient = UsernameRecipient | TelegramIdRecipient;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Телеграмный ли это получатель.
|
|
35
|
+
*
|
|
36
|
+
* Нужен транспортам как ЕДИНСТВЕННАЯ точка отказа от чужого канала: без него проверка расползётся
|
|
37
|
+
* по местам использования `recipient.id` и в каждом будет своей.
|
|
38
|
+
*/
|
|
39
|
+
export function isTelegramRecipient(recipient: MessageRecipient): recipient is TelegramRecipient {
|
|
40
|
+
return recipient.type !== "email";
|
|
41
|
+
}
|
|
13
42
|
|
|
14
43
|
export type OutboundDocument = {
|
|
15
44
|
data: Uint8Array;
|
|
@@ -113,3 +142,33 @@ export interface TelegramPeerStore {
|
|
|
113
142
|
): Promise<void>;
|
|
114
143
|
delete(accountId: string, recipient: MessageRecipient): Promise<void>;
|
|
115
144
|
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Нажатие на кнопку под сообщением.
|
|
148
|
+
*
|
|
149
|
+
* `data` — то, что положили в `OutboundButton.callbackData`. Транспорт не пытается его понимать:
|
|
150
|
+
* смысл строки принадлежит продукту, а не каналу связи.
|
|
151
|
+
*/
|
|
152
|
+
export type ButtonPress = {
|
|
153
|
+
/** Кто нажал. `null` — отправитель неизвестен каналу. */
|
|
154
|
+
senderId: number | null;
|
|
155
|
+
data: string;
|
|
156
|
+
/**
|
|
157
|
+
* Подтвердить нажатие, показав человеку текст.
|
|
158
|
+
*
|
|
159
|
+
* Вызывать ОБЯЗАТЕЛЬНО: Telegram крутит на кнопке часы, пока не получит ответ, и человек видит
|
|
160
|
+
* зависшую кнопку даже при успешно выполненном действии.
|
|
161
|
+
*/
|
|
162
|
+
answer(text: string): Promise<void>;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Канал, умеющий не только слать, но и ПРИНИМАТЬ нажатия.
|
|
167
|
+
*
|
|
168
|
+
* Отдельно от `MessageTransport`, потому что умеют не все: почта кнопок не имеет вовсе, а
|
|
169
|
+
* реализация, которая только шлёт, не должна объяснять, почему у неё пустой приём.
|
|
170
|
+
*/
|
|
171
|
+
export interface ButtonPressTransport {
|
|
172
|
+
/** Подписаться на нажатия. Возврат — функция отписки. */
|
|
173
|
+
onButtonPress(handler: (press: ButtonPress) => void | Promise<void>): () => void;
|
|
174
|
+
}
|