Django Channels sending multiple messages to same channel - python

Referring to documentation here
I'm sending messages to the single fetched channel_name
I'm able to successfully send messages to the specific channel
Issues I'm facing
On the channels it's sending messages multiple times
For Example -
When I send first message, I receive 1 time.
On second message, I'm getting same messages twice.
On third message, I'm geting same message 3 times.
and so on...
class ChatConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.user_id = self.scope['url_route']['kwargs']['user_id']
await self.save_user_channel()
await self.accept()
async def disconnect(self, close_code):
await self.disconnect()
async def receive_json(self, text_data=None, byte_data=None):
message = text_data['message']
to_user = text_data['to_user']
to_user_channel, to_user_id = await self.get_user_channel(to_user)
channel_layer = get_channel_layer()
await channel_layer.send(
str(to_user_channel), {
'type': 'send.message',
'from_user': self.user_id,
'to_user': str(to_user_id),
'message': message,
}
)
await channel_layer.send(
str(self.channel_name), {
'type': 'send.message',
'from_user': self.user_id,
'to_user': str(to_user_id),
'message': message,
}
)
async def send_message(self, event):
from_user = event['from_user']
to_user = event['to_user']
message = event['message']
await self.send(text_data=json.dumps({
'from_user': from_user,
'to_user': to_user,
'message': message,
}))
#database_sync_to_async
def get_user_channel(self, to_user):
try:
self.send_user_channel = ChatParticipantsChannel.objects.filter(
user=to_user).latest('id')
channel_name = self.send_user_channel
user_id = self.send_user_channel.user.user_uid
except Exception as e:
self.send_user_channel = None
channel_name = None
return channel_name, user_id
#database_sync_to_async
def save_user_channel(self):
self.user = User.objects.get(user_uid=self.user_id)
ChatParticipantsChannel.objects.create(
user=self.user,
channel=self.channel_name
)
#database_sync_to_async
def delete_user_channel(self):
ChatParticipantsChannel.objects.filter(user=self.user).delete()

Related

telegram bot deletes data

I tried to make a function for the tg bot so that the user could click the "Code Request" button, when pressed, he could enter additional information and after that the message was sent to the admin a message about the code request. The problem is that after receiving the message by the admin, the data is erased
Here's the code
#dp.message_handler(text='Запрос кода')
async def start_mailing(message : Message):
user_id = message.from_user.id
if db.cat5_exists(message.from_user.id):
await message.answer(f'Введите количество кодов, или дополнительную информацию:')
await bot_mailing2.info.set()
elif db.cat6_exists(message.from_user.id):
await message.answer(f'Введите количество кодов, или дополнительную информацию:')
await bot_mailing2.info.set()
elif db.cat7_exists(message.from_user.id):
await message.answer(f'Введите количество кодов, или дополнительную информацию:')
await bot_mailing2.info.set()
else:
await bot.send_message(chat_id=message.from_user.id, text=f"Данная функция вам не доступна", reply_markup=menu_button_user)
#dp.message_handler(state=bot_mailing2.info)
async def mailing_text(message : Message, state: FSMContext):
answer = message.text
user_id = message.from_user.id
username = message.from_user.username
mirkip = InlineKeyboardMarkup(row_width=2,inline_keyboard=[[
InlineKeyboardButton(text='Отправить код', callback_data='sendit'),
InlineKeyboardButton(text='Отказать', callback_data='cancel')]])
await state.update_data(info=answer)
await state.update_data(text=user_id)
data = await state.get_data()
print(data)
await bot.send_message(chat_id=ADMIN1, text=f"{username}, запросил код. \nДополнительная информация: {answer}",reply_markup=mirkip)
#await bot.send_message(chat_id=ADMIN2, text=f"{username}, запросил код. \nДополнительная информация: {answer}",reply_markup=mirkip)
#await bot.send_message(chat_id=ADMIN3, text=f"{username}, запросил код. \nДополнительная информация: {answer}",reply_markup=mirkip)
#await bot.send_message(chat_id=SENDER, text=f"{username}, запросил код. \nДополнительная информация: {answer}",reply_markup=mirkip)
#dp.callback_query_handler(text='sendit')
async def start_one(message : Message, state: FSMContext):
user_id = message.from_user.id
await bot.send_message(chat_id=user_id, text='Введите код:')
await bot_mailing2.codes.set()
#dp.message_handler(state=bot_mailing2.codes)
async def get_userId(message: types.Message, state: FSMContext):
answer = message.text
await state.update_data(codes=answer)
data = await state.get_data()
text = data.get('text')
info = data.get('info')
codes = data.get('codes')
print(data)
await state.finish()
it goes like this
{'info': '123', 'text': 5253040087}
{'codes': 'asd'}
but it should be like this
{'info': '123', 'text': 5253040087, 'codes': 'asd'}

