I made a telegram bot with python-telegram-bot. I have defined a list of words for the bot and I want to manage the chat bot in the group. That is, if there is a word in the chat that is found in the defined list, the bot will delete it. I added the bot to a group and admin it there. The bot should control the messages sent to the group, and if there is a word in the message that is on the mlist, the bot should delete the message. my codes:
# -*- coding: cp1256 -*-
#!/usr/bin/python
import os, sys
from telegram.ext import Filters
from telegram.ext import Updater, MessageHandler
import re
def delete_method(bot, update):
if not update.message.text:
print("it does not contain text")
return
mlist=['Hello', 'سلام']
for i in mlist:
if re.search(i, update.message.text):
bot.delete_message(chat_id=update.message.chat_id,message_id=update.message.message_id)
def main():
updater = Updater(token='TOKEN')
dispatcher = updater.dispatcher
dispatcher.add_handler(MessageHandler(Filters.all, delete_method))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
# -*- coding: utf8 -*-
#!python2
import time
import json
import requests
#TOKEN = XXXXXX
URL = "https://api.telegram.org/bot{}/".format(TOKEN)
def get_updates(offset=None):
url = URL + "getUpdates?timeout=100"
if offset:url += "&offset={}".format(offset)
return requests.get(url).json()
def get_last_update_id(updates):
update_ids = []
for update in updates["result"]:
update_ids.append(int(update["update_id"]))
return max(update_ids)
def delete_message(message_id, chat_id,msg):
mlist=['Hello', 'سلام']
url=URL + "deleteMessage?message_id={}&chat_id={}".format(message_id, chat_id)
for i in mlist:
if i in msg:request.get(url)
def echo_all(updates):
for update in updates["result"]:
cid = update["message"]["chat"]["id"]
msg = update["message"].get("text")
mid = update["message"].get("message_id")
if msg:delete_message(mid,cid,msg)
def main():
last_update_id = None
while True:
try:
updates = get_updates(last_update_id)
z=updates.get("result")
if z and len(z) > 0:
last_update_id = get_last_update_id(updates) + 1
echo_all(updates)
time.sleep(0.5)
except Exception as e:
print(e)
if __name__ == '__main__':
main()
Related
I have made a simple chat system with python-requests. There are two different files one is the sender and another is the receiver. the main concept of these two files is
1. sender file contains a while loop which always takes the message as input. after
giving the message as input, it sends the message to a website.
2. receiver file also contains a while loop which gets requests from the website after every
5 seconds.
Now I want to run these two different works in the same window with Tkinter. how to do it? Thanks in advance.
Sender.py Code is here
import configme as con
import requests
import datetime
from cryptography.fernet import Fernet
nam = con.my_name
cookies_dict = con.cookie
key = con.crypto_key
url = con.base_url + '/config.php'
def makeID():
return datetime.datetime.now().timestamp()
# encription staff
fernet = Fernet(key)
# member joining message
if nam.__len__() != 0:
requests.get(url+f"?iD={makeID()}&name=<<<>>>&msg={nam} join the room.", cookies=cookies_dict)
with requests.Session() as r:
while True:
msg = input("Enter your Messege: ")
if msg == ".exit":
# r.get(url+f"?iD={makeID()}&name=<<<>>>&msg={nam} has left the room.", cookies=cookies_dict)
break
else:
encMessage = fernet.encrypt(msg.encode())
messenger = {'iD': makeID() ,'name': nam , 'msg': encMessage}
if msg != "":
r.get(url, params=messenger, cookies=cookies_dict)
Receiver.py code here...
import configme as con
import requests
import json
from cryptography.fernet import Fernet
from time import sleep
from datetime import datetime
from pytz import timezone
import pytz
cookies_dict = con.cookie
ozone = con.my_timezone
key = con.crypto_key
time_format = con.date_time_format
url = con.base_url + '/log.json'
t = con.receive_time
# encription staff
fernet = Fernet(key)
timezone = timezone(ozone)
def setTime(t):
stamptime = int(float(t))
GMT0 = pytz.utc.localize(datetime.utcfromtimestamp(stamptime))
return GMT0.astimezone(timezone).strftime(time_format)
j = 0
while True:
r = requests.get(url, cookies=cookies_dict).text
message = json.loads(r)
message_sz = len(message)
if message_sz == 0:
print("Looks like there are no message")
break
for msg in message[j:]:
local_time = setTime(msg['id'])
if msg['nam'] == '<<<>>>':
print(f"{local_time} :: {msg['nam']} :: {msg['msg']}")
else:
decMessage = fernet.decrypt(bytes(msg['msg'], "utf-8")).decode()
print(f"{local_time} :: {msg['nam']} :: {decMessage}")
j = message_sz
sleep(t)
I would not suggest using this checking and going to website method, but you could thread the while loops to go at the same time. And you could update tk when you want using tk.update().
You could get Data from vars that the threaded loops are setting and use them in your single tk window.
use multi threading .or else load data desperately
I'm just starting to discover how to build a bot with python. I'm trying to send a message at certain time. I read a lot of example, I read the documentation regarding modul_schedule function but I can't fix this issue...
import config
import telebot
import requests
import schedule
import time
from my_parser import parse
from bs4 import BeautifulSoup as BS
bot = telebot.TeleBot(config.token)
r = requests.get('https://example')
html = BS(r.content, 'html.parser')
for el in html.select('#content'):
t_min = el.select('.temperature .min')[0].text
t_max = el.select('.temperature .max')[0].text
min_text = el.select('.wDescription .description')[0].text
t_test = el.select('.wDescription .description')[0].text
response = requests.get(url='https://example')
data = response.json()
btc_price = f"B: {round(data.get('btc_usd').get('last'), 2)}$"
#bot.message_handler(commands=['start', 'help'])
def main(message):
bot.send_message(
message.chat.id, t_min + ', ' + t_max + '\n' + min_text + '\n' + parse() + '\n' + btc_price)
if __name__ == '__main__':
bot.polling(none_stop=True, interval=0)
schedule.every(1).seconds.do(main)
while True:
schedule.run_pending()
time.sleep(1)
I would like the bot send message every morning with temperature on to a channel. I did not find any clues on how to use the function correctly.
I use this library.
Example of my code.
import aioschedule as schedule
async def some_fun():
pass
async def scheduler():
schedule.every().day.at("09:00").do(some_fun())
while True:
await schedule.run_pending()
await asyncio.sleep(2)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.create_task(scheduler())
main()
import os
from keep_alive import keep_alive
from discord.ext import commands
import time
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import discord
bot = commands.Bot(
command_prefix="!", # Change to desired prefix
case_insensitive=True # Commands aren't case-sensitive
)
bot.author_id = 581512730343637083 # Change to your discord id!!!
channelID = "688698168996921368"
#bot.event
async def on_ready(): # When the bot is ready
print("I'm in")
print(bot.user) # Prints the bot's username and identifier
while True:
time.sleep(2)#
updateEmbedSaved = check_update()
if channelID != None and updateEmbedSaved != None:
try:
channel = bot.get_channel(int(channelID))
await channel.send(embed=updateEmbedSaved)
except Exception as e:
print(e)
pass
def check_update():
todayDate = datetime.today().strftime('%Y.%m.%d')
todayDate = "2021.06.08"
csgoPage = requests.get("https://blog.counter-strike.net/index.php/category/updates/")
html = csgoPage.text
soup = BeautifulSoup(html, 'html.parser')
dateElems = soup.find_all('p', class_="post_date")
if dateElems[0].text[:10] == todayDate:
with open("detected.txt") as f:
data = f.readline()
if data != todayDate:
print("True")
todayDateSplice = f"/{todayDate[:4]}/{todayDate[5:7]}/"
linkElems = soup.find_all('a', href=True)
for index, linkElem in enumerate(linkElems):
link = linkElem['href']
if todayDateSplice in link:
correctLink = link
break
csgoPage = requests.get(correctLink)
html = csgoPage.text
soup = BeautifulSoup(html, 'html.parser')
titleElems = soup.find_all('h2')
updateEmbed = discord.Embed(title=f"Update Detected: {titleElems[0].text}", color=0x00ff55)
updateEmbed.set_thumbnail(url='https://cdn.akamai.steamstatic.com/steam/apps/730/capsule_616x353.jpg?t=1623182945')
updateEmbed.set_author(name="CS:GO Update Detected")
updateEmbed.set_footer(text="CS:GO Update Checker Bot | Information from https://blog.counter-strike.net/")
paraElems = soup.find_all('p')
paraElems = paraElems[:len(paraElems)-4]
for elem in paraElems:
print(elem.text, "\n-------------")
body = "\n".join(elem.text.split("\n")[1:])
if body != None and elem.text.split("\n")[0] != None:
try:
updateEmbed.add_field(name=elem.text.split("\n")[0], value=body, inline=False)
except:
pass
with open('detected.txt', 'w') as file:
file.writelines(todayDate)
return updateEmbed
else:
print("False")
print(dateElems[0].text[:10])
print(todayDate)
keep_alive() # Starts a webserver to be pinged.
token = os.environ.get("DISCORD_BOT_SECRET")
bot.run(token) # Starts the bot
Can someone please help me, the error is called when the embed is being sent, and the try except catches it, but the embed is not sent. I have checked that the values going into fields are not empty, yet I still get the error:
"400 Bad Request (error code: 50035): Invalid Form Body
In embed.fields.0.value: This field is required"
Can someone help?
I don't know if it works but try this
Change line 78 with this:
updateEmbed.add_field(name=elem.text.split("\n"), value=body, inline=False)
I deleted the specific index brackets, but if you want a specific index from it, I really don't know.
I manage to send only 1 message after launching the script, after which it hangs and no longer receives messages from Twitter
If I remove the block of code I wrapped in "------------------------------" then I will receive all the tweets, but when I try to send it to Telegram, it stops after the first time
Initially did without separate threads, because I could not achieve the result
Wrapped everything in separate threads, but the result is the same
What am I doing wrong?
from telethon import TelegramClient, events, sync
from telethon.tl.types import InputChannel
import tweepy
import yaml
import sys
import coloredlogs, logging
import asyncio
import threading
import concurrent.futures
import time
start_twitter = threading.Event()
forwardinput_channel_entities = []
forwardoutput_channels = {}
class MyStreamListener(tweepy.StreamListener):
def on_status(self, status):
user_id = status.user.id
if user_id in forwardoutput_channels:
for output_channel in forwardoutput_channels[user_id]:
message = status.text
logging.info('-------------')
logging.info(message)
# ------------------------------
try:
loop = asyncio.get_event_loop()
except Exception as e:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
logging.error(e)
pass
loop.run_until_complete(telegram_client.send_message(
output_channel['channel'], message))
# ------------------------------
def twitter_thred():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
auth = tweepy.OAuthHandler(config['twitter_consumer_api'],
config['twitter_consumer_secret'])
auth.set_access_token(config['twitter_user_api'],
config['twitter_user_secret'])
global twitter_api
twitter_api = tweepy.API(auth)
myStreamListener = MyStreamListener()
myStream = tweepy.Stream(auth=twitter_api.auth, listener=myStreamListener)
start_twitter.wait()
myStream.filter(follow=forwardinput_channel_entities,
is_async=True)
def telegram_thred():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
global telegram_client
telegram_client = TelegramClient(config['session_name'],
config['api_id'],
config['api_hash'])
telegram_client.start()
for forwardto in config['forwardto_list_ids']:
for twitter_user_id in forwardto['from']:
forwardinput_channel_entities.append(str(twitter_user_id))
channels = []
for channel in telegram_client.iter_dialogs():
if channel.entity.id in forwardto['to']:
channels.append({
'channel': InputChannel(
channel.entity.id, channel.entity.access_hash),
})
forwardoutput_channels[twitter_user_id] = channels
start_twitter.set()
telegram_client.run_until_disconnected()
def start():
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
future = executor.submit(telegram_thred)
future = executor.submit(twitter_thred)
if __name__ == '__main__':
if len(sys.argv) < 2:
print(f'Usage: {sys.argv[0]} {{CONFIG_PATH}}')
sys.exit(1)
with open(sys.argv[1], 'rb') as f:
global config
config = yaml.safe_load(f)
coloredlogs.install(
fmt='%(asctime)s.%(msecs)03d %(message)s',
datefmt='%H:%M:%S')
start()
An example of a yml config to run the script:
# telegram
api_id: *****************
api_hash: '*****************'
session_name: 'test'
# twitter
twitter_consumer_api: '*****************'
twitter_consumer_secret: '*****************'
twitter_user_api: '*****************'
twitter_user_secret: '*****************'
forwardto_list_ids:
- from:
- 0000000000 # account twitter id
to:
- 0000000000 # telegram channel id
As noted, Tweepy doesn't support asyncio with streaming yet, so it's blocking the event loop when you run the stream. is_async uses a threaded approach.
For now, you should look into using Tweepy's async-streaming branch / https://github.com/tweepy/tweepy/pull/1491.
I am writing a simple producer/consumer app to call multiple URL's asynchronously.
In the following code if I set the conn_count=1, and add 2 items to the Queue it works fine as only one consumer is created. But if I make conn_count=2 and add 4 items to the Queue only 3 request are being made. The other request fails with ClientConnectorError.
Can you please help be debug the reason for failure with multiple consumers? Thank You.
I am using a echo server I created.
Server:
import os
import logging.config
import yaml
from aiohttp import web
import json
def start():
setup_logging()
app = web.Application()
app.router.add_get('/', do_get)
app.router.add_post('/', do_post)
web.run_app(app)
async def do_get(request):
return web.Response(text='hello')
async def do_post(request):
data = await request.json()
return web.Response(text=json.dumps(data))
def setup_logging(
default_path='logging.yaml',
default_level=logging.INFO,
env_key='LOG_CFG'
):
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'rt') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
if __name__ == '__main__':
start()
Client:
import asyncio
import collections
import json
import sys
import async_timeout
from aiohttp import ClientSession, TCPConnector
MAX_CONNECTIONS = 100
URL = 'http://localhost:8080'
InventoryAccount = collections.namedtuple("InventoryAccount", "op_co customer_id")
async def produce(queue, num_consumers):
for i in range(num_consumers * 2):
await queue.put(InventoryAccount(op_co=i, customer_id=i * 100))
for j in range(num_consumers):
await queue.put(None)
async def consumer(n, queue, session, responses):
print('consumer {}: starting'.format(n))
while True:
try:
account = await queue.get()
if account is None:
queue.task_done()
break
else:
print(f"Consumer {n}, Updating cloud prices for account: opCo = {account.op_co!s}, customerId = {account.customer_id!s}")
params = {'opCo': account.op_co, 'customerId': account.customer_id}
headers = {'content-type': 'application/json'}
with async_timeout.timeout(10):
print(f"Consumer {n}, session state " + str(session.closed))
async with session.post(URL,
headers=headers,
data=json.dumps(params)) as response:
assert response.status == 200
responses.append(await response.text())
queue.task_done()
except:
e = sys.exc_info()[0]
print(f"Consumer {n}, Error updating cloud prices for account: opCo = {account.op_co!s}, customerId = {account.customer_id!s}. {e}")
queue.task_done()
print('consumer {}: ending'.format(n))
async def start(loop, session, num_consumers):
queue = asyncio.Queue(maxsize=num_consumers)
responses = []
consumers = [asyncio.ensure_future(loop=loop, coro_or_future=consumer(i, queue, session, responses)) for i in range(num_consumers)]
await produce(queue, num_consumers)
await queue.join()
for consumer_future in consumers:
consumer_future.cancel()
return responses
async def run(loop, conn_count):
async with ClientSession(loop=loop, connector=TCPConnector(verify_ssl=False, limit=conn_count)) as session:
result = await start(loop, session, conn_count)
print("Result: " + str(result))
if __name__ == '__main__':
conn_count = 2
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(run(loop, conn_count))
finally:
loop.close()
Reference:
https://pymotw.com/3/asyncio/synchronization.html
https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html
https://hackernoon.com/asyncio-for-the-working-python-developer-5c468e6e2e8e