Open Argon007 opened 3 years ago
hmm, maybe i'm getting closer now. I've executed this:
function sendCode(phone) {
return api.call('auth.sendCode', {
phone_number: phone,
settings: {
_: 'codeSettings',
},
});
}
and got the code from Telegram. Next I want to execute this:
function signIn({ code, phone, phone_code_hash }) {
return api.call('auth.signIn', {
phone_code: code,
phone_number: phone,
phone_code_hash: phone_code_hash,
});
}
but I don't know what the "phone_code_hash" needs to be? I have the TG code and my phone number of course, but not the "phone_code_hash"...
hmm, maybe i'm getting closer now. I've executed this:
function sendCode(phone) { return api.call('auth.sendCode', { phone_number: phone, settings: { _: 'codeSettings', }, }); }
and got the code from Telegram. Next I want to execute this:
function signIn({ code, phone, phone_code_hash }) { return api.call('auth.signIn', { phone_code: code, phone_number: phone, phone_code_hash: phone_code_hash, }); }
but I don't know what the "phone_code_hash" needs to be? I have the TG code and my phone number of course, but not the "phone_code_hash"...
you will get the phone_code_hash
from the API call to your sendCode
method.
const res = await sendCode('9999XXXXXXX');
const phone_code_hash = res['phone_code_hash'];
Which you can use in the later API call. I hope that helps.
Sorry sir, I still have troubles authenticating against Telegram. Is there someone over here that can show me the exact way how they achieved it?
If I execute the script I receive the Telegram message with an unique code, but can't enter the code into the script since it's already running. So I need to stop the script, enter the "code" I received but I still get an error if I do it that way...
users.getFullUser error: {
_: 'mt_rpc_error',
error_code: 401,
error_message: 'AUTH_KEY_UNREGISTERED'
}
auth.signIn error: {
_: 'mt_rpc_error',
error_code: 401,
error_message: 'SESSION_PASSWORD_NEEDED'
}
Thanks again!
Hey, did you authenticated your app??
I can't... that's the problem :).
I'm adding my phone number to the script, the api_id and api_hash and run it. Once I run it I get the code from Telegram.
I stop the script and add the code into the script and run it again. Next I get are the errors described here above.
So I wonder how you did the authentication process. (friendly reminder, i'm fairly new to Node, so i'm not a daily coder ;-) )
Thanks!
No one that can help me?
This worked for me with my own phone number but it doesn't work with the test settings:
// main.js
const MTProto = require("@mtproto/core");
const prompt = require("prompt");
const API = require("./telegramApi");
const api = new API();
async function main() {
const user = await api.getUser();
console.log("User 1st try: ", user);
// const phone = "+99966XYYYY";
// const code = "XXXXX";
if (!user) {
const { phone } = await prompt.get("phone");
const { phone_code_hash } = await api.sendCode(phone);
const { code } = await prompt.get("code");
try {
const signInResult = await api.signIn({
code,
phone,
phone_code_hash,
});
console.log(signInResult);
if (signInResult._ === "auth.authorizationSignUpRequired") {
const singUpResult = await api.signUp({
phone,
phone_code_hash,
});
console.log(singUpResult);
}
const newUser = await api.getUser();
console.log("User 2nd try: ", newUser);
} catch (error) {
if (error.error_message !== "SESSION_PASSWORD_NEEDED") {
console.log(`error:`, error);
return;
}
// 2FA...
}
}
const result = await api.call("help.getNearestDc");
console.log(result);
process.exit(0);
}
main();
// api.js
const path = require("path");
const MTProto = require("@mtproto/core");
const { sleep } = require("@mtproto/core/src/utils/common");
class API {
constructor({ test } = { test: false }) {
this.mtproto = new MTProto({
api_id: "",
api_hash: "",
test,
storageOptions: {
path: path.resolve(__dirname, "./telegramData.json"),
},
});
}
async call(method, params, options = {}) {
console.log(method);
try {
const result = await this.mtproto.call(method, params, options);
console.log(result);
return result;
} catch (error) {
console.error(error);
const { error_code, error_message } = error;
if (error_code === 420) {
const seconds = Number(error_message.split("FLOOD_WAIT_")[1]);
const ms = seconds * 1000;
await sleep(ms);
return this.call(method, params, options);
}
if (error_code === 303) {
const [type, dcIdAsString] = error_message.split("_MIGRATE_");
const dcId = Number(dcIdAsString);
// If auth.sendCode call on incorrect DC need change default DC, because
// call auth.signIn on incorrect DC return PHONE_CODE_EXPIRED error
if (type === "PHONE") {
await this.mtproto.setDefaultDc(dcId);
} else {
Object.assign(options, { dcId });
}
return this.call(method, params, options);
}
return Promise.reject(error);
}
}
async getUser() {
try {
const user = await this.call("users.getFullUser", {
id: {
_: "inputUserSelf",
},
});
return user;
} catch (error) {
return null;
}
}
sendCode(phone) {
try {
return this.call("auth.sendCode", {
phone_number: phone,
settings: {
_: "codeSettings",
},
});
} catch (error) {
throw error;
}
}
signIn({ code, phone, phone_code_hash }) {
return this.call("auth.signIn", {
phone_code: code,
phone_number: phone,
phone_code_hash: phone_code_hash,
});
}
signUp({ phone, phone_code_hash }) {
return this.call("auth.signUp", {
phone_number: phone,
phone_code_hash: phone_code_hash,
first_name: "MTProto",
last_name: "Core",
});
}
getPassword() {
return this.call("account.getPassword");
}
checkPassword({ srp_id, A, M1 }) {
return this.call("auth.checkPassword", {
password: {
_: "inputCheckPasswordSRP",
srp_id,
A,
M1,
},
});
}
}
module.exports = API;
Install the prompt
library, so you can type in your phone and code:
npm i prompt
I didn't use the 2FA section, so you need to add that yourself.
@andrewszucs what error do you get with test number? I was having problems because docs says that verification code are 5 digits but in fact It was 6 to get my testing number work
@andrewszucs what erro u get with test number? I was having problems because docs says that verification code are 5 digits but in fact It was 6 to get my testing number work
That was my problem too. Thanks a lot @allandiego ! It works now. 🙌
This worked for me with my own phone number but it doesn't work with the test settings:
Install the
prompt
library, so you can type in your phone and code:npm i prompt
I didn't use the 2FA section, so you need to add that yourself.
Hi, I got this error now:
internal/modules/cjs/loader.js:883 throw err; ^
Error: Cannot find module './telegramApi'
Which dependency is this?
Thanks!
This worked for me with my own phone number but it doesn't work with the test settings:
// main.js const MTProto = require("@mtproto/core"); const prompt = require("prompt"); const API = require("./telegramApi"); const api = new API(); async function main() { const user = await api.getUser(); console.log("User 1st try: ", user); // const phone = "+99966XYYYY"; // const code = "XXXXX"; if (!user) { const { phone } = await prompt.get("phone"); const { phone_code_hash } = await api.sendCode(phone); const { code } = await prompt.get("code"); try { const signInResult = await api.signIn({ code, phone, phone_code_hash, }); console.log(signInResult); if (signInResult._ === "auth.authorizationSignUpRequired") { const singUpResult = await api.signUp({ phone, phone_code_hash, }); console.log(singUpResult); } const newUser = await api.getUser(); console.log("User 2nd try: ", newUser); } catch (error) { if (error.error_message !== "SESSION_PASSWORD_NEEDED") { console.log(`error:`, error); return; } // 2FA... } } const result = await api.call("help.getNearestDc"); console.log(result); process.exit(0); } main();
// api.js const path = require("path"); const MTProto = require("@mtproto/core"); const { sleep } = require("@mtproto/core/src/utils/common"); class API { constructor({ test } = { test: false }) { this.mtproto = new MTProto({ api_id: "", api_hash: "", test, storageOptions: { path: path.resolve(__dirname, "./telegramData.json"), }, }); } async call(method, params, options = {}) { console.log(method); try { const result = await this.mtproto.call(method, params, options); console.log(result); return result; } catch (error) { console.error(error); const { error_code, error_message } = error; if (error_code === 420) { const seconds = Number(error_message.split("FLOOD_WAIT_")[1]); const ms = seconds * 1000; await sleep(ms); return this.call(method, params, options); } if (error_code === 303) { const [type, dcIdAsString] = error_message.split("_MIGRATE_"); const dcId = Number(dcIdAsString); // If auth.sendCode call on incorrect DC need change default DC, because // call auth.signIn on incorrect DC return PHONE_CODE_EXPIRED error if (type === "PHONE") { await this.mtproto.setDefaultDc(dcId); } else { Object.assign(options, { dcId }); } return this.call(method, params, options); } return Promise.reject(error); } } async getUser() { try { const user = await this.call("users.getFullUser", { id: { _: "inputUserSelf", }, }); return user; } catch (error) { return null; } } sendCode(phone) { try { return this.call("auth.sendCode", { phone_number: phone, settings: { _: "codeSettings", }, }); } catch (error) { throw error; } } signIn({ code, phone, phone_code_hash }) { return this.call("auth.signIn", { phone_code: code, phone_number: phone, phone_code_hash: phone_code_hash, }); } signUp({ phone, phone_code_hash }) { return this.call("auth.signUp", { phone_number: phone, phone_code_hash: phone_code_hash, first_name: "MTProto", last_name: "Core", }); } getPassword() { return this.call("account.getPassword"); } checkPassword({ srp_id, A, M1 }) { return this.call("auth.checkPassword", { password: { _: "inputCheckPasswordSRP", srp_id, A, M1, }, }); } } module.exports = API;
Install the
prompt
library, so you can type in your phone and code:npm i prompt
I didn't use the 2FA section, so you need to add that yourself.
Adding a prompt for the SMS verification works. This should really be added to the docs here.
@alik0211 Can we add this please to the docs? I'm willing to help.
Does anyone else have an issue with the phone code? I have to keep entering the phone code every time I start node. The data JSON file is being written to, but it does looks like it is being read on start
Finally, deal with it. Official docs btw are better than all this code above. Thank you @alik0211 !
*** HOW TO LOGIN:
node auth.js
// API.js
/* eslint-disable no-undef */
const path = require("path");
const MTProto = require("@mtproto/core");
const { sleep } = require("@mtproto/core/src/utils/common");
class API {
constructor() {
this.mtproto = new MTProto({
// lucky
api_id: api_id,
api_hash: api_hash,
storageOptions: {
path: path.resolve(__dirname, "./1.json"),
},
});
}
async call(method, params, options = {}) {
try {
const result = await this.mtproto.call(method, params, options);
return result;
} catch (error) {
console.log(`${method} error:`, error);
const { error_code, error_message } = error;
if (error_code === 420) {
const seconds = Number(error_message.split("FLOOD_WAIT_")[1]);
const ms = seconds * 1000;
await sleep(ms);
return this.call(method, params, options);
}
if (error_code === 303) {
const [type, dcIdAsString] = error_message.split("_MIGRATE_");
const dcId = Number(dcIdAsString);
// If auth.sendCode call on incorrect DC need change default DC, because
// call auth.signIn on incorrect DC return PHONE_CODE_EXPIRED error
if (type === "PHONE") {
await this.mtproto.setDefaultDc(dcId);
} else {
Object.assign(options, { dcId });
}
return this.call(method, params, options);
}
return Promise.reject(error);
}
}
}
const api = new API();
module.exports = api;
auth.js
// AUTH.js
/* eslint-disable no-undef */
const api = require("./api-origin");
const prompt = require("prompt");
const { sendMessage } = require("./updates");
async function getUser() {
try {
const user = await api.call("users.getFullUser", {
id: {
_: "inputUserSelf",
},
});
return user;
} catch (error) {
return null;
}
}
function signIn({ code, phone, phone_code_hash }) {
return api
.call("auth.signIn", {
phone_code: code,
phone_number: phone,
phone_code_hash: phone_code_hash,
})
.then((v) => {
console.log("LOGIN SUCCESS: ", v);
sendMessage();
})
.catch((e) => console.log("LOGIN FAIL: ", e));
}
function sendCode(phone) {
return api.call("auth.sendCode", {
phone_number: phone,
settings: {
_: "codeSettings",
},
});
}
(async () => {
const user = await getUser();
// const phone = "+9XXXXXXXXXX";
if (!user) {
const { phone } = await prompt.get("phone");
const { phone_code_hash } = await sendCode(phone);
const { code } = await prompt.get("code");
try {
const signInResult = await signIn({
code,
phone,
phone_code_hash,
});
if (signInResult._ === "auth.authorizationSignUpRequired") {
await signUp({
phone,
phone_code_hash,
});
}
} catch (error) {
if (error.error_message !== "SESSION_PASSWORD_NEEDED") {
console.log(`error:`, error);
return;
}
// 2FA
const password = "USER_PASSWORD";
const { srp_id, current_algo, srp_B } = await getPassword();
const { g, p, salt1, salt2 } = current_algo;
const { A, M1 } = await api.mtproto.crypto.getSRPParams({
g,
p,
salt1,
salt2,
gB: srp_B,
password,
});
const checkPasswordResult = await checkPassword({ srp_id, A, M1 });
}
}
})();
updates.js
// UPDATES.js
/* eslint-disable no-undef */
const api = require("./api-origin");
api.mtproto.updates.on("updates", (updateInfo) => {
console.log("updates:", updateInfo);
});
function sendMessage() {
api.call("messages.sendMessage", {
clear_draft: true,
peer: {
_: "inputPeerSelf",
},
message: "Hello @mtproto_core",
entities: [
{
_: "messageEntityBold",
offset: 6,
length: 13,
},
],
random_id:
Math.ceil(Math.random() * 0xffffff) + Math.ceil(Math.random() * 0xffffff),
});
}
module.exports = { sendMessage };
@IgorKurkov
I made a smaller version of your script here
/* Example how to create MTProto:
const api = new MTProto({
api_id: Number(process.env.APP_ID),
api_hash: process.env.APP_HASH,
storageOptions: { path: './tempdata.json' }
})
*/
// Inject right after creating MTProto
api.__call = api.call
api.call = async (name, params, options) => {
if(options?.dcId) return api.__call(name, params, options)
if(api.__defaultDc) {
if(!options) options = {}
options.dcId = api.__defaultDc
}
try {
return await api.__call(name, params, options)
} catch(e) {
const migrateRegex = /_MIGRATE_(\d+)$/
if(migrateRegex.test(e?.error_message)) {
api.__defaultDc = Number(e.error_message.match(migrateRegex)[1])
return await api.call(name, params, options)
} else throw e
}
}
Did anybody get 2FA working? To me it seems the script already fails to recognize "SESSION_PASSWORD_NEEDED" but even if this gets bypassed to reach the 2FA section, I end up with error_code: 400, error_message: 'PASSWORD_HASH_INVALID'
Did anybody get 2FA working? To me it seems the script already fails to recognize "SESSION_PASSWORD_NEEDED" but even if this gets bypassed to reach the 2FA section, I end up with error_code: 400, error_message: 'PASSWORD_HASH_INVALID'
i have a error: Please help me! ( const phone = '+99966XYYYY'; const code = 'XXXXXX' )
users.getFullUser error: { _: 'mt_rpc_error', error_code: 401, error_message: 'AUTH_KEYUNREGISTERED' } auth.sendCode error: { : 'mt_rpc_error', error_code: 400, error_message: 'PHONE_NUMBER_INVALID' }
Hello,
Fairly new to Node and Telegram so this is a bit overwhelming for me. I've created an "api.js" file and copied the content of your api.js file into it (my api and api_hash are configured in the file).
Next i've created the "example.js" file like this:
So I entered my phone number, but can't write anything yet for the "code" variable since I didn't receive the code yet. I also changed the 2FA code to my personal 2FA string. Once I start example.js I get:
Can anyone point me in the right direction how to get authenticated?
Thanks!