Warning discord.getaway "discord.gateway: Shard ID None heartbeat blocked for more than 10 seconds."

I tried to write a Discord bot that forwards messages from one server to another. But I get a warning that disconnects my connection to the discord gateway. I read that it is possible because of tyme.slep(), but without it, the connection is always interrupted. As I understand it, DDOS protection is activated due to a large number of requests.
import asyncio
import websocket
import json
from threading import Thread
import discord
import requests
from io import BytesIO
import time
from discord.ext import tasks
# Bot
bot_token = "anything"
user_token = "anything"
client = discord.Client(intents=discord.Intents.default())
# Channels list
f = open('channels.txt', 'r')
channels_file = f.read()
channels_array = channels_file.strip().split('\n')
# Connect func
def send_json_request(ws, request):
ws.send(json.dumps(request))
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
#WebSoket
def on_closed(ws):
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
ws = websocket.WebSocket(on_close=on_closed)
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
def get_attachment_media(media):
media_array = []
for i in media:
response = requests.get(i['url'])
im = BytesIO(response.content)
print(im)
media_array.append(discord.File(im))
return media_array
def get_channel(id):
for i in channels_array:
if i == id:
return True
return False
#Heartbeat
def heartbeat(interval):
print("Heartbeat begin")
while True:
time.sleep(interval)
heartbeatJSON = {
"op": 1,
"d": "null"
}
send_json_request(ws, heartbeatJSON)
print("Heartbeat sent")
#tasks.loop(seconds=0.5)
async def main():
channel = client.get_channel(anything)
event = receive_json_response(ws)
try:
if event['d']['author']['id'] == 'anything':
return
id_channel = event['d']['channel_id']
id_guild = event['d']['guild_id']
if get_channel(id_channel):
content = event['d']['content']
attachment_media = get_attachment_media(event['d']['attachments'])
await channel.send(content, files=attachment_media)
op_code = event('op')
if op_code == 11:
print('Heartbeat recieved')
except:
pass
#client.event
async def on_ready():
event = receive_json_response(ws)
heartbeat_interval = event['d']['heartbeat_interval'] / 1000
send_json_request(ws, {
"op": 2,
"d": {
"token": user_token,
"properties": {
"$os": 'linux',
"$browser": 'chrome',
"$device": 'pc'
}
}
})
main.start()
asyncio.run(heartbeat(heartbeat_interval))
client.run(bot_token)
I recommend you to check this answer and adjust it to your code.
However, if you are just trying to make your bot copy the contenet of the messages sent in one server and sending to another one, you can do it in a easier way using the on_message() event. This is the entire code, which should also prevent any warning (unless the bot tries to send too many messages in a short period of time):
import discord
intents = discord.Intents.default()
intents.message_content = True # You are missing the message_content intent! (needed to read the content of the guild's messages)
client = discord.Client(intents=intents)
TOKEN = "Your Token"
guild_id = 123456789 # The guild you want your bot to send the messages to
channel_id = 987654321 # The channel of the guild you want your bot to send the messages to
guild = None
channel = None
#client.event
async def on_ready():
global guild, channel, guild_id, channel_id
await client.wait_until_ready()
guild = client.get_guild(guild_id)
channel = guild.get_channel(channel_id)
print("Logged")
#client.event
async def on_message(message : discord.Message):
if message.author == client.user: # You don't want to send the own bot messages
return
if message.guild.id == guild_id: # You don't want to send the messages from the own guild your bot is sending the messages to
return
await channel.send(f"{message.author}: {message.content}") # Add attachments if you want
client.run(TOKEN)

how to delete a previous message if we get new message in django channels

