{Sed}",
43 | parse_mode="HTML",
44 | )
45 |
--------------------------------------------------------------------------------
/Tianabot/modules/helper_funcs/filters.py:
--------------------------------------------------------------------------------
1 | from Tianabot import DEV_USERS, DRAGONS, DEMONS
2 | from telegram import Message
3 | from telegram.ext import BaseFilter
4 |
5 |
6 | class CustomFilters(object):
7 | class _Supporters(BaseFilter):
8 | def filter(self, message: Message):
9 | return bool(message.from_user and message.from_user.id in DEMONS)
10 |
11 | support_filter = _Supporters()
12 |
13 | class _Sudoers(BaseFilter):
14 | def filter(self, message: Message):
15 | return bool(message.from_user and message.from_user.id in DRAGONS)
16 |
17 | sudo_filter = _Sudoers()
18 |
19 | class _Developers(BaseFilter):
20 | def filter(self, message: Message):
21 | return bool(message.from_user and message.from_user.id in DEV_USERS)
22 |
23 | dev_filter = _Developers()
24 |
25 | class _MimeType(BaseFilter):
26 | def __init__(self, mimetype):
27 | self.mime_type = mimetype
28 | self.name = "CustomFilters.mime_type({})".format(self.mime_type)
29 |
30 | def filter(self, message: Message):
31 | return bool(
32 | message.document and message.document.mime_type == self.mime_type
33 | )
34 |
35 | mime_type = _MimeType
36 |
37 | class _HasText(BaseFilter):
38 | def filter(self, message: Message):
39 | return bool(
40 | message.text
41 | or message.sticker
42 | or message.photo
43 | or message.document
44 | or message.video
45 | )
46 |
47 | has_text = _HasText()
48 |
--------------------------------------------------------------------------------
/Tianabot/utils/errors.py:
--------------------------------------------------------------------------------
1 | # © @Mr_Dark_Prince
2 | import sys
3 | import traceback
4 | from functools import wraps
5 | from Tianabot import pbot, SUPPORT_CHAT
6 |
7 | def split_limits(text):
8 | if len(text) < 2048:
9 | return [text]
10 |
11 | lines = text.splitlines(True)
12 | small_msg = ''
13 | result = []
14 | for line in lines:
15 | if len(small_msg) + len(line) < 2048:
16 | small_msg += line
17 | else:
18 | result.append(small_msg)
19 | small_msg = line
20 | else:
21 | result.append(small_msg)
22 |
23 | return result
24 |
25 | def capture_err(func):
26 | @wraps(func)
27 | async def capture(client, message, *args, **kwargs):
28 | try:
29 | return await func(client, message, *args, **kwargs)
30 | except Exception as err:
31 | exc_type, exc_obj, exc_tb = sys.exc_info()
32 | errors = traceback.format_exception(
33 | etype=exc_type, value=exc_obj, tb=exc_tb,
34 | )
35 | error_feedback = split_limits(
36 | '**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n'.format(
37 | 0 if not message.from_user else message.from_user.id,
38 | 0 if not message.chat else message.chat.id,
39 | message.text or message.caption,
40 | ''.join(errors),
41 | ),
42 | )
43 | for x in error_feedback:
44 | await pbot.send_message(
45 | SUPPORT_CHAT,
46 | x
47 | )
48 | raise err
49 | return capture
50 |
--------------------------------------------------------------------------------
/Tianabot/pyrogramee/errors.py:
--------------------------------------------------------------------------------
1 | # © @Mr_Dark_Prince
2 | import sys
3 | import traceback
4 | from functools import wraps
5 | from Tianabot import pbot, SUPPORT_CHAT
6 |
7 | def split_limits(text):
8 | if len(text) < 2048:
9 | return [text]
10 |
11 | lines = text.splitlines(True)
12 | small_msg = ''
13 | result = []
14 | for line in lines:
15 | if len(small_msg) + len(line) < 2048:
16 | small_msg += line
17 | else:
18 | result.append(small_msg)
19 | small_msg = line
20 | else:
21 | result.append(small_msg)
22 |
23 | return result
24 |
25 | def capture_err(func):
26 | @wraps(func)
27 | async def capture(client, message, *args, **kwargs):
28 | try:
29 | return await func(client, message, *args, **kwargs)
30 | except Exception as err:
31 | exc_type, exc_obj, exc_tb = sys.exc_info()
32 | errors = traceback.format_exception(
33 | etype=exc_type, value=exc_obj, tb=exc_tb,
34 | )
35 | error_feedback = split_limits(
36 | '**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n'.format(
37 | 0 if not message.from_user else message.from_user.id,
38 | 0 if not message.chat else message.chat.id,
39 | message.text or message.caption,
40 | ''.join(errors),
41 | ),
42 | )
43 | for x in error_feedback:
44 | await pbot.send_message(
45 | SUPPORT_CHAT,
46 | x
47 | )
48 | raise err
49 | return capture
50 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/mod_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from sqlalchemy import Column, String, BigInteger
4 |
5 | from Tianabot.modules.sql import BASE, SESSION
6 |
7 |
8 | class Mods(BASE):
9 | __tablename__ = "mod"
10 | chat_id = Column(String(14), primary_key=True)
11 | user_id = Column(BigInteger, primary_key=True)
12 |
13 | def __init__(self, chat_id, user_id):
14 | self.chat_id = str(chat_id) # ensure string
15 | self.user_id = user_id
16 |
17 | def __repr__(self):
18 | return "{chat_name}\n"
32 | except BadRequest:
33 | pass
34 | except Unauthorized:
35 | pass
36 | except RetryAfter as e:
37 | sleep(e.retry_after)
38 |
39 | if len(text) < 4096:
40 | msg.reply_text(text, parse_mode="HTML")
41 | else:
42 | with open("common_chats.txt", "w") as f:
43 | f.write(text)
44 | with open("common_chats.txt", "rb") as f:
45 | msg.reply_document(f)
46 | os.remove("common_chats.txt")
47 |
48 |
49 | COMMON_CHATS_HANDLER = CommandHandler(
50 | "getchats", get_user_common_chats, filters=Filters.user(OWNER_ID)
51 | )
52 |
53 | dispatcher.add_handler(COMMON_CHATS_HANDLER)
54 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/aihelp_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from Tianabot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String
5 |
6 |
7 | class aiChats(BASE):
8 | __tablename__ = "ai_chats"
9 | chat_id = Column(String(14), primary_key=True)
10 | ses_id = Column(String(70))
11 | expires = Column(String(15))
12 |
13 | def __init__(self, chat_id, ses_id, expires):
14 | self.chat_id = chat_id
15 | self.ses_id = ses_id
16 | self.expires = expires
17 |
18 |
19 | aiChats.__table__.create(checkfirst=True)
20 |
21 | INSERTION_LOCK = threading.RLock()
22 |
23 |
24 | def is_chat(chat_id):
25 | try:
26 | chat = SESSION.query(aiChats).get(str(chat_id))
27 | if chat:
28 | return True
29 | return False
30 | finally:
31 | SESSION.close()
32 |
33 |
34 | def set_ses(chat_id, ses_id, expires):
35 | with INSERTION_LOCK:
36 | autochat = SESSION.query(aiChats).get(str(chat_id))
37 | if not autochat:
38 | autochat = aiChats(str(chat_id), str(ses_id), str(expires))
39 | else:
40 | autochat.ses_id = str(ses_id)
41 | autochat.expires = str(expires)
42 |
43 | SESSION.add(autochat)
44 | SESSION.commit()
45 |
46 |
47 | def get_ses(chat_id):
48 | autochat = SESSION.query(aiChats).get(str(chat_id))
49 | sesh = ""
50 | exp = ""
51 | if autochat:
52 | sesh = str(autochat.ses_id)
53 | exp = str(autochat.expires)
54 |
55 | SESSION.close()
56 | return sesh, exp
57 |
58 |
59 | def rem_chat(chat_id):
60 | with INSERTION_LOCK:
61 | autochat = SESSION.query(aiChats).get(str(chat_id))
62 | if autochat:
63 | SESSION.delete(autochat)
64 |
65 | SESSION.commit()
66 |
67 |
68 | def get_all_chats():
69 | try:
70 | return SESSION.query(aiChats.chat_id).all()
71 | finally:
72 | SESSION.close()
73 |
--------------------------------------------------------------------------------
/Tianabot/modules/json.py:
--------------------------------------------------------------------------------
1 | import io
2 | from Tianabot.events import register
3 | from Tianabot import telethn as borg
4 | from Tianabot import telethn as tbot
5 | from telethon import types
6 | from telethon import events
7 | from telethon.tl import functions, types
8 | from telethon.tl.types import *
9 |
10 |
11 | async def is_register_admin(chat, user):
12 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
13 | return isinstance(
14 | (
15 | await tbot(functions.channels.GetParticipantRequest(chat, user))
16 | ).participant,
17 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
18 | )
19 | if isinstance(chat, types.InputPeerUser):
20 | return True
21 |
22 |
23 | @register(pattern="^/json$")
24 | async def _(event):
25 | if event.fwd_from:
26 | return
27 | if event.is_group:
28 | if not (await is_register_admin(event.input_chat, event.message.sender_id)):
29 | await event.reply("🚨 Need Admin Pewer.. You can't use this command.. But you can use in my pm")
30 | return
31 |
32 | the_real_message = None
33 | reply_to_id = None
34 | if event.reply_to_msg_id:
35 | previous_message = await event.get_reply_message()
36 | the_real_message = previous_message.stringify()
37 | reply_to_id = event.reply_to_msg_id
38 | else:
39 | the_real_message = event.stringify()
40 | reply_to_id = event.message.id
41 | if len(the_real_message) > 4095:
42 | with io.BytesIO(str.encode(the_real_message)) as out_file:
43 | out_file.name = "json.text"
44 | await borg.send_file(
45 | event.chat_id,
46 | out_file,
47 | force_document=True,
48 | allow_cache=False,
49 | reply_to=reply_to_id,
50 | )
51 | await event.delete()
52 | else:
53 | await event.reply("`{}`".format(the_real_message))
54 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # We're using Debian Slim Buster image
2 | FROM python:3.8.5-slim-buster
3 |
4 | ENV PIP_NO_CACHE_DIR 1
5 |
6 | RUN sed -i.bak 's/us-west-2\.ec2\.//' /etc/apt/sources.list
7 |
8 | # Installing Required Packages
9 | RUN apt update && apt upgrade -y && \
10 | apt install --no-install-recommends -y \
11 | debian-keyring \
12 | debian-archive-keyring \
13 | bash \
14 | bzip2 \
15 | curl \
16 | figlet \
17 | git \
18 | util-linux \
19 | libffi-dev \
20 | libjpeg-dev \
21 | libjpeg62-turbo-dev \
22 | libwebp-dev \
23 | linux-headers-amd64 \
24 | musl-dev \
25 | musl \
26 | neofetch \
27 | php-pgsql \
28 | python3-lxml \
29 | postgresql \
30 | postgresql-client \
31 | python3-psycopg2 \
32 | libpq-dev \
33 | libcurl4-openssl-dev \
34 | libxml2-dev \
35 | libxslt1-dev \
36 | python3-pip \
37 | python3-requests \
38 | python3-sqlalchemy \
39 | python3-tz \
40 | python3-aiohttp \
41 | openssl \
42 | pv \
43 | jq \
44 | wget \
45 | python3 \
46 | python3-dev \
47 | libreadline-dev \
48 | libyaml-dev \
49 | gcc \
50 | sqlite3 \
51 | libsqlite3-dev \
52 | sudo \
53 | zlib1g \
54 | ffmpeg \
55 | libssl-dev \
56 | libgconf-2-4 \
57 | libxi6 \
58 | xvfb \
59 | unzip \
60 | libopus0 \
61 | libopus-dev \
62 | && rm -rf /var/lib/apt/lists /var/cache/apt/archives /tmp
63 |
64 | # Pypi package Repo upgrade
65 | RUN pip3 install --upgrade pip setuptools
66 |
67 | # Copy Python Requirements to /root/Tianabot
68 | RUN git clone -b shiken https://github.com/teamofdevil-x/tiana /root/Tianabot
69 | WORKDIR /root/Tianabot
70 |
71 | #Copy config file to /root/Tianabot
72 | COPY ./Tianabot/sample_config.py ./Tianabot/config.py* /root/Tianabot/Tianabot/
73 |
74 | ENV PATH="/home/bot/bin:$PATH"
75 |
76 | # Install requirements
77 | RUN pip3 install -U -r requirements.txt
78 |
79 | # Starting Worker
80 | CMD ["python3","-m","Tianabot"]
81 |
--------------------------------------------------------------------------------
/Tianabot/modules/currency_converter.py:
--------------------------------------------------------------------------------
1 | import requests
2 | from Tianabot import CASH_API_KEY, dispatcher
3 | from telegram import Update, ParseMode
4 | from telegram.ext import CallbackContext, CommandHandler, run_async
5 |
6 |
7 | @run_async
8 | def convert(update: Update, context: CallbackContext):
9 | args = update.effective_message.text.split(" ")
10 |
11 | if len(args) == 4:
12 | try:
13 | orig_cur_amount = float(args[1])
14 |
15 | except ValueError:
16 | update.effective_message.reply_text("Invalid Amount Of Currency")
17 | return
18 |
19 | orig_cur = args[2].upper()
20 |
21 | new_cur = args[3].upper()
22 |
23 | request_url = (
24 | f"https://www.alphavantage.co/query"
25 | f"?function=CURRENCY_EXCHANGE_RATE"
26 | f"&from_currency={orig_cur}"
27 | f"&to_currency={new_cur}"
28 | f"&apikey={CASH_API_KEY}"
29 | )
30 | response = requests.get(request_url).json()
31 | try:
32 | current_rate = float(
33 | response["Realtime Currency Exchange Rate"]["5. Exchange Rate"]
34 | )
35 | except KeyError:
36 | update.effective_message.reply_text("Currency Not Supported.")
37 | return
38 | new_cur_amount = round(orig_cur_amount * current_rate, 5)
39 | update.effective_message.reply_text(
40 | f"{orig_cur_amount} {orig_cur} = {new_cur_amount} {new_cur}"
41 | )
42 |
43 | elif len(args) == 1:
44 | update.effective_message.reply_text(__help__, parse_mode=ParseMode.MARKDOWN)
45 |
46 | else:
47 | update.effective_message.reply_text(
48 | f"*Invalid Args!!:* Required 3 But Passed {len(args) -1}",
49 | parse_mode=ParseMode.MARKDOWN,
50 | )
51 |
52 |
53 | CONVERTER_HANDLER = CommandHandler("cash", convert)
54 |
55 | dispatcher.add_handler(CONVERTER_HANDLER)
56 |
57 | __command_list__ = ["cash"]
58 | __handlers__ = [CONVERTER_HANDLER]
59 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/userinfo_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from Tianabot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, BigInteger, UnicodeText
5 |
6 | class UserInfo(BASE):
7 | __tablename__ = "userinfo"
8 | user_id = Column(BigInteger, primary_key=True)
9 | info = Column(UnicodeText)
10 |
11 | def __init__(self, user_id, info):
12 | self.user_id = user_id
13 | self.info = info
14 |
15 | def __repr__(self):
16 | return "{}".format(e), parse_mode=ParseMode.HTML
33 | )
34 | if res:
35 | result = f"{search}\n\n"
36 | result += f"{res}\n"
37 | result += f"""Read more..."""
38 | if len(result) > 4000:
39 | with open("result.txt", "w") as f:
40 | f.write(f"{result}\n\nUwU OwO OmO UmU")
41 | with open("result.txt", "rb") as f:
42 | context.bot.send_document(
43 | document=f,
44 | filename=f.name,
45 | reply_to_message_id=update.message.message_id,
46 | chat_id=update.effective_chat.id,
47 | parse_mode=ParseMode.HTML,
48 | )
49 | else:
50 | update.message.reply_text(
51 | result, parse_mode=ParseMode.HTML, disable_web_page_preview=True
52 | )
53 |
54 | WIKI_HANDLER = DisableAbleCommandHandler("wiki", wiki)
55 | dispatcher.add_handler(WIKI_HANDLER)
56 |
--------------------------------------------------------------------------------
/Tianabot/modules/debug.py:
--------------------------------------------------------------------------------
1 | import os
2 | import datetime
3 |
4 | from telethon import events
5 | from telegram import Update
6 | from telegram.ext import CallbackContext, CommandHandler, run_async
7 |
8 | from Tianabot import telethn, dispatcher
9 | from Tianabot.modules.helper_funcs.chat_status import dev_plus
10 |
11 | DEBUG_MODE = False
12 |
13 |
14 | @run_async
15 | @dev_plus
16 | def debug(update: Update, context: CallbackContext):
17 | global DEBUG_MODE
18 | args = update.effective_message.text.split(None, 1)
19 | message = update.effective_message
20 | print(DEBUG_MODE)
21 | if len(args) > 1:
22 | if args[1] in ("yes", "on"):
23 | DEBUG_MODE = True
24 | message.reply_text("Debug mode is now on.")
25 | elif args[1] in ("no", "off"):
26 | DEBUG_MODE = False
27 | message.reply_text("Debug mode is now off.")
28 | else:
29 | if DEBUG_MODE:
30 | message.reply_text("Debug mode is currently on.")
31 | else:
32 | message.reply_text("Debug mode is currently off.")
33 |
34 |
35 | @telethn.on(events.NewMessage(pattern="[/!].*"))
36 | async def i_do_nothing_yes(event):
37 | global DEBUG_MODE
38 | if DEBUG_MODE:
39 | print(f"-{event.from_id} ({event.chat_id}) : {event.text}")
40 | if os.path.exists("updates.txt"):
41 | with open("updates.txt", "r") as f:
42 | text = f.read()
43 | with open("updates.txt", "w+") as f:
44 | f.write(text + f"\n-{event.from_id} ({event.chat_id}) : {event.text}")
45 | else:
46 | with open("updates.txt", "w+") as f:
47 | f.write(
48 | f"- {event.from_id} ({event.chat_id}) : {event.text} | {datetime.datetime.now()}"
49 | )
50 |
51 |
52 | support_chat = os.getenv("SUPPORT_CHAT")
53 |
54 |
55 | @run_async
56 | @dev_plus
57 | def logs(update: Update, context: CallbackContext):
58 | user = update.effective_user
59 | with open("log.txt", "rb") as f:
60 | context.bot.send_document(document=f, filename=f.name, chat_id=user.id)
61 |
62 |
63 | LOG_HANDLER = CommandHandler("logs", logs)
64 | dispatcher.add_handler(LOG_HANDLER)
65 |
66 | DEBUG_HANDLER = CommandHandler("debug", debug)
67 | dispatcher.add_handler(DEBUG_HANDLER)
68 |
69 | __mod_name__ = "Debug"
70 | __command_list__ = ["debug"]
71 | __handlers__ = [DEBUG_HANDLER]
72 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/afk_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from Tianabot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Boolean, Column, BigInteger, UnicodeText
5 |
6 | class AFK(BASE):
7 | __tablename__ = "afk_users"
8 |
9 | user_id = Column(BigInteger, primary_key=True)
10 | is_afk = Column(Boolean)
11 | reason = Column(UnicodeText)
12 |
13 | def __init__(self, user_id, reason="", is_afk=True):
14 | self.user_id = user_id
15 | self.reason = reason
16 | self.is_afk = is_afk
17 |
18 | def __repr__(self):
19 | return "afk_status for {}".format(self.user_id)
20 |
21 |
22 | AFK.__table__.create(checkfirst=True)
23 | INSERTION_LOCK = threading.RLock()
24 |
25 | AFK_USERS = {}
26 |
27 |
28 | def is_afk(user_id):
29 | return user_id in AFK_USERS
30 |
31 |
32 | def check_afk_status(user_id):
33 | try:
34 | return SESSION.query(AFK).get(user_id)
35 | finally:
36 | SESSION.close()
37 |
38 |
39 | def set_afk(user_id, reason=""):
40 | with INSERTION_LOCK:
41 | curr = SESSION.query(AFK).get(user_id)
42 | if not curr:
43 | curr = AFK(user_id, reason, True)
44 | else:
45 | curr.is_afk = True
46 |
47 | AFK_USERS[user_id] = reason
48 |
49 | SESSION.add(curr)
50 | SESSION.commit()
51 |
52 |
53 | def rm_afk(user_id):
54 | with INSERTION_LOCK:
55 | curr = SESSION.query(AFK).get(user_id)
56 | if curr:
57 | if user_id in AFK_USERS: # sanity check
58 | del AFK_USERS[user_id]
59 |
60 | SESSION.delete(curr)
61 | SESSION.commit()
62 | return True
63 |
64 | SESSION.close()
65 | return False
66 |
67 |
68 | def toggle_afk(user_id, reason=""):
69 | with INSERTION_LOCK:
70 | curr = SESSION.query(AFK).get(user_id)
71 | if not curr:
72 | curr = AFK(user_id, reason, True)
73 | elif curr.is_afk:
74 | curr.is_afk = False
75 | elif not curr.is_afk:
76 | curr.is_afk = True
77 | SESSION.add(curr)
78 | SESSION.commit()
79 |
80 |
81 | def __load_afk_users():
82 | global AFK_USERS
83 | try:
84 | all_afk = SESSION.query(AFK).all()
85 | AFK_USERS = {user.user_id: user.reason for user in all_afk if user.is_afk}
86 | finally:
87 | SESSION.close()
88 |
89 |
90 | __load_afk_users()
91 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/log_channel_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from Tianabot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, String, distinct, func
5 |
6 |
7 | class GroupLogs(BASE):
8 | __tablename__ = "log_channels"
9 | chat_id = Column(String(14), primary_key=True)
10 | log_channel = Column(String(14), nullable=False)
11 |
12 | def __init__(self, chat_id, log_channel):
13 | self.chat_id = str(chat_id)
14 | self.log_channel = str(log_channel)
15 |
16 |
17 | GroupLogs.__table__.create(checkfirst=True)
18 |
19 | LOGS_INSERTION_LOCK = threading.RLock()
20 |
21 | CHANNELS = {}
22 |
23 |
24 | def set_chat_log_channel(chat_id, log_channel):
25 | with LOGS_INSERTION_LOCK:
26 | res = SESSION.query(GroupLogs).get(str(chat_id))
27 | if res:
28 | res.log_channel = log_channel
29 | else:
30 | res = GroupLogs(chat_id, log_channel)
31 | SESSION.add(res)
32 |
33 | CHANNELS[str(chat_id)] = log_channel
34 | SESSION.commit()
35 |
36 |
37 | def get_chat_log_channel(chat_id):
38 | return CHANNELS.get(str(chat_id))
39 |
40 |
41 | def stop_chat_logging(chat_id):
42 | with LOGS_INSERTION_LOCK:
43 | res = SESSION.query(GroupLogs).get(str(chat_id))
44 | if res:
45 | if str(chat_id) in CHANNELS:
46 | del CHANNELS[str(chat_id)]
47 |
48 | log_channel = res.log_channel
49 | SESSION.delete(res)
50 | SESSION.commit()
51 | return log_channel
52 |
53 |
54 | def num_logchannels():
55 | try:
56 | return SESSION.query(func.count(distinct(GroupLogs.chat_id))).scalar()
57 | finally:
58 | SESSION.close()
59 |
60 |
61 | def migrate_chat(old_chat_id, new_chat_id):
62 | with LOGS_INSERTION_LOCK:
63 | chat = SESSION.query(GroupLogs).get(str(old_chat_id))
64 | if chat:
65 | chat.chat_id = str(new_chat_id)
66 | SESSION.add(chat)
67 | if str(old_chat_id) in CHANNELS:
68 | CHANNELS[str(new_chat_id)] = CHANNELS.get(str(old_chat_id))
69 |
70 | SESSION.commit()
71 |
72 |
73 | def __load_log_channels():
74 | global CHANNELS
75 | try:
76 | all_chats = SESSION.query(GroupLogs).all()
77 | CHANNELS = {chat.chat_id: chat.log_channel for chat in all_chats}
78 | finally:
79 | SESSION.close()
80 |
81 |
82 | __load_log_channels()
83 |
--------------------------------------------------------------------------------
/Tianabot/modules/speed_test.py:
--------------------------------------------------------------------------------
1 | import speedtest
2 | from Tianabot import DEV_USERS, dispatcher
3 | from Tianabot.modules.disable import DisableAbleCommandHandler
4 | from Tianabot.modules.helper_funcs.chat_status import dev_plus
5 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ParseMode, Update
6 | from telegram.ext import CallbackContext, CallbackQueryHandler, run_async
7 |
8 |
9 | def convert(speed):
10 | return round(int(speed) / 1048576, 2)
11 |
12 |
13 | @dev_plus
14 | @run_async
15 | def speedtestxyz(update: Update, context: CallbackContext):
16 | buttons = [
17 | [
18 | InlineKeyboardButton("Image", callback_data="speedtest_image"),
19 | InlineKeyboardButton("Text", callback_data="speedtest_text"),
20 | ]
21 | ]
22 | update.effective_message.reply_text(
23 | "Select Ping Mode", reply_markup=InlineKeyboardMarkup(buttons)
24 | )
25 |
26 |
27 | @run_async
28 | def speedtestxyz_callback(update: Update, context: CallbackContext):
29 | query = update.callback_query
30 |
31 | if query.from_user.id in DEV_USERS:
32 | msg = update.effective_message.edit_text("Pinging...")
33 | speed = speedtest.Speedtest()
34 | speed.get_best_server()
35 | speed.download()
36 | speed.upload()
37 | replymsg = "Ping Result:"
38 |
39 | if query.data == "speedtest_image":
40 | speedtest_image = speed.results.share()
41 | update.effective_message.reply_photo(
42 | photo=speedtest_image, caption=replymsg
43 | )
44 | msg.delete()
45 |
46 | elif query.data == "speedtest_text":
47 | result = speed.results.dict()
48 | replymsg += f"\nDownload: `{convert(result['download'])}Mb/s`\nUpload: `{convert(result['upload'])}Mb/s`\nPing: `{result['ping']}`"
49 | update.effective_message.edit_text(replymsg, parse_mode=ParseMode.MARKDOWN)
50 | else:
51 | query.answer("You are required to join Heroes Association to use this command.")
52 |
53 |
54 | SPEED_TEST_HANDLER = DisableAbleCommandHandler("ping", speedtestxyz)
55 | SPEED_TEST_CALLBACKHANDLER = CallbackQueryHandler(
56 | speedtestxyz_callback, pattern="speedtest_.*"
57 | )
58 |
59 | dispatcher.add_handler(SPEED_TEST_HANDLER)
60 | dispatcher.add_handler(SPEED_TEST_CALLBACKHANDLER)
61 |
62 | __command_list__ = ["ping"]
63 | __handlers__ = [SPEED_TEST_HANDLER, SPEED_TEST_CALLBACKHANDLER]
64 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/rss_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from Tianabot.modules.sql import BASE, SESSION
4 | from sqlalchemy import Column, BigInteger, UnicodeText
5 |
6 | class RSS(BASE):
7 | __tablename__ = "rss_feed"
8 | id = Column(BigInteger, primary_key=True)
9 | chat_id = Column(UnicodeText, nullable=False)
10 | feed_link = Column(UnicodeText)
11 | old_entry_link = Column(UnicodeText)
12 |
13 | def __init__(self, chat_id, feed_link, old_entry_link):
14 | self.chat_id = chat_id
15 | self.feed_link = feed_link
16 | self.old_entry_link = old_entry_link
17 |
18 | def __repr__(self):
19 | return "{translation.text}"
73 | )
74 |
75 | await message.reply_text(reply, parse_mode="html")
76 |
77 |
78 | def languages(update: Update, context: CallbackContext) -> None:
79 | update.effective_message.reply_text(
80 | "Click on the button below to see the list of supported language codes.",
81 | reply_markup=InlineKeyboardMarkup(
82 | [
83 | [
84 | InlineKeyboardButton(
85 | text="Language codes",
86 | url="https://telegra.ph/Lang-Codes-03-19-3",
87 | ),
88 | ],
89 | ],
90 | disable_web_page_preview=True,
91 | ),
92 | )
93 |
94 |
95 | LANG_HANDLER = DisableAbleCommandHandler("langs", languages)
96 |
97 | dispatcher.add_handler(LANG_HANDLER)
98 |
--------------------------------------------------------------------------------
/Tianabot/modules/dev.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | import sys
4 |
5 | from contextlib import suppress
6 | from time import sleep
7 |
8 | import Tianabot
9 |
10 | from Tianabot import dispatcher
11 | from Tianabot.modules.helper_funcs.chat_status import dev_plus
12 | from telegram import TelegramError, Update
13 | from telegram.error import Unauthorized
14 | from telegram.ext import CallbackContext, CommandHandler, run_async
15 |
16 | @run_async
17 | @dev_plus
18 | def allow_groups(update: Update, context: CallbackContext):
19 | args = context.args
20 | if not args:
21 | update.effective_message.reply_text(f"Current state: {Tianabot.ALLOW_CHATS}")
22 | return
23 | if args[0].lower() in ["off", "no"]:
24 | Tianabot.ALLOW_CHATS = True
25 | elif args[0].lower() in ["yes", "on"]:
26 | Tianabot.ALLOW_CHATS = False
27 | else:
28 | update.effective_message.reply_text("Format: /lockdown Yes/No or Off/On")
29 | return
30 | update.effective_message.reply_text("Done! Lockdown value toggled.")
31 |
32 | @run_async
33 | @dev_plus
34 | def leave(update: Update, context: CallbackContext):
35 | bot = context.bot
36 | args = context.args
37 | if args:
38 | chat_id = str(args[0])
39 | try:
40 | bot.leave_chat(int(chat_id))
41 | except TelegramError:
42 | update.effective_message.reply_text(
43 | "Beep boop, I could not leave that group(dunno why tho)."
44 | )
45 | return
46 | with suppress(Unauthorized):
47 | update.effective_message.reply_text("Beep boop, I left that soup!.")
48 | else:
49 | update.effective_message.reply_text("Send a valid chat ID")
50 |
51 |
52 | @run_async
53 | @dev_plus
54 | def gitpull(update: Update, context: CallbackContext):
55 | sent_msg = update.effective_message.reply_text(
56 | "Pulling all changes from remote and then attempting to restart."
57 | )
58 | subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)
59 |
60 | sent_msg_text = sent_msg.text + "\n\nChanges pulled...I guess.. Restarting in "
61 |
62 | for i in reversed(range(5)):
63 | sent_msg.edit_text(sent_msg_text + str(i + 1))
64 | sleep(1)
65 |
66 | sent_msg.edit_text("Restarted.")
67 |
68 | os.system("restart.bat")
69 | os.execv("start.bat", sys.argv)
70 |
71 |
72 | @run_async
73 | @dev_plus
74 | def restart(update: Update, context: CallbackContext):
75 | update.effective_message.reply_text(
76 | "Starting a new instance and shutting down this one"
77 | )
78 |
79 | os.system("restart.bat")
80 | os.execv("start.bat", sys.argv)
81 |
82 |
83 | LEAVE_HANDLER = CommandHandler("leave", leave)
84 | GITPULL_HANDLER = CommandHandler("gitpull", gitpull)
85 | RESTART_HANDLER = CommandHandler("reboot", restart)
86 | ALLOWGROUPS_HANDLER = CommandHandler("lockdown", allow_groups)
87 |
88 | dispatcher.add_handler(ALLOWGROUPS_HANDLER)
89 | dispatcher.add_handler(LEAVE_HANDLER)
90 | dispatcher.add_handler(GITPULL_HANDLER)
91 | dispatcher.add_handler(RESTART_HANDLER)
92 |
93 | __mod_name__ = "ᴇᴠs"
94 | __handlers__ = [LEAVE_HANDLER, GITPULL_HANDLER, RESTART_HANDLER, ALLOWGROUPS_HANDLER]
95 |
--------------------------------------------------------------------------------
/Tianabot/modules/helper_funcs/telethn/chatstatus.py:
--------------------------------------------------------------------------------
1 | from Tianabot.modules.helper_funcs.telethn import IMMUNE_USERS, telethn
2 | from Tianabot import DRAGONS
3 | from telethon.tl.types import ChannelParticipantsAdmins
4 |
5 |
6 | async def user_is_ban_protected(user_id: int, message):
7 | status = False
8 | if message.is_private or user_id in (IMMUNE_USERS):
9 | return True
10 |
11 | async for user in telethn.iter_participants(
12 | message.chat_id, filter=ChannelParticipantsAdmins
13 | ):
14 | if user_id == user.id:
15 | status = True
16 | break
17 | return status
18 |
19 |
20 | async def user_is_admin(user_id: int, message):
21 | status = False
22 | if message.is_private:
23 | return True
24 |
25 | async for user in telethn.iter_participants(
26 | message.chat_id, filter=ChannelParticipantsAdmins
27 | ):
28 | if user_id == user.id or user_id in DRAGONS:
29 | status = True
30 | break
31 | return status
32 |
33 |
34 | async def is_user_admin(user_id: int, chat_id):
35 | status = False
36 | async for user in telethn.iter_participants(
37 | chat_id, filter=ChannelParticipantsAdmins
38 | ):
39 | if user_id == user.id or user_id in DRAGONS:
40 | status = True
41 | break
42 | return status
43 |
44 |
45 | async def masha_is_admin(chat_id: int):
46 | status = False
47 | masha = await telethn.get_me()
48 | async for user in telethn.iter_participants(
49 | chat_id, filter=ChannelParticipantsAdmins
50 | ):
51 | if masha.id == user.id:
52 | status = True
53 | break
54 | return status
55 |
56 |
57 | async def is_user_in_chat(chat_id: int, user_id: int):
58 | status = False
59 | async for user in telethn.iter_participants(chat_id):
60 | if user_id == user.id:
61 | status = True
62 | break
63 | return status
64 |
65 |
66 | async def can_change_info(message):
67 | status = False
68 | if message.chat.admin_rights:
69 | status = message.chat.admin_rights.change_info
70 | return status
71 |
72 |
73 | async def can_ban_users(message):
74 | status = False
75 | if message.chat.admin_rights:
76 | status = message.chat.admin_rights.ban_users
77 | return status
78 |
79 |
80 | async def can_pin_messages(message):
81 | status = False
82 | if message.chat.admin_rights:
83 | status = message.chat.admin_rights.pin_messages
84 | return status
85 |
86 |
87 | async def can_invite_users(message):
88 | status = False
89 | if message.chat.admin_rights:
90 | status = message.chat.admin_rights.invite_users
91 | return status
92 |
93 |
94 | async def can_add_admins(message):
95 | status = False
96 | if message.chat.admin_rights:
97 | status = message.chat.admin_rights.add_admins
98 | return status
99 |
100 |
101 | async def can_delete_messages(message):
102 |
103 | if message.is_private:
104 | return True
105 | elif message.chat.admin_rights:
106 | status = message.chat.admin_rights.delete_messages
107 | return status
108 | else:
109 | return False
110 |
--------------------------------------------------------------------------------
/Tianabot/modules/tagall.py:
--------------------------------------------------------------------------------
1 | import os
2 | import asyncio
3 | from telethon import Button
4 | from telethon import TelegramClient, events
5 | from telethon.tl.types import ChannelParticipantAdmin
6 | from telethon.tl.types import ChannelParticipantCreator
7 | from telethon.tl.functions.channels import GetParticipantRequest
8 | from telethon.errors import UserNotParticipantError
9 | from Tianabot import telethn as client
10 |
11 |
12 | spam_chats = []
13 |
14 | @client.on(events.NewMessage(pattern="^/tagall ?(.*)"))
15 | @client.on(events.NewMessage(pattern="^@all ?(.*)"))
16 | async def mentionall(event):
17 | chat_id = event.chat_id
18 | if event.is_private:
19 | return await event.respond("__This command can be use in groups and channels!__")
20 |
21 | is_admin = False
22 | try:
23 | partici_ = await client(GetParticipantRequest(
24 | event.chat_id,
25 | event.sender_id
26 | ))
27 | except UserNotParticipantError:
28 | is_admin = False
29 | else:
30 | if (
31 | isinstance(
32 | partici_.participant,
33 | (
34 | ChannelParticipantAdmin,
35 | ChannelParticipantCreator
36 | )
37 | )
38 | ):
39 | is_admin = True
40 | if not is_admin:
41 | return await event.respond("__Only admins can mention all!__")
42 |
43 | if event.pattern_match.group(1) and event.is_reply:
44 | return await event.respond("__Give me one argument!__")
45 | elif event.pattern_match.group(1):
46 | mode = "text_on_cmd"
47 | msg = event.pattern_match.group(1)
48 | elif event.is_reply:
49 | mode = "text_on_reply"
50 | msg = await event.get_reply_message()
51 | if msg == None:
52 | return await event.respond("__I can't mention members for older messages! (messages which are sent before I'm added to group)__")
53 | else:
54 | return await event.respond("__Reply to a message or give me some text to mention others!__")
55 |
56 | spam_chats.append(chat_id)
57 | usrnum = 0
58 | usrtxt = ''
59 | async for usr in client.iter_participants(chat_id):
60 | if not chat_id in spam_chats:
61 | break
62 | usrnum += 1
63 | usrtxt += f"[{usr.first_name}](tg://user?id={usr.id}), "
64 | if usrnum == 5:
65 | if mode == "text_on_cmd":
66 | txt = f"{msg}\n{usrtxt}"
67 | await client.send_message(chat_id, txt)
68 | elif mode == "text_on_reply":
69 | await msg.reply(usrtxt)
70 | await asyncio.sleep(2)
71 | usrnum = 0
72 | usrtxt = ''
73 | try:
74 | spam_chats.remove(chat_id)
75 | except:
76 | pass
77 |
78 | @client.on(events.NewMessage(pattern="^/cancel$"))
79 | async def cancel_spam(event):
80 | if not event.chat_id in spam_chats:
81 | return await event.respond("__There is no proccess on going...__")
82 | is_admin = False
83 | try:
84 | partici_ = await client(GetParticipantRequest(
85 | event.chat_id,
86 | event.sender_id
87 | ))
88 | except UserNotParticipantError:
89 | is_admin = False
90 | else:
91 | if (
92 | isinstance(
93 | partici_.participant,
94 | (
95 | ChannelParticipantAdmin,
96 | ChannelParticipantCreator
97 | )
98 | )
99 | ):
100 | is_admin = True
101 | if not is_admin:
102 | return await event.respond("__Only admins can execute this command!__")
103 |
104 | else:
105 | try:
106 | spam_chats.remove(event.chat_id)
107 | except:
108 | pass
109 | return await event.respond("__Stopped Mention.__")
110 |
111 |
--------------------------------------------------------------------------------
/Tianabot/modules/speechtotext.py:
--------------------------------------------------------------------------------
1 | import os
2 | import urllib.request
3 | from datetime import datetime
4 | from typing import List
5 | from typing import Optional
6 | import requests
7 | from telethon import *
8 | from telethon import events
9 | from telethon.tl import functions
10 | from telethon.tl import types
11 | from telethon.tl.types import *
12 |
13 | from Tianabot import *
14 | from Tianabot.events import register
15 | from Tianabot import telethn as tbot
16 |
17 |
18 | async def is_register_admin(chat, user):
19 | if isinstance(chat, (types.InputPeerChannel, types.InputChannel)):
20 | return isinstance(
21 | (
22 | await tbot(functions.channels.GetParticipantRequest(chat, user))
23 | ).participant,
24 | (types.ChannelParticipantAdmin, types.ChannelParticipantCreator),
25 | )
26 | if isinstance(chat, types.InputPeerUser):
27 | return True
28 |
29 |
30 | @register(pattern="^/stt$")
31 | async def _(event):
32 | if event.fwd_from:
33 | return
34 | start = datetime.now()
35 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
36 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
37 |
38 | if event.reply_to_msg_id:
39 | previous_message = await event.get_reply_message()
40 | required_file_name = await event.client.download_media(
41 | previous_message, TEMP_DOWNLOAD_DIRECTORY
42 | )
43 | if IBM_WATSON_CRED_URL is None or IBM_WATSON_CRED_PASSWORD is None:
44 | await event.reply(
45 | "You need to set the required ENV variables for this module. \nModule stopping"
46 | )
47 | else:
48 | # await event.reply("Starting analysis")
49 | headers = {
50 | "Content-Type": previous_message.media.document.mime_type,
51 | }
52 | data = open(required_file_name, "rb").read()
53 | response = requests.post(
54 | IBM_WATSON_CRED_URL + "/v1/recognize",
55 | headers=headers,
56 | data=data,
57 | auth=("apikey", IBM_WATSON_CRED_PASSWORD),
58 | )
59 | r = response.json()
60 | if "results" in r:
61 | # process the json to appropriate string format
62 | results = r["results"]
63 | transcript_response = ""
64 | transcript_confidence = ""
65 | for alternative in results:
66 | alternatives = alternative["alternatives"][0]
67 | transcript_response += " " + str(alternatives["transcript"])
68 | transcript_confidence += (
69 | " " + str(alternatives["confidence"]) + " + "
70 | )
71 | end = datetime.now()
72 | ms = (end - start).seconds
73 | if transcript_response != "":
74 | string_to_show = "TRANSCRIPT: `{}`\nTime Taken: {} seconds\nConfidence: `{}`".format(
75 | transcript_response, ms, transcript_confidence
76 | )
77 | else:
78 | string_to_show = "TRANSCRIPT: `Nil`\nTime Taken: {} seconds\n\n**No Results Found**".format(
79 | ms
80 | )
81 | await event.reply(string_to_show)
82 | else:
83 | await event.reply(r["error"])
84 | # now, remove the temporary file
85 | os.remove(required_file_name)
86 | else:
87 | await event.reply("Reply to a voice message, to get the text out of it.")
88 |
--------------------------------------------------------------------------------
/Tianabot/config.py:
--------------------------------------------------------------------------------
1 | # Create a new config.py or rename this to config.py file in same dir and import, then extend this class.
2 | import json
3 | import os
4 |
5 |
6 | def get_user_list(config, key):
7 | with open("{}/Tianabot/{}".format(os.getcwd(), config), "r") as json_file:
8 | return json.load(json_file)[key]
9 |
10 |
11 | # Create a new config.py or rename this to config.py file in same dir and import, then extend this class.
12 | class Config(object):
13 | LOGGER = True
14 | # REQUIRED
15 | # Login to https://my.telegram.org and fill in these slots with the details given by it
16 |
17 | API_ID = 123456 # integer value, dont use ""
18 | API_HASH = "awoo"
19 | TOKEN = "BOT_TOKEN" # This var used to be API_KEY but it is now TOKEN, adjust accordingly.
20 | OWNER_ID = 792109647 # If you dont know, run the bot and do /id in your private chat with it, also an integer
21 | OWNER_USERNAME = "Sawada"
22 | SUPPORT_CHAT = "OnePunchSupport" # Your own group for support, do not add the @
23 | JOIN_LOGGER = (
24 | -1001253661229
25 | ) # Prints any new group the bot is added to, prints just the name and ID.
26 | EVENT_LOGS = (
27 | -1001190806654
28 | ) # Prints information like gbans, sudo promotes, AI enabled disable states that may help in debugging and shit
29 |
30 | # RECOMMENDED
31 | SQLALCHEMY_DATABASE_URI = "something://somewhat:user@hosturl:port/databasename" # needed for any database module
32 | LOAD = []
33 | NO_LOAD = ["rss", "cleaner", "connection", "math"]
34 | WEBHOOK = False
35 | INFOPIC = True
36 | URL = None
37 | SPAMWATCH_API = "" # go to support.spamwat.ch to get key
38 | SPAMWATCH_SUPPORT_CHAT = "@SpamWatchSupport"
39 |
40 | # OPTIONAL
41 | ##List of id's - (not usernames) for users which have sudo access to the bot.
42 | DRAGONS = get_user_list("elevated_users.json", "sudos")
43 | ##List of id's - (not usernames) for developers who will have the same perms as the owner
44 | DEV_USERS = get_user_list("elevated_users.json", "devs")
45 | ##List of id's (not usernames) for users which are allowed to gban, but can also be banned.
46 | DEMONS = get_user_list("elevated_users.json", "supports")
47 | # List of id's (not usernames) for users which WONT be banned/kicked by the bot.
48 | TIGERS = get_user_list("elevated_users.json", "tigers")
49 | WOLVES = get_user_list("elevated_users.json", "whitelists")
50 | DONATION_LINK = None # EG, paypal
51 | CERT_PATH = None
52 | PORT = 5000
53 | DEL_CMDS = True # Delete commands that users dont have access to, like delete /ban if a non admin uses it.
54 | STRICT_GBAN = True
55 | WORKERS = (
56 | 8 # Number of subthreads to use. Set as number of threads your processor uses
57 | )
58 | BAN_STICKER = "" # banhammer marie sticker id, the bot will send this sticker before banning or kicking a user in chat.
59 | ALLOW_EXCL = True # Allow ! commands as well as / (Leave this to true so that blacklist can work)
60 | CASH_API_KEY = (
61 | "awoo" # Get your API key from https://www.alphavantage.co/support/#api-key
62 | )
63 | TIME_API_KEY = "awoo" # Get your API key from https://timezonedb.com/api
64 | WALL_API = (
65 | "awoo" # For wallpapers, get one from https://wall.alphacoders.com/api.php
66 | )
67 | AI_API_KEY = "awoo" # For chatbot, get one from https://coffeehouse.intellivoid.net/dashboard
68 | BL_CHATS = [] # List of groups that you want blacklisted.
69 | SPAMMERS = None
70 |
71 | class Production(Config):
72 | LOGGER = True
73 |
74 |
75 | class Development(Config):
76 | LOGGER = True
77 |
--------------------------------------------------------------------------------
/Tianabot/modules/truth_and_dare_string.py:
--------------------------------------------------------------------------------
1 | TRUTH = (
2 | "Have you ghosted someone?"
3 | "Have you ever walked in on your parents doing 'it'?",
4 | "Who was the last person you liked the most? Why?",
5 | "Have you ever been suspended from school?",
6 | "If you had to choose between going naked or having your thoughts appear in thought bubbles above your head for everyone to read, which would you choose?",
7 | "What’s the one thing you’re afraid to lose?",
8 | "Do you like someone as of the moment?",
9 | "One thing about your best friend you are jealous of?",
10 | "Would you cheat on your boyfriend for a rich guy?",
11 | "What is your biggest turn on?",
12 | "When’s the last time you lied to your parents and why?",
13 | "Describe your ideal partner.",
14 | "What’s the scariest thing you’ve ever done?",
15 | "Have you ever picked your nose and eaten it?",
16 | "When’s the last time you lied to your parents and why?",
17 | "Have you ever lied about your age to participate in a contest?",
18 | "Have you ever been caught checking someone out?",
19 |
20 | )
21 |
22 | DARE = (
23 | "Show the most embarrassing photo on your phone"
24 | "Show the last five people you texted and what the messages said",
25 | "Let the rest of the group DM someone from your Instagram account",
26 | "Eat a raw piece of garlic",
27 | "Do 100 squats",
28 | "Keep three ice cubes in your mouth until they melt",
29 | "Say something dirty to the person on your leftYou've got company!",
30 | "Give a foot massage to the person on your right",
31 | "Put 10 different available liquids into a cup and drink it",
32 | "*Yell out the first word that comes to your mind",
33 | "Give a lap dance to someone of your choice",
34 | "Remove four items of clothing",
35 | "Like the first 15 posts on your Facebook newsfeed",
36 | "Eat a spoonful of mustard",
37 | "Keep your eyes closed until it's your go again",
38 | "Send a sext to the last person in your phonebook",
39 | "Show off your orgasm face",
40 | "Seductively eat a banana",
41 | "Empty out your wallet/purse and show everyone what's inside",
42 | "Do your best sexy crawl",
43 | "Pretend to be the person to your right for 10 minutes",
44 | "Eat a snack without using your hands",
45 | "Say two honest things about everyone else in the group",
46 | "Twerk for a minute",
47 | "Try and make the group laugh as quickly as possible",
48 | "Try to put your whole fist in your mouth",
49 | "Tell everyone an embarrassing story about yourself",
50 | "Try to lick your elbow",
51 | "Post the oldest selfie on your phone on Instagram Stories",
52 | "Tell the saddest story you know",
53 | "Howl like a wolf for two minutes",
54 | "Dance without music for two minutes",
55 | "Pole dance with an imaginary pole",
56 | "Let someone else tickle you and try not to laugh",
57 | "Put as many snacks into your mouth at once as you can",
58 | "Send your most recent selfie.",
59 | "Send your ugliest selfie.",
60 | "Send a screenshot of your facebook search history",
61 | "Send a screenshot of your gallery.",
62 | "Send a screenshot of your messenger inbox",
63 | "Tell something very intimate.",
64 | "Send a screenshot of your twitter inbox",
65 | "Send a screenshot of your homescreen.",
66 | "Send a cover of your favorite song. 🎤",
67 | "Do a lyric prank on someone and send proof.",
68 | "Confess to your current crush. ❤️",
69 | "Declare who is your true love.",
70 | "Send a screenshot of your gallery.",
71 | "Set your crush’s picture as your dp.",
72 | "Suggest me more dares.",
73 | )
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
7 | Ready-To-Use Bot • 8 | Documentation • 9 | Update Channel • 10 | Support Chat 11 |
12 | 13 | # Tiana Bot 14 | #### Tiana is a Telegram group managment bot made using Telethon and Pyrogram which makes it modern and faster than most of the exisitng Telegram Chat Managers. 15 |
{ping_time} (Status: {r.status_code})"
64 |
65 | ping_text = f"{pinged_site}: {ping_time}"
66 | ping_result.append(ping_text)
67 |
68 | return ping_result
69 |
70 |
71 | @run_async
72 | @sudo_plus
73 | def ping(update: Update, context: CallbackContext):
74 | msg = update.effective_message
75 |
76 | start_time = time.time()
77 | message = msg.reply_text("Pinging...")
78 | end_time = time.time()
79 | telegram_ping = str(round((end_time - start_time) * 1000, 3)) + " ms"
80 | uptime = get_readable_time((time.time() - StartTime))
81 |
82 | message.edit_text(
83 | "PONG!!\n"
84 | "Time Taken: {}\n"
85 | "Service uptime: {}".format(telegram_ping, uptime),
86 | parse_mode=ParseMode.HTML,
87 | )
88 |
89 |
90 | @run_async
91 | @sudo_plus
92 | def pingall(update: Update, context: CallbackContext):
93 | to_ping = ["Kaizoku", "Kayo", "Telegram", "Jikan"]
94 | pinged_list = ping_func(to_ping)
95 | pinged_list.insert(2, "")
96 | uptime = get_readable_time((time.time() - StartTime))
97 |
98 | reply_msg = "⏱Ping results are:\n"
99 | reply_msg += "\n".join(pinged_list)
100 | reply_msg += "\nService uptime: {}".format(uptime)
101 |
102 | update.effective_message.reply_text(
103 | reply_msg, parse_mode=ParseMode.HTML, disable_web_page_preview=True
104 | )
105 |
106 |
107 | PING_HANDLER = DisableAbleCommandHandler("alive", ping)
108 | PINGALL_HANDLER = DisableAbleCommandHandler("pingall", pingall)
109 |
110 | dispatcher.add_handler(PING_HANDLER)
111 | dispatcher.add_handler(PINGALL_HANDLER)
112 |
113 | __command_list__ = ["alive", "pingall"]
114 | __handlers__ = [PING_HANDLER, PINGALL_HANDLER]
115 |
--------------------------------------------------------------------------------
/Tianabot/modules/img2pdf.py:
--------------------------------------------------------------------------------
1 | """
2 | MIT License
3 | Copyright (c) 2021 TheHamkerCat
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including witout limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 | SOFTWARE.
19 | """
20 | from io import BytesIO
21 | from os import path, remove
22 | from time import time
23 |
24 | import img2pdf
25 | from PIL import Image
26 | from pyrogram import filters
27 | from pyrogram.types import Message
28 |
29 | from Tianabot import pbot as app
30 | from Tianabot.utils.errors import capture_err
31 | from Tianabot.utils.sections import section
32 |
33 |
34 | async def convert(
35 | main_message: Message,
36 | reply_messages,
37 | status_message: Message,
38 | start_time: float,
39 | ):
40 | m = status_message
41 |
42 | documents = []
43 |
44 | for message in reply_messages:
45 | if not message.document:
46 | return await m.edit("Not document, ABORTED!")
47 |
48 | if message.document.mime_type.split("/")[0] != "image":
49 | return await m.edit("Invalid mime type!")
50 |
51 | if message.document.file_size > 5000000:
52 | return await m.edit("Size too large, ABORTED!")
53 | documents.append(await message.download())
54 |
55 | for img_path in documents:
56 | img = Image.open(img_path).convert("RGB")
57 | img.save(img_path, "JPEG", quality=100)
58 |
59 | pdf = BytesIO(img2pdf.convert(documents))
60 | pdf.name = "Tianabot.pdf"
61 |
62 | if len(main_message.command) >= 2:
63 | pdf.name = main_message.text.split(None, 1)[1]
64 |
65 | elapsed = round(time() - start_time, 2)
66 |
67 | await main_message.reply_document(
68 | document=pdf,
69 | caption=section(
70 | "IMG2PDF",
71 | body={
72 | "Title": pdf.name,
73 | "Size": f"{pdf.__sizeof__() / (10**6)}MB",
74 | "Pages": len(documents),
75 | "Took": f"{elapsed}s",
76 | },
77 | ),
78 | )
79 |
80 | await m.delete()
81 | pdf.close()
82 | for file in documents:
83 | if path.exists(file):
84 | remove(file)
85 |
86 |
87 | @app.on_message(filters.command("pdf"))
88 | @capture_err
89 | async def img_to_pdf(_, message: Message):
90 | reply = message.reply_to_message
91 | if not reply:
92 | return await message.reply(
93 | "Reply to an image (as document) or group of images."
94 | )
95 |
96 | m = await message.reply_text("Converting..")
97 | start_time = time()
98 |
99 | if reply.media_group_id:
100 | messages = await app.get_media_group(
101 | message.chat.id,
102 | reply.message_id,
103 | )
104 | return await convert(message, messages, m, start_time)
105 |
106 | return await convert(message, [reply], m, start_time)
107 |
--------------------------------------------------------------------------------
/Tianabot/modules/sql/antiflood_sql.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | from sqlalchemy import String, Column, BigInteger, UnicodeText
4 |
5 | from Tianabot.modules.sql import SESSION, BASE
6 |
7 | DEF_COUNT = 1
8 | DEF_LIMIT = 0
9 | DEF_OBJ = (None, DEF_COUNT, DEF_LIMIT)
10 |
11 | class FloodControl(BASE):
12 | __tablename__ = "antiflood"
13 | chat_id = Column(String(14), primary_key=True)
14 | user_id = Column(BigInteger)
15 | count = Column(BigInteger, default=DEF_COUNT)
16 | limit = Column(BigInteger, default=DEF_LIMIT)
17 |
18 | def __init__(self, chat_id):
19 | self.chat_id = str(chat_id) # ensure string
20 |
21 | def __repr__(self):
22 | return "{e}",
90 | parse_mode="html",
91 | )
92 | return
93 | key = key.get("result").get("key")
94 | url = f"https://nekobin.com/{key}.py"
95 | context.bot.send_message(
96 | OWNER_ID,
97 | text=f"#{context.error.identifier}\nAn unknown error occured:\n{e}",
98 | reply_markup=InlineKeyboardMarkup(
99 | [[InlineKeyboardButton("Nekobin", url=url)]]
100 | ),
101 | parse_mode="html",
102 | )
103 |
104 |
105 | def list_errors(update: Update, context: CallbackContext):
106 | if update.effective_user.id not in DEV_USERS:
107 | return
108 | e = {
109 | k: v for k, v in sorted(errors.items(), key=lambda item: item[1], reverse=True)
110 | }
111 | msg = "Errors List:\n"
112 | for x in e:
113 | msg += f"• {x}: {e[x]} #{x.identifier}\n"
114 | msg += f"{len(errors)} have occurred since startup."
115 | if len(msg) > 4096:
116 | with open("errors_msg.txt", "w+") as f:
117 | f.write(msg)
118 | context.bot.send_document(
119 | update.effective_chat.id,
120 | open("errors_msg.txt", "rb"),
121 | caption=f"Too many errors have occured..",
122 | parse_mode="html",
123 | )
124 | return
125 | update.effective_message.reply_text(msg, parse_mode="html")
126 |
127 |
128 | dispatcher.add_error_handler(error_callback)
129 | dispatcher.add_handler(CommandHandler("errors", list_errors))
130 |
--------------------------------------------------------------------------------
/Tianabot/modules/telegraph.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from Tianabot.events import register
4 | from Tianabot import telethn as Client
5 | from telethon import events, Button, types
6 |
7 | TMP_DOWNLOAD_DIRECTORY = "./"
8 |
9 | from PIL import Image
10 | from datetime import datetime
11 | from telegraph import Telegraph, upload_file, exceptions
12 |
13 |
14 | wibu = "Tianabot"
15 | telegraph = Telegraph()
16 | data = telegraph.create_account(short_name=wibu)
17 | auth_url = data["auth_url"]
18 |
19 |
20 | @register(pattern="^/t(m|xt) ?(.*)")
21 | async def telegrap(event):
22 | optional_title = event.pattern_match.group(2)
23 | if event.reply_to_msg_id:
24 | start = datetime.now()
25 | reply_msg = await event.get_reply_message()
26 | input_str = event.pattern_match.group(1)
27 | if input_str == "gm":
28 | downloaded_file_name = await Client.download_media(
29 | reply_msg,
30 | TMP_DOWNLOAD_DIRECTORY
31 | )
32 | end = datetime.now()
33 | ms = (end - start).seconds
34 | if not downloaded_file_name:
35 | await Client.send_message(
36 | event.chat_id,
37 | "Not Supported Format Media!"
38 | )
39 | return
40 | else:
41 | if downloaded_file_name.endswith((".webp")):
42 | resize_image(downloaded_file_name)
43 | try:
44 | start = datetime.now()
45 | media_urls = upload_file(downloaded_file_name)
46 | except exceptions.TelegraphException as exc:
47 | await event.reply("ERROR: " + str(exc))
48 | os.remove(downloaded_file_name)
49 | else:
50 | end = datetime.now()
51 | ms_two = (end - start).seconds
52 | os.remove(downloaded_file_name)
53 | await Client.send_message(
54 | event.chat_id,
55 | "Your telegraph is complete uploaded!",
56 | buttons=[
57 | [
58 | types.KeyboardButtonUrl(
59 | "➡ View Telegraph", "https://telegra.ph{}".format(media_urls[0], (ms + ms_two))
60 | )
61 | ]
62 | ]
63 | )
64 | elif input_str == "xt":
65 | user_object = await Client.get_entity(reply_msg.sender_id)
66 | title_of_page = user_object.first_name # + " " + user_object.last_name
67 | # apparently, all Users do not have last_name field
68 | if optional_title:
69 | title_of_page = optional_title
70 | page_content = reply_msg.message
71 | if reply_msg.media:
72 | if page_content != "":
73 | title_of_page = page_content
74 | else:
75 | await Client.send_message(
76 | event.chat_id,
77 | "Not Supported Format Text!"
78 | )
79 | downloaded_file_name = await Client.download_media(
80 | reply_msg,
81 | TMP_DOWNLOAD_DIRECTORY
82 | )
83 | m_list = None
84 | with open(downloaded_file_name, "rb") as fd:
85 | m_list = fd.readlines()
86 | for m in m_list:
87 | page_content += m.decode("UTF-8") + "\n"
88 | os.remove(downloaded_file_name)
89 | page_content = page_content.replace("\n", "