Skip to content

Commit

Permalink
Multiple auth
Browse files Browse the repository at this point in the history
  • Loading branch information
qertis committed Nov 14, 2024
1 parent 0ed4f37 commit a35f133
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 85 deletions.
104 changes: 63 additions & 41 deletions src/actions/public/start.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { TELEGRAM_MINI_APP } = process.env;
const { TELEGRAM_MINI_APP, IS_DEV } = require('../../environments/index.cjs');
const { getUsers } = require('../../libs/database.cjs');

function getWelcomeText() {
Expand All @@ -12,9 +12,16 @@ function getWelcomeText() {
'🔄 Синхронизация с другими календарями\n\n' +
'📊 Анализ вашего расписания\n\n' +
'Продолжая использование вы соглашаетесь с Лицензионным соглашением /licence\\.\n'
// 'Узнай больше подробностей командой /help.' +
// 'Предоставь свои контакты чтобы продолжить пользоваться сервисом',
);
).trim();
}

function getInstallAgainText() {
return (
'**Требуется повторная установка**\n\n' +
'Предоставь свои контакты заново, чтобы продолжить пользоваться сервисом\\.\n\n' +
'Узнай больше подробностей командой /help\\.\n' +
'Продолжая использование вы соглашаетесь с Лицензионным соглашением /licence\\.\n'
).trim();
}

/**
Expand All @@ -26,44 +33,59 @@ function getWelcomeText() {
*/
module.exports = async (bot, message) => {
let webAppUrl = `${TELEGRAM_MINI_APP}/tutorial?lang=${message.from.language_code}`;
if (process.env.NODE_ENV?.toLowerCase()?.startsWith('dev')) {
// eslint-disable-next-line unicorn/consistent-destructuring
if (IS_DEV) {
webAppUrl += '&debug=1';
} else {
const users = getUsers(message.chat.id);
if (users.length > 0) {
return bot.sendMessage(
message.chat.id,
'Повторная установка не требуется\n\n' + '/help - помощь' + '\n' + '/licence - соглашение',
);
}
}

const me = await bot.getMe();
const photos = await bot.getUserProfilePhotos(me.id);
const photo = photos.photos?.[0]?.[0]?.file_id;
const file = await bot.getFile(photo);
const fileBuffer = await bot.getFileStream(file.file_id);
await bot.sendPhoto(message.chat.id, fileBuffer, {
caption: 'Hello',
parse_mode: 'HTML',
filename: 'hello',
contentType: 'image/png',
});
await bot.sendMessage(message.chat.id, getWelcomeText(), {
parse_mode: 'MarkdownV2',
disable_notification: true,
reply_markup: {
remove_keyboard: true,
resize_keyboard: true,
one_time_keyboard: true,
keyboard: [
[
{
text: 'Авторизоваться',
web_app: { url: webAppUrl },
},
const existUser = getUsers(message.chat.id)?.length > 0;
if (!existUser) {
await bot.sendMessage(message.chat.id, getInstallAgainText(), {
parse_mode: 'MarkdownV2',
disable_notification: true,
reply_markup: {
remove_keyboard: true,
resize_keyboard: true,
one_time_keyboard: true,
keyboard: [
[
{
text: 'Принимаю лицензионное соглашение',
request_contact: true,
},
],
],
},
});
} else {
/* uncomment in prod
const me = await bot.getMe();
const photos = await bot.getUserProfilePhotos(me.id);
const photo = photos.photos?.[0]?.[0]?.file_id;
const file = await bot.getFile(photo);
const fileBuffer = await bot.getFileStream(file.file_id);
await bot.sendPhoto(message.chat.id, fileBuffer, {
caption: 'Hello',
parse_mode: 'HTML',
filename: 'hello',
contentType: 'image/png',
});
*/
bot.sendMessage(message.chat.id, getWelcomeText(), {
parse_mode: 'MarkdownV2',
disable_notification: true,
reply_markup: {
remove_keyboard: true,
resize_keyboard: true,
one_time_keyboard: true,
keyboard: [
[
{
text: 'Авторизоваться',
web_app: { url: webAppUrl },
},
],
],
],
},
});
},
});
}
};
6 changes: 4 additions & 2 deletions src/actions/system/focus-pomodoro.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { TELEGRAM_MINI_APP_URL } = require('../../environments/index.cjs');

module.exports = async (bot, message) => {
console.log('start pomodoro timer', message);
await bot.setMessageReaction(message.chat.id, message.message_id, {
Expand All @@ -20,10 +22,10 @@ module.exports = async (bot, message) => {
[
{
text: 'Завершить',
'url': 'https://t.me/gotois_bot/App'
url: TELEGRAM_MINI_APP_URL,
},
],
],
},
});
}
};
4 changes: 2 additions & 2 deletions src/actions/system/notifier.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ module.exports.notifyNextHour = async (bot, message) => {
await bot.sendMessage(message.chat.id, 'Напомню через: 60 мин.', {
message_id: message.message_id,
});
}
};