I want to broadcast the only latest message of Django-channel layer in a specific room. Right now I have created specific room names for specific users. Now I just want to send them only latest message or note, I don't want to show all the previous messages. Right now all the previous message are showing to user side.
# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ProjectConsumer(AsyncWebsocketConsumer):
async def connect(self):
parameter = self.scope['url_route']['kwargs']["project_key"]
print("url_parameter ",parameter)
self.room_name = parameter
# Join room group
await self.channel_layer.group_add(
self.room_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
instance_user = text_data_json['instance_user']
sender = text_data_json['sender']
receiver = text_data_json['receiver']
message = text_data_json['message']
object = {
'sender':sender,
'receiver':receiver,
'message':message,
}
# Send message to room group
await self.channel_layer.group_send(
self.room_name,
{
'type': 'sent', #function name as an event type
'object': object #function parameters as an event object
}
)
# Receive message from room group
async def sent(self, event):
sender = event['object']["sender"]
receiver = event['object']["receiver"]
message = event['object']["message"]
# Send message to WebSocket
await self.send(text_data=json.dumps({
'sender':sender,
'receiver':receiver,
'message':message,
}))
Channel_layer broadcasts only the available message, you are probably appending the message to a DOM element in your front-end

Spring boot and python ends issue aio_pika

hi there am using spring boot to consume messages and expecting to receive the response at the python script where I publish the message
everything works fine and when am publishing the message the spring boot is able to consume the message
but with the python code am receiving the same request as body
import aio_pika
import asyncio
import json
from aio_pika import Message
from messaging import face_recognition_request_owner, face_recognition_exchange, face_recognition_request_owner_queue
async def process_message(message: aio_pika.IncomingMessage):
async with message.process():
print(message.info())
print(message.body)
await asyncio.sleep(1)
async def got_message(message: aio_pika.IncomingMessage):
with message.process():
print(message.body.decode())
async def main(loop):
connection = await aio_pika.connect_robust(
"amqp://guest:guest#127.0.0.1/", loop=loop
)
queue_name = face_recognition_request_owner_queue
main_exchange = face_recognition_exchange
routing_key = face_recognition_request_owner
# Creating channel
channel = await connection.channel()
# Declaring exchange
exchange = await channel.declare_exchange(
name=main_exchange,
type="direct",
auto_delete=False,
durable=False,
)
# Maximum message count which will be
# processing at the same time.
await channel.set_qos(prefetch_count=100)
# Declaring queue
queue = await channel.declare_queue(queue_name, auto_delete=False)
# Binding queue
await queue.bind(exchange, routing_key)
await exchange.publish(
Message(
bytes(json.dumps({'userId': "e4271f86-b933-465e-ae3f-f0b93335c773"}), "utf-8"),
content_type="application/json",
),
routing_key
)
await queue.consume(process_message)
return connection
if __name__ == "__main__":
loop = asyncio.get_event_loop()
connection = loop.run_until_complete(main(loop))
try:
loop.run_forever()
finally:
loop.run_until_complete(connection.close())
the spring code is :
#RabbitListener(queues = BackendCodes.LOAD_OWNER_QUEUE)
public Users loadOwner(FetchOwnerRequest fetchOwnerRequest) {
LOGGER.info("message: {}", fetchOwnerRequest.getUserId());
LOGGER.info("Processed and returned message");
return usersService.loadByOwnerId(fetchOwnerRequest.getUserId());
}
am getting this response
{'body_size': 50, 'headers': {}, 'content_type': 'application/json', 'content_encoding': '', 'delivery_mode': 1, 'priority': 0, 'correlation_id': None, 'reply_to': None, 'expiration': None, 'message_id': '932b3e80e2ff6df9b5408b8f6d788f1b', 'timestamp': None, 'type': 'None', 'user_id': None, 'app_id': None, 'cluster_id': '', 'consumer_tag': 'ctag1.b7b5aa77e52adde6ee9cfeb6135e9fac', 'delivery_tag': 2, 'exchange': 'face-recognition:exchange', 'redelivered': True, 'routing_key': 'face-recognition.requestOwner'}
b'{"userId": "e4271f86-b933-465e-ae3f-f0b93335c773"}'
thanks for helping

Discord.py cannot send message in specific channel using separate function

I try to make a function that will take text and channel_id params and send a embed to specific channel. For some reason, bot is not sending anything to the channel. What did I wrong?
async def QuickEmbed(text, channelId):
channel = bot.get_channel(channelId)
em = discord.Embed(title="\u200b", description=text, color="#f1c40f")
await channel.send(embed=em)
#bot.command()
async def log(ctx):
await QuickEmbed("test message", 123456789)```
here's a good way to do it:
async def log(
self,
ctx,
desc,
title='**Title**',
color=0xff0000,
**kwargs
):
guild = ctx.guild
log_embed = discord.Embed(
title=title,
description=desc,
color=color
)
for key, value in kwargs.items():
if key == 'fields':
for field in value:
if len(field) == 2:
log_embed.add_field(
name=field[0],
value=field[1]
)
else:
log_embed.add_field(
name=field[0],
value=field[1],
inline=field[2]
)
if key == 'showauth':
if value:
author = ctx.author
disp_name = author.display_name
icon_url = author.avatar_url
log_embed.set_author(
name=disp_name,
icon_url=icon_url
)
log_embed.set_thumbnail(
url=icon_url
)
now = datetime.now()
log_embed.timestamp = now
log_channel = discord.utils.get(guild.text_channels, name="channel_name")
await log_channel.send(embed=log_embed)
also a quick example on using it:
await self.log(
ctx,
'tdescription here',
'title here',
discord.Color.blue(),
fields=[
('**Field**', "field value, you can add more fields")
],
showauth=True
)
# you can use message, title, color, field(s), and the showauth

Categories