supertelegram 0.3.1 → 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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  telegram cli for ai to read/write messages using gramjs.
4
4
 
5
+ > **warning:** don't use this to send spam or abuse the telegram api. your account can get banned.
6
+
5
7
  ## installation
6
8
 
7
9
  ```bash
@@ -30,9 +32,11 @@ that's it! now you're ready to use telegram from the cli.
30
32
  ### messages
31
33
 
32
34
  ```bash
33
- # send a message
35
+ # send a message — chat can be @username, a numeric id, or a name
34
36
  telegram send @username "hello there"
35
- telegram send "me" "note to self" # use "me" for saved messages
37
+ telegram send 7069934904 "hey" # by id (for chats with no username)
38
+ telegram send "Ben YC" "hello" # by name (partial, case-insensitive)
39
+ telegram send "me" "note to self" # use "me" for saved messages
36
40
 
37
41
  # read messages (shows [photo], [video], [file] indicators)
38
42
  telegram read @username 10
@@ -43,7 +47,7 @@ telegram reply "John" "hey back!"
43
47
  # get unread messages (json output with media info)
44
48
  telegram unread 20
45
49
 
46
- # list dialogs
50
+ # list dialogs (shows @username and [id: ...] for each chat)
47
51
  telegram dialogs 10
48
52
  ```
49
53
 
@@ -99,8 +103,8 @@ telegram send @friend "hey" --session ./custom.txt
99
103
 
100
104
  clone repo and install:
101
105
  ```bash
102
- git clone https://github.com/caffeinum/telegram-cli.git
103
- cd telegram-cli
106
+ git clone https://github.com/caffeinum/supertelegram.git
107
+ cd supertelegram
104
108
  bun install
105
109
  ```
106
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supertelegram",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "telegram cli for humans and bots",
5
5
  "module": "index.ts",
6
6
  "type": "module",
@@ -71,8 +71,16 @@ export async function dialogs(limit = 10) {
71
71
 
72
72
  const dialogList = await getDialogs(limit);
73
73
  for (const dialog of dialogList) {
74
- console.log(`- ${dialog.title}`);
75
- }
74
+ const entity = dialog.entity;
75
+ const username =
76
+ entity && "username" in entity && entity.username
77
+ ? ` @${entity.username}`
78
+ : "";
79
+ const id = dialog.id?.toString() ?? entity?.id?.toString() ?? "?";
80
+ const unread = dialog.unreadCount > 0 ? ` (${dialog.unreadCount} unread)` : "";
81
+ console.log(`- ${dialog.title}${username} [id: ${id}]${unread}`);
82
+ }
83
+ console.log("\nsend with: telegram send <@username|id> \"your message\"");
76
84
  await disconnect();
77
85
  }
78
86
 
package/src/cli/run.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env bun
2
2
  import { send, read, dialogs, unread, reply, login, config, sendFile, downloadMedia } from "./commands";
3
3
  import { setVerbose, setSessionPath } from "../client/telegram";
4
+ import pkg from "../../package.json";
4
5
 
5
- const VERSION = "0.1.0";
6
+ const VERSION = pkg.version;
6
7
  const NAME = "telegram";
7
8
 
8
9
  const HELP = `
@@ -12,7 +13,7 @@ usage:
12
13
  ${NAME} <command> [options]
13
14
 
14
15
  commands:
15
- send <chat> <message> send a message to a chat
16
+ send <chat> <message> send a message (chat = @username, id, or name)
16
17
  send-file <chat> <path> send a file/image/video (optional: caption)
17
18
  read <chat> [limit] read messages from a chat (default: 10)
18
19
  download <chat> <id> [out] download media from message id
@@ -76,12 +76,60 @@ export async function login(callbacks: {
76
76
  console.log("session saved!");
77
77
  }
78
78
 
79
+ // a chat can be addressed by @username, "me", phone (+123), t.me link,
80
+ // or a numeric id copied from `telegram dialogs`. usernames/links resolve
81
+ // natively; numeric ids and bare names need the dialog entity cache, so we
82
+ // look them up here.
83
+ export async function resolveEntity(
84
+ identifier: string
85
+ ): Promise<string | Api.TypeEntityLike> {
86
+ const c = await getClient();
87
+ const id = identifier.trim();
88
+
89
+ // things gramjs resolves on its own
90
+ if (
91
+ id === "me" ||
92
+ id.startsWith("@") ||
93
+ id.startsWith("+") ||
94
+ id.startsWith("http")
95
+ ) {
96
+ return id;
97
+ }
98
+
99
+ // numeric id (users positive, chats/channels may be negative)
100
+ if (/^-?\d+$/.test(id)) {
101
+ try {
102
+ // fast path: entity already in the session cache
103
+ return await c.getInputEntity(id);
104
+ } catch {
105
+ // slow path: fetch dialogs to populate + match the entity
106
+ const match = (await c.getDialogs({ limit: 200 })).find(
107
+ (d) => d.id?.toString() === id || d.entity?.id?.toString() === id
108
+ );
109
+ if (match?.entity) return match.entity;
110
+ throw new Error(
111
+ `chat with id ${id} not found in your dialogs. run: telegram dialogs 200`
112
+ );
113
+ }
114
+ }
115
+
116
+ // bare name: partial, case-insensitive match against dialog titles
117
+ const match = (await c.getDialogs({ limit: 200 })).find((d) =>
118
+ d.title?.toLowerCase().includes(id.toLowerCase())
119
+ );
120
+ if (match?.entity) return match.entity;
121
+
122
+ // let gramjs take a final shot (e.g. a username without the @)
123
+ return id;
124
+ }
125
+
79
126
  export async function sendMessage(
80
127
  username: string,
81
128
  message: string
82
129
  ): Promise<Api.Message> {
83
130
  const c = await getClient();
84
- return c.sendMessage(username, { message });
131
+ const entity = await resolveEntity(username);
132
+ return c.sendMessage(entity, { message });
85
133
  }
86
134
 
87
135
  export async function sendFile(
@@ -90,7 +138,8 @@ export async function sendFile(
90
138
  caption?: string
91
139
  ): Promise<Api.Message> {
92
140
  const c = await getClient();
93
- return c.sendFile(username, {
141
+ const entity = await resolveEntity(username);
142
+ return c.sendFile(entity, {
94
143
  file: filePath,
95
144
  caption: caption,
96
145
  });
@@ -117,7 +166,8 @@ export async function getMessages(
117
166
  limit = 10
118
167
  ): Promise<Api.Message[]> {
119
168
  const c = await getClient();
120
- const messages = await c.getMessages(username, { limit });
169
+ const entity = await resolveEntity(username);
170
+ const messages = await c.getMessages(entity, { limit });
121
171
  return messages as Api.Message[];
122
172
  }
123
173
 
package/tsconfig.json CHANGED
@@ -11,6 +11,7 @@
11
11
  // Bundler mode
12
12
  "moduleResolution": "bundler",
13
13
  "allowImportingTsExtensions": true,
14
+ "resolveJsonModule": true,
14
15
  "verbatimModuleSyntax": true,
15
16
  "noEmit": true,
16
17