module.exports.notifyNextDay = async (bot, message) => {
await bot.sendMessage(message.chat.id, 'Напомню завтра', {
message_id: message.message_id,
});
}
};
2 changes: 1 addition & 1 deletion src/actions/system/ping.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { SERVER_HOST, SERVER_HOST_USERNAME, SERVER_HOST_PASSWORD } = process.env;
const { SERVER_HOST, SERVER_HOST_USERNAME, SERVER_HOST_PASSWORD } = require('../../environments/index.cjs');

/**
* Проверка сети
Expand Down
68 changes: 68 additions & 0 deletions src/actions/system/registration-phone.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const { setJWT } = require('../../libs/database.cjs');
const { SERVER_HOST, SERVER_HOST_USERNAME, SERVER_HOST_PASSWORD } = require('../../environments/index.cjs');
const { generateTelegramHash } = require('../../libs/tg-crypto.cjs');

function registrationSuccessMessage() {
return `
**Успешно зарегистрированы** ✅`.trim();
}

/**
* @description Ассистент детектирует пользователя
* @param {any} bot - telegram bot
* @param {any} message - telegram message
* @returns {Promise<void>}
*/
module.exports = async (bot, message) => {
const body = {
contact: {
phoneNumber: message.contact.phone_number,
firstName: message.contact.first_name,
lastName: message.contact.last_name,
userId: message.contact.user_id,
},
authDate: message.date * 1000,
hash: generateTelegramHash({
auth_date: message.date,
contact: JSON.stringify(message.contact),
}),
};
try {
// добавляем в запрос фото профиля
const profilePhotos = await bot.getUserProfilePhotos(message.chat.id);
if (profilePhotos.photos.length > 0) {
const userPicture = await bot.getFileLink(profilePhotos.photos[0][0].file_id);
body.picture = userPicture;
}
} catch (error) {
console.error(error);
}
try {
const response = await fetch(SERVER_HOST + '/registration', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa(SERVER_HOST_USERNAME + ':' + SERVER_HOST_PASSWORD),
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error('Произошла ошибка');
}
const result = await response.text();
setJWT(Number(message.chat.id), result);
await bot.deleteMessage(message.chat.id, message.message_id);
await bot.sendMessage(message.chat.id, registrationSuccessMessage(), {
parse_mode: 'MarkdownV2',
message_effect_id: '5046509860389126442', // 🎉
reply_markup: {
remove_keyboard: true,
},
});
} catch (error) {
console.error(error);
return bot.sendMessage(message.chat.id, error.message, {
message_effect_id: '5046589136895476101', // 💩
});
}
};
18 changes: 3 additions & 15 deletions src/actions/system/registration.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ function registrationSuccessMessage() {
Отправь мне войс, текст или картинку и я добавлю это событие в твой календарь\\!
Например:
**"💈Напомни завтра о барбершопе в 9:00 на Бауманской"**
**"📆В это воскресенье будет митап"**
**"💧Мне важно пить 2 литра воды в день ежедневно"**
**💈Напомни завтра о барбершопе в 9:00 на Бауманской**
**📆В это воскресенье будет митап**
**💧Мне важно пить 2 литра воды в день ежедневно**
`.trim();
}

Expand All @@ -21,18 +21,6 @@ function registrationSuccessMessage() {
* @returns {Promise<void>}
*/
module.exports = async (bot, message, jwt) => {
/* todo - перенести в другие модули где требуется получить изображение пользователя
const profilePhotos = await bot.getUserProfilePhotos(message.chat.id);
if (profilePhotos.photos.length > 0) {
const userPicture = await bot.getFileLink(profilePhotos.photos[0][0].file_id);
activity.actor.image = {
type: 'Link',
href: userPicture,
mediaType: 'image/jpeg',
};
}
*/

try {
await bot.deleteMessage(message.chat.id, message.message_id);
setJWT(Number(message.chat.id), jwt);
Expand Down
13 changes: 8 additions & 5 deletions src/actions/system/want.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
module.exports = async function (bot, message) {
const text = message.entities
.filter(entity => entity.type === 'bot_command')
.reduce((acc, command) => {
acc = acc.substring(command.offset + command.length);
return acc;
.filter((entity) => {
return entity.type === 'bot_command';
})
// eslint-disable-next-line unicorn/no-array-reduce
.reduce((accumulator, command) => {
accumulator = accumulator.substring(command.offset + command.length);
return accumulator;
}, message.text)
.trim();

Expand All @@ -13,4 +16,4 @@ module.exports = async function (bot, message) {
await bot.sendMessage(message.chat.id, 'Задача ' + text + ' начата', {
disable_web_page_preview: true,
});
}
};
3 changes: 1 addition & 2 deletions src/controllers/generate-calendar.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ const ICAL = require('ical.js');
const requestJsonRpc2 = require('request-json-rpc2').default;
const { serializeMarkdownV2 } = require('../libs/md-serialize.cjs');
const { TEXT_CALENDAR } = require('../libs/mime-types.cjs');

const { SERVER_HOST } = process.env;
const { SERVER_HOST } = require('../environments/index.cjs');

module.exports.formatGoogleCalendarUrl = function (ical) {
const icalData = ICAL.parse(ical);
Expand Down
26 changes: 26 additions & 0 deletions src/environments/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const {
NODE_ENV,
DIALOGFLOW_CREDENTIALS,
TELEGRAM_MINI_APP,
SERVER_HOST,
SERVER_HOST_USERNAME,
SERVER_HOST_PASSWORD,
TELEGRAM_TOKEN,
TELEGRAM_DOMAIN,
} = process.env;

module.exports = {
get IS_DEV() {
return NODE_ENV?.toLowerCase()?.startsWith('dev');
},
TELEGRAM_MINI_APP: TELEGRAM_MINI_APP,
TELEGRAM_TOKEN: TELEGRAM_TOKEN,
TELEGRAM_DOMAIN: TELEGRAM_DOMAIN,
TELEGRAM_MINI_APP_URL: 'https://t.me/gotois_bot/App',
SERVER_HOST: SERVER_HOST,
SERVER_HOST_USERNAME: SERVER_HOST_USERNAME,
SERVER_HOST_PASSWORD: SERVER_HOST_PASSWORD,
get DIALOGFLOW_CREDENTIALS() {
return JSON.parse(DIALOGFLOW_CREDENTIALS);
},
};
12 changes: 7 additions & 5 deletions src/index.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const botController = require('telegram-bot-api-express');
const { TELEGRAM_TOKEN, TELEGRAM_DOMAIN } = require('./environments/index.cjs');
const pingAction = require('./actions/system/ping.cjs');
const dbclearAction = require('./actions/system/dbclear.cjs');
const helpAction = require('./actions/system/help.cjs');
const offertaAction = require('./actions/system/offerta.cjs');
const registrationAction = require('./actions/system/registration.cjs');
const registrationByMiniAppAction = require('./actions/system/registration.cjs');
const registrationByPhoneAction = require('./actions/system/registration-phone.cjs');
const wantAction = require('./actions/system/want.cjs');
const sendCalendar = require('./actions/system/send-calendar.cjs');
const startAction = require('./actions/public/start.cjs');
Expand Down Expand Up @@ -48,7 +50,7 @@ function checkAuth(callback) {
};
}

module.exports = ({ token = process.env.TELEGRAM_TOKEN, domain = process.env.TELEGRAM_DOMAIN }) => {
module.exports = ({ token = TELEGRAM_TOKEN, domain = TELEGRAM_DOMAIN }) => {
return botController({
token: token,
domain: domain,
Expand Down Expand Up @@ -86,18 +88,18 @@ module.exports = ({ token = process.env.TELEGRAM_TOKEN, domain = process.env.TEL

/* CALLBACK */
['web_app_data']: (bot, message) => {
const webAppData = JSON.parse(message.web_app_data);
const webAppData = JSON.parse(message.web_app_data.data);
switch (webAppData.type) {
case 'registration': {
return registrationAction(bot, message, webAppData.data);
return registrationByMiniAppAction(bot, message, webAppData.data);
}
default: {
console.warn('Unknown type:' + webAppData.type, webAppData);
break;
}
}
},
['auth_by_contact']: () => {},
['auth_by_contact']: registrationByPhoneAction,
['send_calendar']: checkAuth(sendCalendar),

// Сделать напоминание того же события через 15 мин, 60 мин или на следующий день
Expand Down
9 changes: 3 additions & 6 deletions src/libs/database.cjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
const sqlite = require('node:sqlite');
const { IS_DEV } = require('../environments/index.cjs');

const database = (() => {
// eslint-disable-next-line unicorn/prefer-ternary
if (process.env.NODE_ENV?.toLowerCase()?.startsWith('dev')) {
return new sqlite.DatabaseSync('database.sqlite');
} else {
return new sqlite.DatabaseSync(':memory:');
}
const location = IS_DEV ? 'database.sqlite' : ':memory:';
return new sqlite.DatabaseSync(location);
})();

function createUsersTable() {
Expand Down
Loading

0 comments on commit a35f133

Please sign in to comment.