Skip to content

Commit 7c68ed6

Browse files
authored
Merge pull request #36 from SHABIN-K/main
add broadcast command
2 parents 082ef35 + 39cc27a commit 7c68ed6

File tree

7 files changed

+144
-3
lines changed

7 files changed

+144
-3
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ python3 main.py
6969
7070
/genlink - create link for one post
7171
72+
/users - view bot statistics
73+
74+
/broadcast - broadcast any messages to bot users
7275
```
7376

7477
### Variables

config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#OWNER ID
1818
OWNER_ID = int(os.environ.get("OWNER_ID", ""))
1919

20+
#Database
21+
DB_URI = os.environ.get("DATABASE_URL", "")
22+
2023
#force sub channel id, if you want enable force sub
2124
FORCE_SUB_CHANNEL = int(os.environ.get("FORCE_SUB_CHANNEL", "0"))
2225

database/sql.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
import os
3+
import threading
4+
from sqlalchemy import create_engine
5+
from sqlalchemy import Column, TEXT, Numeric
6+
from sqlalchemy.ext.declarative import declarative_base
7+
from sqlalchemy.orm import sessionmaker, scoped_session
8+
from config import DB_URI
9+
10+
def start() -> scoped_session:
11+
engine = create_engine(DB_URI, client_encoding="utf8")
12+
BASE.metadata.bind = engine
13+
BASE.metadata.create_all(engine)
14+
return scoped_session(sessionmaker(bind=engine, autoflush=False))
15+
16+
17+
BASE = declarative_base()
18+
SESSION = start()
19+
20+
INSERTION_LOCK = threading.RLock()
21+
22+
class Broadcast(BASE):
23+
__tablename__ = "broadcast"
24+
id = Column(Numeric, primary_key=True)
25+
user_name = Column(TEXT)
26+
27+
def __init__(self, id, user_name):
28+
self.id = id
29+
self.user_name = user_name
30+
31+
Broadcast.__table__.create(checkfirst=True)
32+
33+
34+
# Add user details -
35+
async def add_user(id, user_name):
36+
with INSERTION_LOCK:
37+
msg = SESSION.query(Broadcast).get(id)
38+
if not msg:
39+
usr = Broadcast(id, user_name)
40+
SESSION.add(usr)
41+
SESSION.commit()
42+
else:
43+
pass
44+
45+
async def query_msg():
46+
try:
47+
query = SESSION.query(Broadcast.id).order_by(Broadcast.id)
48+
return query
49+
finally:
50+
SESSION.close()

database/support.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import asyncio
2+
from database.sql import query_msg
3+
from pyrogram.errors import FloodWait
4+
5+
async def users_info(bot):
6+
users = 0
7+
blocked = 0
8+
identity = await query_msg()
9+
for id in identity:
10+
name = bool()
11+
try:
12+
name = await bot.send_chat_action(int(id[0]), "typing")
13+
except FloodWait as e:
14+
await asyncio.sleep(e.x)
15+
except Exception:
16+
pass
17+
if bool(name):
18+
users += 1
19+
else:
20+
blocked += 1
21+
return users, blocked

plugins/channel_post.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from config import ADMINS, CHANNEL_ID, DISABLE_CHANNEL_BUTTON
1010
from helper_func import encode
1111

12-
@Bot.on_message(filters.private & filters.user(ADMINS) & ~filters.command(['start','batch','genlink']))
12+
@Bot.on_message(filters.private & filters.user(ADMINS) & ~filters.command(['start','users','broadcast','batch','genlink']))
1313
async def channel_post(client: Client, message: Message):
1414
reply_text = await message.reply_text("Please Wait...!", quote = True)
1515
try:

plugins/start.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#(©)Codexbotz
2-
2+
import os
33
import asyncio
44
from pyrogram import Client, filters, __version__
55
from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
@@ -8,9 +8,27 @@
88
from bot import Bot
99
from config import ADMINS, START_MSG, OWNER_ID, CUSTOM_CAPTION, DISABLE_CHANNEL_BUTTON
1010
from helper_func import subscribed, encode, decode, get_messages
11+
from database.support import users_info
12+
from database.sql import add_user, query_msg
13+
14+
15+
#=====================================================================================##
16+
17+
USERS_LIST = """<b>⭕️Total:</b>\n\n⭕️Subscribers - {}\n⭕️Blocked- {}"""
18+
19+
WAIT_MSG = """"<b>Processing ...</b>"""
20+
21+
REPLY_ERROR = """<code>Use this command as a replay to any telegram message with out any spaces.</code>"""
22+
23+
24+
#=====================================================================================##
25+
1126

1227
@Bot.on_message(filters.command('start') & filters.private & subscribed)
1328
async def start_command(client: Client, message: Message):
29+
id = message.from_user.id
30+
user_name = '@' + message.from_user.username if message.from_user.username else None
31+
await add_user(id, user_name)
1432
text = message.text
1533
if len(text)>7:
1634
try:
@@ -108,3 +126,43 @@ async def not_joined(client: Client, message: Message):
108126
quote = True,
109127
disable_web_page_preview = True
110128
)
129+
130+
@Bot.on_message(filters.private & filters.command('users'))
131+
async def subscribers_count(bot, m: Message):
132+
id = m.from_user.id
133+
if id not in ADMINS:
134+
return
135+
msg = await m.reply_text(WAIT_MSG)
136+
messages = await users_info(bot)
137+
active = messages[0]
138+
blocked = messages[1]
139+
await m.delete()
140+
await msg.edit(USERS_LIST.format(active, blocked))
141+
142+
143+
144+
@Bot.on_message(filters.private & filters.command('broadcast'))
145+
async def send_text(bot, m: Message):
146+
id = m.from_user.id
147+
if id not in ADMINS:
148+
return
149+
if (" " not in m.text) and ("broadcast" in m.text) and (m.reply_to_message is not None):
150+
query = await query_msg()
151+
for row in query:
152+
chat_id = int(row[0])
153+
try:
154+
await bot.copy_message(
155+
chat_id=chat_id,
156+
from_chat_id=m.chat.id,
157+
message_id=m.reply_to_message.message_id,
158+
caption=m.caption,
159+
reply_markup=m.reply_markup
160+
)
161+
except FloodWait as e:
162+
await asyncio.sleep(e.x)
163+
except Exception:
164+
pass
165+
else:
166+
msg = await m.reply_text(REPLY_ERROR, m.message_id)
167+
await asyncio.sleep(8)
168+
await msg.delete()

requirements.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
Pyrogram
1+
# --- For-Bot-Working --------- #
2+
pyrogram
23
TgCrypto
34
Pyromod
5+
# --- For-Database ------------ #
6+
sqlalchemy~=1.3.23
7+
psycopg2-binary
8+
feedparser
9+

0 commit comments

Comments
 (0)