telegraf-opex
Version:
Дополнение для ботов на телеграфе.
989 lines (851 loc) • 17.2 kB
JavaScript
const SQLite3 = require('better-sqlite3');
var sql, res, lang;
class OpexSQLite3Base {
constructor( config, saveRequests=true, updateUsernames=true, updateBotInfo=true ) {
this.path = config.path
this.cooldown = config.cooldown
this.saveRequests = saveRequests
this.updateUsernames = updateUsernames
this.updateBotInfo = updateBotInfo
this.db = new SQLite3( this.path)
this.t = {
u: 'users',
a: 'admins',
b: 'bots',
c: 'blacklist',
r: 'requests'
}
this.requests = this.t.r
this.tr = config.tr
this.query = (sql) => {
return this.db.prepare(sql)
}
this.adminsTable = () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.a} (
userId BIGINT,
date BIGINT,
PRIMARY KEY ( userId )
)
`
return this.query(sql).run()
}
this.blacklistTable = () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.c} (
userId BIGINT,
date BIGINT,
reason VARCHAR(300),
PRIMARY KEY ( userId )
)
`
return this.query(sql).run()
}
this.usersTable = () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.u} (
userId BIGINT,
first_name VARCHAR(255),
last_name VARCHAR(255),
username VARCHAR(255),
lang VARCHAR(10),
first_date BIGINT,
last_date BIGINT,
PRIMARY KEY ( userId )
)`
return this.query(sql).run()
}
this.requestsTable = () =>{
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.r} (
userId BIGINT,
botId BIGINT,
date BIGINT
)
`
return this.query(sql).run()
}
this.botsTable = () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.b} (
botId BIGINT,
first_name VARCHAR(255),
username VARCHAR(255),
PRIMARY KEY ( botId )
)`
return this.query(sql).run()
}
this.setTables = () => {
this.adminsTable()
this.blacklistTable()
this.usersTable()
this.requestsTable()
this.botsTable()
}
this.setTables()
}
log(e){console.log(e)}
/* SQL QQuey *\
\* query(sql: string) */
/* .run() *\
|: .bind() |
|: .all() |
\* .get() */
from(ctx) {
try{
var u = ctx.update.callback_query.from
} catch (err) {
var u = ctx.message.from
}
return u
}
unix() {
var unix = Math.round((new Date()).getTime() / 1000);
return unix
}
/* Tables List *\
\* tables(sys=false: boolean) */
tables(sys=false) {
if(sys==false){
var data = this.query(`SELECT name FROM sqlite_schema
WHERE type IN ('table','view')
AND name NOT LIKE 'sqlite_%'
ORDER BY 1;`).all()
} else {
var data = this.query('PRAGMA table_list').all();
}
return data
}
// TABLES
deleteTable(table) {
sql = `
DROP TABLE ${table}
`
return this.query(sql).run()
}
deleteTables() {
this.tables().forEach((el,ind)=>{
this.deleteTable(el.name)
})
}
/* Add ID to Table :*
*: uadd('table', 'userId') */
uadd(table, userId) {
const sql = `
INSERT INTO
${table} (userId)
VALUES
(${userId})
`
try{
res = this.query(sql).run()
} catch (e){
res = false
}
return res
}
// uset('table', 'var', 'val', 'userId')
uset(table, variable, value, userId) {
sql = `
UPDATE
${table}
SET
${variable} = ?
WHERE
userId = ${userId}
`
res = this.query(sql).bind([value]).run()
return res
}
// vget('table',?'var')
vget(table, variable='*') {
sql = `
SELECT ${variable}
FROM ${table}
`
return this.query(sql).all()
}
// uget('table','userId',?'var')
uget(table,userId, variable='*') {
sql = `
SELECT ${variable}
FROM ${table}
WHERE userId = ${userId}
`
return this.query(sql).all()
}
vrset(variable,value,userId,ugetted,check=true,tabl=this.t.u) {
if(check==true){
try{
if(ugetted[0][variable]==undefined||null){
this.uset(tabl,variable,value,userId)
}
} catch (e){
this.uset(tabl,variable,value,userId)
}
} else {
//check == false
this.uset(tabl,variable,value,userId)
}
}
setProfile(ctx,moresave=true) {
var us = this.from(ctx)
var mass = !moresave
var id = us.id
this.uadd(this.t.u,id);
var ud = this.uget(this.t.u,id)
var tabl = this.t.u
var first_name = us.first_name
this.vrset('first_name',first_name,id,ud,mass,tabl)
var last_name = us.last_name
this.vrset('last_name',last_name,id,ud,mass,tabl)
var username = us.username
this.vrset('username', username, id, ud, mass,tabl)
var lang = us.language_code
lang = this.convertLang(lang)
this.vrset('lang',lang,id,ud,true,tabl)
var date = this.unix()
this.vrset('first_date',date,id,ud,true,tabl)
this.vrset('last_date',date,id,ud,false,tabl)
return "ok"
}
logReq(ctx,moresave=true) {
var mass = !moresave
var botid = ctx.botInfo.id
var first_name = ctx.botInfo.first_name
var username = ctx.botInfo.username
var us = this.from(ctx)
var id = us.id
var tabl = this.t.b
this.uadd(tabl,botid)
var ud = this.uget(tabl,botid)
this.vrset('first_name',first_name,botid,ud,mass,tabl)
this.vrset('username',username,botid,ud,mass,tabl)
var date = this.unix()
sql = `
INSERT INTO
${this.requests} (userId,botId,date)
VALUES
(${id},${botid},${date})
`
try{
res = this.query(sql).run()
} catch (e){
res = false
}
return res
}
setCd(ctx) {
var us = this.from(ctx)
var uid = us.id
var time = this.unix()
uset(this.t.u,'last_date',time,uid)
return time
}
checkc(userId,table=this.t.u) {
sql = `
SELECT *
FROM ${table}
WHERE userId = ${userId}
`
var ou = this.query(sql).all()
var chck = String(ou)
if(chck){
return ou
} else {
return false
}
}
checkCd(ctx) {
try{
var u = ctx.update.callback_query.from
var inl = true
} catch (err) {
var u = ctx.message.from
var inl = false
}
var us = this.from(ctx)
var uid = us.id
var time = this.unix()
var user = this.checkc(uid)
if(user == false){
this.setProfile(ctx)
var ou = true
} else {
user = user[0]
if(user['last_date']==''){
this.setCd(ctx)
}
if(user['last_date']+this.cooldown<=time){
var ou = true
} else {
var ou = false
var msg = this.tr[this.getLang(ctx)]['ratelimit']['text']
if(inl==true){
ctx.telegram.answerCbQuery(ctx.update.callback_query.id, msg, {show_alert: true})
} else {
ctx.reply(msg);
}
return ()=>{}
} }
}
middleware = async (ctx,next)=>{
try{
this.checkCd(ctx)
this.l(ctx)
} catch (e) {
}
return await next()
}
saveLang(uid,lang) {
this.uset(this.t.u,'lang',lang,uid)
return lang
}
// Save Lang to DB
convertLang(lang) {
var langs = ['ru', 'uk', 'uz', 'kz', 'es']
if (langs.includes(lang) == true){
lang = 'ru'
} else {
lang = 'en'
}
return lang
}
// Convert Lang to LangID
getLang(ctx) {
var us = this.from(ctx)
var uid = us.id
var user = this.checkc(uid)
if(user==false){
this.setProfile(ctx)
}
return this.uget(this.t.u,uid,"lang")[0]["lang"]
}
setLang(ctx) {
var us = this.from(ctx)
var uid = us.id
var user = this.checkc(uid)
if(user==false){
lang = us.language_code
} else {
lang = user[0]['lang']
}
lang = this.convertLang(lang)
if(lang=='ru'){
lang = 'en'
} else {
lang = 'ru'
}
this.saveLang(uid,lang)
return lang
}
l(ctx) {
this.setProfile(ctx,this.updateUsernames)
if(this.saveRequests==true){
this.logReq(ctx,this.updateBotInfo)
}
}
count(array){
var c = 0;
for(i in array) // in returns key, not object
if(array[i] != undefined)
c++;
return c;
}
botsList(id=ctx){
sql = `
SELECT DISTINCT userId, botId
FROM requests
WHERE userId = ${id};
`
var out = [];
var ou = this.query(sql).all()
ou.forEach((el,i) => {
out.push(el["botId"])
})
return Array.from(new Set(out))
}
usersList(botid=null){
sql = `
SELECT DISTINCT userId, botId
FROM requests `
if(botid!=null){
sql = sql + `WHERE botId = ${botid};`
}
var out = [];
var ou = this.query(sql).all()
ou.forEach((el,i) => {
out.push(el["userId"])
})
return Array.from(new Set(out))
}
t(ctx){
return this.tr[this.getLang(ctx)]
}
lastUsers(days){
sql = `
SELECT *
FROM users
WHERE first_date > ${this.unix()-60*60*24*days}
`
return this.query(sql).all()
}
lastRequests(days,extra = {
user_id: null,
bot_id: null
}){
sql = `
SELECT *
FROM requests
WHERE date > ${this.unix()-60*60*24*days}`
if(extra.user_id!=null){
sql = sql + `
AND userId = ${extra.user_id}` }
if(extra.bot_id!=null){
sql = sql + `
AND botId = ${extra.bot_id}
`}
return this.query(sql).all()
}
}
class OpexMySQLBase {
constructor( config, saveRequests=true, updateUsernames=true, updateBotInfo=true , db=undefined) {
this.config = config
this.cooldown = config.cooldown
this.saveRequests = saveRequests
this.updateUsernames = updateUsernames
this.updateBotInfo = updateBotInfo
this.db = db
this.t = {
u: 'users',
a: 'admins',
b: 'bots',
c: 'blacklist',
r: 'requests'
}
this.requests = this.t.r
this.tr = config.tr
this.query = async (sql) => {
return await this.db.query(sql)
}
this.adminsTable = async () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.a} (
id BIGINT,
date BIGINT,
PRIMARY KEY ( id )
)
`
return await this.query(sql)
}
this.blacklistTable = async () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.c} (
id BIGINT,
date BIGINT,
reason VARCHAR(300),
PRIMARY KEY ( id )
)
`
return await this.query(sql)
}
this.usersTable = async () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.u} (
id BIGINT,
first_name VARCHAR(255),
last_name VARCHAR(255),
username VARCHAR(255),
balance BIGINT,
lang VARCHAR(10),
sub TINYINT(1),
first_date BIGINT,
last_date BIGINT,
PRIMARY KEY ( id )
)`
return await this.query(sql)
}
this.requestsTable = async () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.r} (
id BIGINT,
botid BIGINT,
date BIGINT
)
`
return await this.query(sql)
}
this.botsTable = async () => {
sql = `
CREATE TABLE
IF NOT EXISTS
${this.t.b} (
id BIGINT,
first_name VARCHAR(255),
username VARCHAR(255),
PRIMARY KEY ( id )
)`
return await this.query(sql)
}
this.setTables = async () => {
await this.adminsTable()
await this.blacklistTable()
await this.usersTable()
await this.requestsTable()
await this.botsTable()
}
(async()=>{
this.setTables()
})()
}
log(e){console.log(e)}
/* SQL Query *\
\* query(sql: string) */
from(ctx) {
try{
var u = ctx.update.callback_query.from
} catch (err) {
var u = ctx.message.from
}
return u
}
unix() {
var unix = Math.round((new Date()).getTime() / 1000);
return unix
}
/* Tables List *\
\* tables(sys=false: boolean) */
async tables() {
var data = await this.query(`SHOW TABLES`)
var tabls = [];
data.forEach(await (async (el,ind)=>{
tabls.push(el["Tables_in_"+this.config.mysql.database])
}))
return tabls
}
async deleteTable(table) {
sql = `
DROP TABLE ${table}
`
return await this.query(sql)
}
async deleteTables() {
this.tables().forEach(await (async (el,ind)=>{
await this.deleteTable(el)
}))
}
/* Add ID to Table :*
*: uadd('table', 'id') */
async uadd(table, id) {
sql = `
INSERT INTO
${table} (id)
VALUES
(${id})
`
try{
res = await this.query(sql)
} catch (e){
res = false
}
return res
}
// uset('table', 'var', 'val', 'id')
async uset(table, variable, value, id) {
sql = `
UPDATE
${table}
SET
${variable} = "${value}"
WHERE
id = ${id}
`
res = await this.query(sql)
return res
}
// vget('table',?'var')
async vget(table, variable='*') {
sql = `
SELECT ${variable}
FROM ${table}
`
return await this.query(sql)
}
// uget('table','id',?'var')
async uget(table,id, variable='*') {
sql = `
SELECT ${variable}
FROM ${table}
WHERE id = ${id}
`
return await this.query(sql)
}
async vrset(variable,value,id,ugetted,check=true,tabl=this.t.u) {
if(check==true){
try{
if(ugetted[0][variable]==undefined||null){
await this.uset(tabl,variable,value,id)
}
} catch (e){
await this.uset(tabl,variable,value,id)
}
} else {
//check == false
await this.uset(tabl,variable,value,id)
}
}
async setProfile(ctx,moresave=true) {
var us = this.from(ctx)
var mass = !moresave
var id = us.id
await this.uadd(this.t.u,id);
var ud = await this.uget(this.t.u,id)
var tabl = this.t.u
var first_name = us.first_name
await this.vrset('first_name',first_name,id,ud,mass,tabl)
var last_name = us.last_name
await this.vrset('last_name',last_name,id,ud,mass,tabl)
var username = us.username
await this.vrset('username', username, id, ud, mass,tabl)
var balance = 0
await this.vrset('balance', balance, id, ud, true,tabl)
var lang = us.language_code
lang = this.convertLang(lang)
await this.vrset('lang',lang,id,ud,true,tabl)
var sub = 1
await this.vrset('sub',sub,id,ud,true,tabl)
var date = this.unix()
await this.vrset('first_date',date,id,ud,true,tabl)
await this.vrset('last_date',date,id,ud,false,tabl)
return "ok"
}
async subset(ctx,sub="def") {
var us = this.from(ctx)
var id = us.id
if(sub=="def"){
var sub = await this.uget(this.t.u,id,'sub');
sub = sub[0]['sub']
if(!!sub){sub=0}else{sub=1}
}
await this.uset(this.t.u,'sub',sub,id)
return sub
}
async logReq(ctx,moresave=true) {
var mass = !moresave
var botid = ctx.botInfo.id
var first_name = ctx.botInfo.first_name
var username = ctx.botInfo.username
var us = this.from(ctx)
var id = us.id
var tabl = this.t.b
await this.uadd(tabl,botid)
var ud = await this.uget(tabl,botid)
await this.vrset('first_name',first_name,botid,ud,mass,tabl)
await this.vrset('username',username,botid,ud,mass,tabl)
var date = this.unix()
sql = `
INSERT INTO
${this.requests} (id,botid,date)
VALUES
(${id},${botid},${date})
`
try{
res = await this.query(sql)
} catch (e){
res = false
}
return res
}
async setCd(ctx) {
var us = this.from(ctx)
var uid = us.id
var time = this.unix()
await this.uset(this.t.u,'last_date',time,uid)
return time
}
async checkc(id,table=this.t.u) {
sql = `
SELECT *
FROM ${table}
WHERE id = ${id}
`
var ou = await this.query(sql)
var chck = String(ou)
if(chck){
return ou
} else {
return false
}
}
async checkCd(ctx) {
try{
var u = ctx.update.callback_query.from
var inl = true
} catch (err) {
var u = ctx.message.from
var inl = false
}
var us = this.from(ctx)
var uid = us.id
var time = this.unix()
var user = await this.checkc(uid)
if(user == false){
await this.setProfile(ctx)
var ou = true
} else {
user = user[0]
if(user['last_date']==''){
await this.setCd(ctx)
}
if(user['last_date']+this.cooldown<=time){
var ou = true
} else {
var ou = false
var msg = this.tr[await this.getLang(ctx)]['ratelimit']['text']
if(inl==true){
ctx.telegram.answerCbQuery(ctx.update.callback_query.id, msg, {show_alert: true})
} else {
ctx.reply(msg);
}
return ()=>{}
} }
}
middleware = async (ctx,next)=>{
try{
await this.checkCd(ctx)
await this.l(ctx)
} catch (e) {
}
return await next()
}
async saveLang(uid,lang) {
await this.uset(this.t.u,'lang',lang,uid)
return lang
}
// Save Lang to DB
convertLang(lang) {
var langs = ['ru', 'uk', 'uz', 'kz', 'es']
if (langs.includes(lang) == true){
lang = 'ru'
} else {
lang = 'en'
}
return lang
}
// Convert Lang to LangID
async getLang(ctx) {
var us = this.from(ctx)
var uid = us.id
var user = await this.checkc(uid)
if(user==false){
await this.setProfile(ctx)
}
var l1 = (await this.uget(this.t.u,uid,"lang"))[0]["lang"]
return l1
}
async setLang(ctx) {
var us = this.from(ctx)
var uid = us.id
var user = await this.checkc(uid)
if(user==false){
lang = us.language_code
} else {
lang = user[0]['lang']
}
lang = this.convertLang(lang)
if(lang=='ru'){
lang = 'en'
} else {
lang = 'ru'
}
await this.saveLang(uid,lang)
return lang
}
async l(ctx) {
await this.setProfile(ctx,this.updateUsernames)
if(this.saveRequests==true){
await this.logReq(ctx,this.updateBotInfo)
}
}
count(array){
var c = 0;
for(i in array) // in returns key, not object
if(array[i] != undefined)
c++;
return c;
}
async botsList(id=ctx){
sql = `
SELECT DISTINCT id, botid
FROM requests
WHERE id = ${id};
`
var out = [];
var ou = await this.query(sql)
ou.forEach((el,i) => {
out.push(el["botid"])
})
return Array.from(new Set(out))
}
async usersList(botid=null){
sql = `
SELECT DISTINCT id, botid
FROM requests `
if(botid!=null){
sql = sql + `WHERE botid = ${botid};`
}
var out = [];
var ou = await this.query(sql)
ou.forEach((el,i) => {
out.push(el["id"])
})
return Array.from(new Set(out))
}
async t(ctx){
return this.tr[await this.getLang(ctx)]
}
async lastUsers(days){
sql = `
SELECT *
FROM users
WHERE first_date > ${this.unix()-60*60*24*days}
`
return await this.query(sql)
}
async lastRequests(days,extra = {
user_id: null,
bot_id: null
}){
sql = `
SELECT *
FROM requests
WHERE date > ${this.unix()-60*60*24*days}`
if(extra.user_id!=null){
sql = sql + `
AND id = ${extra.user_id}` }
if(extra.bot_id!=null){
sql = sql + `
AND botid = ${extra.bot_id}
`}
return await this.query(sql)
}
}
module.exports = { OpexMySQLBase, OpexSQLite3Base }