@ebowwa/mcp-telegram 0.1.4

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/auth-verify.ts ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Telegram Authentication Script (Non-interactive)
4
+ *
5
+ * Usage:
6
+ * Step 1 - Request code:
7
+ * doppler run --project seed --config prd -- bun run auth-verify.ts +1234567890
8
+ *
9
+ * Step 2 - Verify with code:
10
+ * doppler run --project seed --config prd -- bun run auth-verify.ts +1234567890 12345
11
+ *
12
+ * Step 3 - With 2FA password:
13
+ * doppler run --project seed --config prd -- bun run auth-verify.ts +1234567890 12345 "mypassword"
14
+ */
15
+
16
+ import { TelegramClient, Api } from "telegram";
17
+ import { StringSession } from "telegram/sessions";
18
+ import { homedir } from "os";
19
+ import { join } from "path";
20
+ import { mkdirSync, existsSync, writeFileSync, readFileSync } from "fs";
21
+
22
+ const SESSION_DIR = join(homedir(), ".telegram-mcp");
23
+ const SESSION_FILE = join(SESSION_DIR, "session.txt");
24
+ const PHONE_CODE_HASH_FILE = join(SESSION_DIR, "phone_code_hash.txt");
25
+
26
+ // Ensure session directory exists
27
+ if (!existsSync(SESSION_DIR)) {
28
+ mkdirSync(SESSION_DIR, { recursive: true });
29
+ }
30
+
31
+ async function main() {
32
+ const apiId = parseInt(process.env.TELEGRAM_API_ID || "0");
33
+ const apiHash = process.env.TELEGRAM_API_HASH;
34
+
35
+ if (!apiId || !apiHash) {
36
+ console.error("ERROR: TELEGRAM_API_ID and TELEGRAM_API_HASH must be set");
37
+ console.error("Run with: doppler run --project seed --config prd -- bun run auth-verify.ts ...");
38
+ process.exit(1);
39
+ }
40
+
41
+ const phoneNumber = process.argv[2];
42
+ const code = process.argv[3];
43
+ const password = process.argv[4] || "";
44
+
45
+ if (!phoneNumber) {
46
+ console.error("Usage: bun run auth-verify.ts <phone> [code] [password]");
47
+ console.error(" phone: Phone number with country code (e.g., +1234567890)");
48
+ console.error(" code: Verification code (optional, for step 2)");
49
+ console.error(" password: 2FA password (optional)");
50
+ process.exit(1);
51
+ }
52
+
53
+ // Check for existing session
54
+ if (existsSync(SESSION_FILE)) {
55
+ const existingSession = readFileSync(SESSION_FILE, "utf-8").trim();
56
+ if (existingSession && !code) {
57
+ console.log("Found existing session, testing connection...");
58
+ const session = new StringSession(existingSession);
59
+ const client = new TelegramClient(session, apiId, apiHash, {
60
+ connectionRetries: 5,
61
+ });
62
+
63
+ try {
64
+ await client.connect();
65
+ if (await client.checkAuthorization()) {
66
+ const me = await client.getMe();
67
+ console.log("\nāœ… Already authenticated as:", me.firstName, me.lastName || "");
68
+ console.log("šŸ“ž Phone:", me.phone);
69
+ await client.disconnect();
70
+ process.exit(0);
71
+ }
72
+ } catch (e) {
73
+ console.log("Existing session invalid, re-authenticating...");
74
+ }
75
+ }
76
+ }
77
+
78
+ const session = new StringSession("");
79
+ const client = new TelegramClient(session, apiId, apiHash, {
80
+ connectionRetries: 5,
81
+ });
82
+
83
+ await client.connect();
84
+
85
+ if (!code) {
86
+ // Step 1: Send verification code
87
+ console.log(`\nšŸ“± Sending verification code to ${phoneNumber}...`);
88
+
89
+ try {
90
+ const result = await client.invoke(
91
+ new Api.auth.SendCode({
92
+ phoneNumber: phoneNumber,
93
+ apiId: apiId,
94
+ apiHash: apiHash,
95
+ settings: new Api.CodeSettings({}),
96
+ })
97
+ );
98
+
99
+ // Save phone_code_hash for step 2
100
+ writeFileSync(PHONE_CODE_HASH_FILE, (result as any).phoneCodeHash, "utf-8");
101
+
102
+ console.log("\nāœ… Verification code sent!");
103
+ console.log("Check your Telegram app for the code.");
104
+ console.log(`\nNext step: Run this command with the code:`);
105
+ console.log(` doppler run --project seed --config prd -- bun run auth-verify.ts ${phoneNumber} <CODE>`);
106
+ } catch (e: any) {
107
+ console.error("\nāŒ Error sending code:", e.message);
108
+ }
109
+ } else {
110
+ // Step 2: Sign in with code
111
+ console.log(`\nšŸ” Signing in with code: ${code}...`);
112
+
113
+ let phoneCodeHash = "";
114
+ if (existsSync(PHONE_CODE_HASH_FILE)) {
115
+ phoneCodeHash = readFileSync(PHONE_CODE_HASH_FILE, "utf-8").trim();
116
+ }
117
+
118
+ if (!phoneCodeHash) {
119
+ console.error("āŒ No phone_code_hash found. Run step 1 first (without code).");
120
+ process.exit(1);
121
+ }
122
+
123
+ try {
124
+ let result: any;
125
+
126
+ try {
127
+ result = await client.invoke(
128
+ new Api.auth.SignIn({
129
+ phoneNumber: phoneNumber,
130
+ phoneCodeHash: phoneCodeHash,
131
+ phoneCode: code,
132
+ })
133
+ );
134
+ } catch (e: any) {
135
+ if (e.message?.includes("SESSION_PASSWORD_NEEDED") || password) {
136
+ // 2FA required
137
+ if (!password) {
138
+ console.log("\nāš ļø 2FA is enabled on this account.");
139
+ console.log("Please provide your 2FA password:");
140
+ console.log(` doppler run --project seed --config prd -- bun run auth-verify.ts ${phoneNumber} ${code} "YOUR_PASSWORD"`);
141
+ process.exit(1);
142
+ }
143
+ // Get password info and sign in
144
+ const passwordInfo = await client.invoke(new Api.account.GetPassword({}));
145
+ result = await client.invoke(
146
+ new Api.auth.CheckPassword({
147
+ password: await client.computeCheck(passwordInfo as any, password),
148
+ })
149
+ );
150
+ } else {
151
+ throw e;
152
+ }
153
+ }
154
+
155
+ // Save session
156
+ const sessionString = client.session.save() as unknown as string;
157
+ writeFileSync(SESSION_FILE, sessionString, "utf-8");
158
+
159
+ console.log("\nāœ… Successfully authenticated!");
160
+ console.log(`šŸ“ Session saved to: ${SESSION_FILE}`);
161
+
162
+ // Get user info
163
+ const me = await client.getMe();
164
+ console.log(`šŸ‘¤ Logged in as: ${me.firstName} ${me.lastName || ""}`);
165
+ console.log(`šŸ“ž Phone: ${me.phone}`);
166
+ console.log(`šŸ‘¤ Username: @${me.username || "N/A"}`);
167
+
168
+ } catch (e: any) {
169
+ console.error("\nāŒ Sign in error:", e.message);
170
+ }
171
+ }
172
+
173
+ await client.disconnect();
174
+ process.exit(0);
175
+ }
176
+
177
+ main().catch((err) => {
178
+ console.error("Fatal error:", err);
179
+ process.exit(1);
180
+ });
package/auth.js ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env bun
2
+ "use strict";
3
+ /**
4
+ * Telegram Authentication Script
5
+ *
6
+ * Run this once to authenticate and generate a session string.
7
+ * The session will be saved to ~/.telegram-mcp/session.txt
8
+ *
9
+ * Usage:
10
+ * bun run auth.ts
11
+ *
12
+ * Environment variables (from Doppler):
13
+ * TELEGRAM_API_ID - Your Telegram API ID
14
+ * TELEGRAM_API_HASH - Your Telegram API Hash
15
+ */
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
27
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ var telegram_1 = require("telegram");
54
+ var sessions_1 = require("telegram/sessions");
55
+ var readline_1 = require("readline");
56
+ var os_1 = require("os");
57
+ var path_1 = require("path");
58
+ var fs_1 = require("fs");
59
+ var SESSION_DIR = (0, path_1.join)((0, os_1.homedir)(), ".telegram-mcp");
60
+ var SESSION_FILE = (0, path_1.join)(SESSION_DIR, "session.txt");
61
+ // Ensure session directory exists
62
+ if (!(0, fs_1.existsSync)(SESSION_DIR)) {
63
+ (0, fs_1.mkdirSync)(SESSION_DIR, { recursive: true });
64
+ }
65
+ var rl = readline_1.default.createInterface({
66
+ input: process.stdin,
67
+ output: process.stdout,
68
+ });
69
+ var question = function (prompt) {
70
+ return new Promise(function (resolve) {
71
+ rl.question(prompt, resolve);
72
+ });
73
+ };
74
+ function main() {
75
+ return __awaiter(this, void 0, void 0, function () {
76
+ var apiId, apiHash, session, client, sessionString;
77
+ var _this = this;
78
+ return __generator(this, function (_a) {
79
+ switch (_a.label) {
80
+ case 0:
81
+ apiId = parseInt(process.env.TELEGRAM_API_ID || "0");
82
+ apiHash = process.env.TELEGRAM_API_HASH;
83
+ if (!apiId || !apiHash) {
84
+ console.error("ERROR: TELEGRAM_API_ID and TELEGRAM_API_HASH must be set");
85
+ console.error("Run with: doppler run --project seed --config prd -- bun run auth.ts");
86
+ process.exit(1);
87
+ }
88
+ console.log("\nšŸ“± Telegram Authentication\n");
89
+ console.log("This will authenticate your Telegram account and save a session.");
90
+ console.log("You'll receive a verification code via Telegram.\n");
91
+ session = new sessions_1.StringSession("");
92
+ client = new telegram_1.TelegramClient(session, apiId, apiHash, {
93
+ connectionRetries: 5,
94
+ });
95
+ return [4 /*yield*/, client.start({
96
+ phoneNumber: function () { return __awaiter(_this, void 0, void 0, function () {
97
+ var phone;
98
+ return __generator(this, function (_a) {
99
+ switch (_a.label) {
100
+ case 0: return [4 /*yield*/, question("Enter your phone number (with country code, e.g., +1234567890): ")];
101
+ case 1:
102
+ phone = _a.sent();
103
+ return [2 /*return*/, phone];
104
+ }
105
+ });
106
+ }); },
107
+ password: function () { return __awaiter(_this, void 0, void 0, function () {
108
+ var password;
109
+ return __generator(this, function (_a) {
110
+ switch (_a.label) {
111
+ case 0: return [4 /*yield*/, question("Enter your 2FA password (if enabled, press Enter to skip): ")];
112
+ case 1:
113
+ password = _a.sent();
114
+ return [2 /*return*/, password || ""];
115
+ }
116
+ });
117
+ }); },
118
+ phoneCode: function () { return __awaiter(_this, void 0, void 0, function () {
119
+ var code;
120
+ return __generator(this, function (_a) {
121
+ switch (_a.label) {
122
+ case 0: return [4 /*yield*/, question("Enter the verification code you received: ")];
123
+ case 1:
124
+ code = _a.sent();
125
+ return [2 /*return*/, code];
126
+ }
127
+ });
128
+ }); },
129
+ onError: function (err) {
130
+ console.error("Auth error:", err);
131
+ },
132
+ })];
133
+ case 1:
134
+ _a.sent();
135
+ rl.close();
136
+ sessionString = client.session.save();
137
+ (0, fs_1.writeFileSync)(SESSION_FILE, sessionString, "utf-8");
138
+ console.log("\nāœ… Successfully authenticated!");
139
+ console.log("\uD83D\uDCC1 Session saved to: ".concat(SESSION_FILE));
140
+ console.log("\uD83D\uDD11 Session string (backup): ".concat(sessionString.substring(0, 50), "..."));
141
+ console.log("\nYou can now use the Telegram MCP server.");
142
+ return [4 /*yield*/, client.disconnect()];
143
+ case 2:
144
+ _a.sent();
145
+ process.exit(0);
146
+ return [2 /*return*/];
147
+ }
148
+ });
149
+ });
150
+ }
151
+ main().catch(function (err) {
152
+ console.error("Fatal error:", err);
153
+ process.exit(1);
154
+ });
package/auth.ts ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Telegram Authentication Script
4
+ *
5
+ * Run this once to authenticate and generate a session string.
6
+ * The session will be saved to ~/.telegram-mcp/session.txt
7
+ *
8
+ * Usage:
9
+ * bun run auth.ts
10
+ *
11
+ * Environment variables (from Doppler):
12
+ * TELEGRAM_API_ID - Your Telegram API ID
13
+ * TELEGRAM_API_HASH - Your Telegram API Hash
14
+ */
15
+
16
+ import { TelegramClient } from "telegram";
17
+ import { StringSession } from "telegram/sessions";
18
+ import readline from "readline";
19
+ import { homedir } from "os";
20
+ import { join } from "path";
21
+ import { mkdirSync, existsSync, writeFileSync } from "fs";
22
+
23
+ const SESSION_DIR = join(homedir(), ".telegram-mcp");
24
+ const SESSION_FILE = join(SESSION_DIR, "session.txt");
25
+
26
+ // Ensure session directory exists
27
+ if (!existsSync(SESSION_DIR)) {
28
+ mkdirSync(SESSION_DIR, { recursive: true });
29
+ }
30
+
31
+ const rl = readline.createInterface({
32
+ input: process.stdin,
33
+ output: process.stdout,
34
+ });
35
+
36
+ const question = (prompt: string): Promise<string> => {
37
+ return new Promise((resolve) => {
38
+ rl.question(prompt, resolve);
39
+ });
40
+ };
41
+
42
+ async function main() {
43
+ const apiId = parseInt(process.env.TELEGRAM_API_ID || "0");
44
+ const apiHash = process.env.TELEGRAM_API_HASH;
45
+
46
+ if (!apiId || !apiHash) {
47
+ console.error("ERROR: TELEGRAM_API_ID and TELEGRAM_API_HASH must be set");
48
+ console.error("Run with: doppler run --project seed --config prd -- bun run auth.ts");
49
+ process.exit(1);
50
+ }
51
+
52
+ console.log("\nšŸ“± Telegram Authentication\n");
53
+ console.log("This will authenticate your Telegram account and save a session.");
54
+ console.log("You'll receive a verification code via Telegram.\n");
55
+
56
+ const session = new StringSession("");
57
+
58
+ const client = new TelegramClient(session, apiId, apiHash, {
59
+ connectionRetries: 5,
60
+ });
61
+
62
+ await client.start({
63
+ phoneNumber: async () => {
64
+ const phone = await question("Enter your phone number (with country code, e.g., +1234567890): ");
65
+ return phone;
66
+ },
67
+ password: async () => {
68
+ const password = await question("Enter your 2FA password (if enabled, press Enter to skip): ");
69
+ return password || "";
70
+ },
71
+ phoneCode: async () => {
72
+ const code = await question("Enter the verification code you received: ");
73
+ return code;
74
+ },
75
+ onError: (err) => {
76
+ console.error("Auth error:", err);
77
+ },
78
+ });
79
+
80
+ rl.close();
81
+
82
+ // Save session
83
+ const sessionString = client.session.save() as unknown as string;
84
+ writeFileSync(SESSION_FILE, sessionString, "utf-8");
85
+
86
+ console.log("\nāœ… Successfully authenticated!");
87
+ console.log(`šŸ“ Session saved to: ${SESSION_FILE}`);
88
+ console.log(`šŸ”‘ Session string (backup): ${sessionString.substring(0, 50)}...`);
89
+ console.log("\nYou can now use the Telegram MCP server.");
90
+
91
+ await client.disconnect();
92
+ process.exit(0);
93
+ }
94
+
95
+ main().catch((err) => {
96
+ console.error("Fatal error:", err);
97
+ process.exit(1);
98
+ });