Skip to content

Commit

Permalink
move from procedural to oo approach
Browse files Browse the repository at this point in the history
  • Loading branch information
michelkaporin committed Nov 4, 2020
1 parent fcabca9 commit c0c501d
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 71 deletions.
76 changes: 7 additions & 69 deletions app.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,13 @@
import TelegramBot, { InlineQueryResultCachedVoice } from 'node-telegram-bot-api';
import fs from 'fs';
import { LocalVoiceMap, TelegramVoiceMap } from './types';
import lodash from 'lodash';
const { isEqual } = lodash;
import dotenv from 'dotenv';
import { BotWrapper } from './bot';
import { VoicesLoader } from './voices-loader';

dotenv.config();
const token = process.env.TELEGRAM_BOT_TOKEN as string;

const localVoicesFilepath = './assets/local_voice_map.json';
const localVoicesFile = fs.readFileSync(localVoicesFilepath, 'utf-8');
const files: LocalVoiceMap = JSON.parse(localVoicesFile);

// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, { polling: true });

const voiceMapFilepath = './assets/telegram_voice_map.json';
const voiceMapFile = fs.readFileSync(voiceMapFilepath, 'utf-8');
const voiceMap: TelegramVoiceMap = JSON.parse(voiceMapFile);
const latestVoiceMap: TelegramVoiceMap = JSON.parse(voiceMapFile);

for (const file of files.voices) {
const voice = voiceMap.voices.find(v => v.id === file.id);

// Upload if voice doesn't exist
if (!voice) {
const data = fs.createReadStream(file.path);
const msg = await bot.sendVoice(459393176, data); // send to my chat id

if (!msg.voice) {
throw Error("Did not get an expected file_id from Telegram");
}

latestVoiceMap.voices.push({
id: file.id,
file_id: msg.voice.file_id,
title: file.title,
});
}
}
if (!isEqual(voiceMap, latestVoiceMap)) {
fs.writeFileSync(voiceMapFilepath, JSON.stringify(latestVoiceMap), { encoding: 'utf-8' });
}

latestVoiceMap.voices = latestVoiceMap.voices.sort((a, b) => {
if (a.title > b.title) {
return 1;
} else if (a.title < b.title) {
return -1;
}
return 0;
})

bot.on('inline_query', async query => {
const inlineMsg = query.query.toLowerCase();
let results = latestVoiceMap.voices;

if (inlineMsg.length > 1) {
results = latestVoiceMap.voices.filter(v => v.title.toLowerCase().includes(inlineMsg));
}

if (results.length > 50) {
results = results.slice(0, 49);
}

const voices = results.map(v => ({
id: v.id,
title: v.title,
voice_file_id: v.file_id,
type: 'voice'
}) as InlineQueryResultCachedVoice);
const botWrapper = new BotWrapper();
const bot = botWrapper.init();
const loader = new VoicesLoader(bot);
const voiceMap = loader.load();

bot.answerInlineQuery(query.id, voices);
});
botWrapper.bind(voiceMap);
43 changes: 43 additions & 0 deletions bot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import TelegramBot, { InlineQueryResultCachedVoice } from "node-telegram-bot-api";
import { TelegramVoiceMap } from "./types";

export class BotWrapper {

private bot?: TelegramBot;
private readonly token: string;

constructor() {
this.token = process.env.TELEGRAM_BOT_TOKEN as string;
}

init(): TelegramBot {
// Create a bot that uses 'polling' to fetch new updates
this.bot = new TelegramBot(this.token, { polling: true });
return this.bot;
}

async bind(voiceMap: Promise<TelegramVoiceMap>) {
const map = await voiceMap;
this.bot?.on('inline_query', async query => {
const inlineMsg = query.query.toLowerCase();
let results = map.voices;

if (inlineMsg.length > 1) {
results = map.voices.filter(v => v.title.toLowerCase().includes(inlineMsg));
}

if (results.length > 50) {
results = results.slice(0, 49);
}

const voices = results.map(v => ({
id: v.id,
title: v.title,
voice_file_id: v.file_id,
type: 'voice'
}) as InlineQueryResultCachedVoice);

this.bot?.answerInlineQuery(query.id, voices);
});
}
}
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"lodash": "^4.17.20",
"node-telegram-bot-api": "^0.50.0"
},
"type": "module",
"devDependencies": {
"@types/lodash": "^4.14.162",
"tslint": "^6.1.3",
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "esnext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
Expand Down
69 changes: 69 additions & 0 deletions voices-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { LocalVoiceMap, TelegramVoiceMap } from "./types";
import fs from 'fs';
import TelegramBot from "node-telegram-bot-api";
import { isEqual } from "lodash";

export class VoicesLoader {
private readonly localVoicesFilepath = './assets/local_voice_map.json';
private readonly voiceMapFilepath = './assets/telegram_voice_map.json';
private readonly myChatId = 459393176;

private bot: TelegramBot;

constructor(bot: TelegramBot) {
this.bot = bot;
}

async load(): Promise<TelegramVoiceMap> {
const localVoicesFile = fs.readFileSync(this.localVoicesFilepath, 'utf-8');
const files: LocalVoiceMap = JSON.parse(localVoicesFile);

const voiceMapFile = fs.readFileSync(this.voiceMapFilepath, 'utf-8');
const voiceMap: TelegramVoiceMap = JSON.parse(voiceMapFile);
const latestVoiceMap: TelegramVoiceMap = JSON.parse(voiceMapFile);

await this.uploadNewVoices(files, voiceMap, latestVoiceMap);

this.sortVoices(latestVoiceMap);

return latestVoiceMap;
}

private async uploadNewVoices(files: LocalVoiceMap, voiceMap: TelegramVoiceMap, newVoiceMap: TelegramVoiceMap) {
for (const file of files.voices) {
const voice = voiceMap.voices.find(v => v.id === file.id);

// Upload if voice doesn't exist
if (!voice) {
const data = fs.createReadStream(file.path);
const msg = await this.bot.sendVoice(this.myChatId, data); // send to my chat id

if (!msg.voice) {
throw Error("Did not get an expected file_id from Telegram");
}

newVoiceMap.voices.push({
id: file.id,
file_id: msg.voice.file_id,
title: file.title,
});
}
}

// Persist new voice map
if (!isEqual(voiceMap, newVoiceMap)) {
fs.writeFileSync(this.voiceMapFilepath, JSON.stringify(newVoiceMap), { encoding: 'utf-8' });
}
}

private sortVoices(latestVoiceMap: TelegramVoiceMap) {
latestVoiceMap.voices = latestVoiceMap.voices.sort((a, b) => {
if (a.title > b.title) {
return 1;
} else if (a.title < b.title) {
return -1;
}
return 0;
});
}
}

0 comments on commit c0c501d

Please sign in to comment.