Puede considerar donar aquí si desea que siga desarrollando esto: https://www.buyymeacoffee.com/prxm
¡Una biblioteca de chatbot de eventos totalmente destacada para las salas de chat de Reddit!
Funciona con Reddit UserName & Password o el token API (no es regular que obtenga de su aplicación registrada, ya que no está completamente alcanzada)
pip install Reddit-ChatBot-Python
requerido:
websocket_client
requests
El módulo es multiproceso y basado en eventos. Usted maneja lo que sucederá en estos eventos escribiendo su función con el decorador del evento correspondiente.
Para crear una instancia de redditauthenticaton, hay dos opciones
La forma recomendada es crear una contraseña:
from Reddit_ChatBot_Python import RedditAuthentication
reddit_authentication = RedditAuthentication . PasswordAuth ( reddit_username = "" ,
reddit_password = "" ,
twofa = None )O puede ir con su tecla API Obstanía autogestionada. (No es el que obtienes de tu aplicación registrada)
from Reddit_ChatBot_Python import RedditAuthentication
reddit_authentication = RedditAuthentication . TokenAuth ( token = "" )luego instanciando el chatbot con la reddit_authentication pasó en
from Reddit_ChatBot_Python import ChatBot
chatbot = ChatBot ( print_chat = True ,
store_session = True ,
log_websocket_frames = False ,
authentication = reddit_authentication
) print_chat es para print los mensajes de chat en la consola
store_session Cuando se establece en verdadero, crea un archivo de sesión que almacena la reddit_authentication en el mismo directorio en el que se llamó el script principal. Acelera la conexión inital.
log_websocket_frames registra los marcos de WebSocket no parcionados en la consola
authentication es la RedditAuthentication redditauthent que instancia antes
Los eventos:
@ chatbot . event . on_messageEl evento de recibir un mensaje de chat regular.
@ chatbot . event . on_readyEl evento de conectarse a los chats por primera vez. Ejecutado solo una vez.
@ chatbot . event . on_invitationEl evento del bot que recibe una invitación de chat, ya sea directa o grupo.
@ chatbot . event . on_invitation_of_otherEl evento de que otro usuario reciba una invitación para un chat grupal en el que se encuentra el bot.
@ chatbot . event . on_message_deletedEl evento de un usuario que elimina su mensaje.
@ chatbot . event . on_user_joinedEl evento de un usuario se une a un chat en el que se encuentra el bot.
@ chatbot . event . on_user_leftEl evento de que un usuario salga de chat en el que se encuentra el bot.
@ chatbot . event . on_user_typingEl evento de una escritura de usuario.
@ chatbot . event . on_user_readEl evento de un usuario que lee un mensaje.
@ chatbot . event . on_broadcastEl evento de recibir una transmisión como To To User Union
@ chatbot . event . on_reactionEl evento de que un usuario envíe una reacción
Todos los eventos reciben un marco analizado como argumento. Se manejan así:
@ chatbot . event . on_message
def greet ( resp ):
if resp . user . name == chatbot . get_own_name (): # return if the message is from the bot
return True
if resp . message == "Hi!" :
chatbot . send_message ( "Hello!" , resp . channel_url )
return True ¡Devolver True de los eventos significa que el manejo de los otros eventos no se llevará a cabo!
resp.channel_url es la URL del canal al que queremos enviar el mensaje (resp.channel_url en este caso, que es el canal en el que se envió el mensaje "¡Hola!").
El argumento resp respira más datos que solo el usuario y la cadena de mensajes. Las instancias de Resp para algunos eventos se enumeran a continuación.
Todo lo que queda es comenzar el chatbot:
chatbot . run_4ever ( auto_reconnect = True )Cómo se accede a los campos:
message = resp.message
nickname = resp.user.name
{
"msg_id" : 1000000 ,
"is_op_msg" : false ,
"is_guest_msg" : true ,
"message" : " msg " ,
"silent" : false ,
"ts" : 1611782454265 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 " ,
"is_removed" : false ,
"sts" : 1611782454265 ,
"user" : {
"is_blocked_by_me" : false ,
"require_auth_for_profile_image" : false ,
"name" : " *user nickname* " ,
"is_bot" : false ,
"image" : " " ,
"is_active" : true ,
"guest_id" : " t2_5z9rqylm " ,
"friend_discovery_key" : null ,
"role" : " " ,
"friend_name" : null ,
"id" : 10000
}
}{
"unread_cnt" : {
"all" : 1 ,
"ts" : 1614006345986
},
"is_super" : false ,
"data" : {
"inviter" : {
"nickname" : " *inviter nickname* " ,
"metadata" : {
},
"require_auth_for_profile_image" : false ,
"profile_url" : " " ,
"user_id" : " *user id str t2_ included* "
},
"invited_at" : 1614006345956 ,
"invitees" : [
{
"nickname" : " *bot's nickname* " ,
"metadata" : {
},
"require_auth_for_profile_image" : false ,
"profile_url" : " " ,
"user_id" : " t2_5z9rqylm "
}
]
},
"ts" : 1614006345978 ,
"is_access_code_required" : false ,
"cat" : 10020 ,
"channel_type" : " *can either be 'group' for group chat or 'direct' for DM* " ,
"channel_id" : 177639012 ,
"sts" : 1614006345978 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 "
}{
"is_super" : false ,
"data" : {
"is_bulk" : true ,
"users" : [
{
"require_auth_for_profile_image" : false ,
"nickname" : " nickname " ,
"role" : " " ,
"user_id" : " t2_5z9rqylm " ,
"inviter" : {
"user_id" : " t2_5z9rqylm " ,
"role" : " " ,
"require_auth_for_profile_image" : false ,
"nickname" : " nickname " ,
"profile_url" : " " ,
"metadata" : {
}
},
"profile_url" : " " ,
"metadata" : {
}
}
]
},
"ts" : 1614264797294 ,
"is_access_code_required" : false ,
"cat" : 10000 ,
"channel_type" : " group " ,
"channel_id" : 177639012 ,
"sts" : 1614264797294 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 "
}{
"channel_type" : " group " ,
"channel_id" : 177639012 ,
"is_super" : false ,
"channel" : {
"custom_type" : " group " ,
"is_ephemeral" : false ,
"freeze" : false ,
"disappearing_message" : {
"message_survival_seconds" : -1 ,
"is_triggered_by_message_read" : false
},
"member_count" : 2 ,
"is_broadcast" : false ,
"last_message" : null ,
"unread_mention_count" : 0 ,
"sms_fallback" : {
"wait_seconds" : -1 ,
"exclude_user_ids" : [
]
},
"is_discoverable" : false ,
"ignore_profanity_filter" : false ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 " ,
"message_survival_seconds" : -1 ,
"unread_message_count" : 0 ,
"is_distinct" : false ,
"cover_url" : " https: // static.sendbird.com / sample / cover / cover_00.jpg " ,
"members" : [
{
"is_active" : true ,
"state" : " " ,
"user_id" : 10000000 ,
"is_online" : false ,
"is_muted" : false ,
"require_auth_for_profile_image" : false ,
"last_seen_at" : 0 ,
"nickname" : " nickname1 " ,
"profile_url" : " " ,
"metadata" : {
}
},
{
"is_active" : true ,
"state" : " " ,
"user_id" : 10000000 ,
"is_online" : false ,
"is_muted" : false ,
"require_auth_for_profile_image" : false ,
"last_seen_at" : 0 ,
"nickname" : " nickname2 " ,
"profile_url" : " " ,
"metadata" : {
}
}
],
"is_public" : false ,
"data" : " " ,
"joined_member_count" : 1 ,
"is_super" : false ,
"name" : " group name " ,
"created_at" : 1614264775 ,
"is_access_code_required" : false ,
"max_length_message" : 5000
},
"sts" : 1614265517558 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 " ,
"data" : {
"require_auth_for_profile_image" : false ,
"member_count" : 2 ,
"user_id" : " t2_5z9rqylm " ,
"joined_member_count" : 1 ,
"nickname" : " nickanme of user who left the group " ,
"profile_url" : " " ,
"metadata" : {
}
},
"ts" : 1614265517558 ,
"is_access_code_required" : false ,
"cat" : 10001
}{
"is_super" : false ,
"msg_id" : 2323966291 ,
"ts" : 1614266924885 ,
"channel_type" : " group " ,
"channel_id" : 177623421 ,
"sts" : 1614266924885 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 "
}{
"is_super" : false ,
"data" : {
"require_auth_for_profile_image" : false ,
"user_id" : " t2_xxxxxx " ,
"nickname" : " xxxx " ,
"profile_url" : " " ,
"metadata" : {
}
},
"ts" : 1617897296948 ,
"is_access_code_required" : false ,
"cat" : 10900 ,
"channel_type" : " group " ,
"channel_id" : 11111111 ,
"sts" : 1617897296948 ,
"channel_url" : " sendbird_group_channel_000000000_0000000000000000000000000000000000000000 "
} from Reddit_ChatBot_Python import ChatBot , RedditAuthentication
from Reddit_ChatBot_Python import CustomType , Snoo , Reaction
import random # for a basic dice rolling game
# create authentication with username and pass
reddit_authentication = RedditAuthentication . PasswordAuth ( reddit_username = "" , reddit_password = "" ,
twofa = None ) # 2FA supported, default'd to None
# instantiate the chatbot
chatbot = ChatBot ( print_chat = True , store_session = True , log_websocket_frames = False , # some parameters u might wanna know
authentication = reddit_authentication )
# you can add a rate limit like so:
chatbot . enable_rate_limiter ( max_calls = 23 , # how many messages will be sent by the bot
period = 1.5 # in what period (minutes)
)
# now you can add hooks which will be executed when a frame is received like so:
@ chatbot . event . on_message
def dice_roller ( resp ): # resp is a SimpleNamespace that carries all the data of the received frame
messg_s = resp . message . split ()
if messg_s [ 0 ] == "!roll" and len ( messg_s ) == 3 : # if received message says !roll
chatbot . send_reaction ( Reaction . REACT4 , resp . msg_id , resp . channel_url ) # send a reaction
limit_bottom = int ( messg_s [ 1 ])
limit_top = int ( messg_s [ 2 ])
rolled_number = random . randint ( limit_bottom , limit_top )
response_text = f"@ { resp . user . name } rolled { rolled_number } . Better luck next time!"
# send typing indicator cuz why not? maybe they think you are a real person
chatbot . send_typing_indicator ( resp . channel_url )
chatbot . send_message ( response_text ,
resp . channel_url ) # send the message, always add resp.channel_url as the second argument
chatbot . stop_typing_indicator ( resp . channel_url )
chatbot . send_snoomoji ( Snoo . PARTYPARROT , resp . channel_url ) # and send a snoomoji cuz why not??
return True # return true if you want to be done with checking the other hooks, otherwise return None or False
# keep in mind that first added hooks get executed first
# now everytime someone says "!roll 1 100", the bot will roll a dice between 1 and 100 and send the result!
# there are also host actions availabe but ofc they require the bot account to be the host of the chatroom
@ chatbot . event . on_message
def keeper_of_decency ( resp ):
if resp . message == "*some very bad slur word*" :
chatbot . kick_user ( channel_url = resp . channel_url , user_id = resp . user . guest_id , duration = 600 ) # duration is in secs
chatbot . send_message ( f'i banned { resp . user . name } for 10 mins' , resp . channel_url )
elif resp . message == "*another bad word*" :
chatbot . delete_mesg ( channel_url = resp . channel_url , msg_id = resp . msg_id )
chatbot . send_message ( f"i deleted { resp . user . name } 's message" , resp . channel_url )
# or you can add a basic response hook directly like so:
chatbot . set_respond_hook ( input_ = "Hi" , response = "Hello {nickname}! sup?" , limited_to_users = None , lower_the_input = False ,
exclude_itself = True , must_be_equal = True ,
limited_to_channels = [ "my cozy chat group" ]) # you can limit by indicating chatroom's name
# you can add a welcome message for newly joined users:
chatbot . set_welcome_message ( "welcome to the my cozy chat group u/{nickname}!)" ,
limited_to_channels = [ "my cozy chat group" ])
# and a farewell message too:
chatbot . set_farewell_message ( "Too bad u/{nickname} left us :(" , limited_to_channels = [ "my cozy chat group" ])
# there are also other types of hooks like this one for invitations
@ chatbot . event . on_invitation
def on_invit ( resp ):
if resp . channel_type == CustomType . group :
invit_type = "group chat"
elif resp . channel_type == CustomType . direct :
invit_type = "DM"
print ( f"got invited to { invit_type } by { resp . data . inviter . nickname } " )
chatbot . accept_chat_invite ( resp . channel_url )
chatbot . send_message ( "Hello! I accepted your invite" , resp . channel_url )
return True
# or on ready hook
@ chatbot . event . on_ready
def report_channels ( _ ):
channels = chatbot . get_channels ()
print ( "up and running in these channels!: " )
for channel in channels :
print ( channel . name )
# reading message history from a channel
@ chatbot . event . on_ready
def report_channels ( _ ):
channels = chatbot . get_channels ()
my_channel = None
for channel in channels :
if channel . name == "My Channel" :
my_channel = channel
last_hundred_messages = chatbot . get_older_messages ( channel_url = my_channel . channel_url ,
prev_limit = 100 )
last_created_at = last_hundred_messages [ - 1 ]. created_at
while True :
messages = chatbot . get_older_messages ( channel_url = my_channel . channel_url ,
message_ts = last_created_at ,
prev_limit = 30 )
last_created_at = messages [ - 1 ]. created_at
# starting a direct chat
@ chatbot . event . on_ready
def dm_chat ( _ ):
dm_channel = chatbot . create_direct_channel ( "someuseridk" )
chatbot . send_message ( "Hey what's up?" , dm_channel . channel_url )
# starting a group chat
@ chatbot . event . on_ready
def gorup_chat ( _ ):
group_channel = chatbot . create_channel ( nicknames = [ "user1" , "user2" ], group_name = "my group" )
chatbot . send_message ( "Hey guys what's up?" , group_channel . channel_url )
chatbot . invite_user_to_channel ( group_channel . channel_url , nicknames = [ "someotheruser" ])
invite_link = chatbot . get_invite_link ( group_channel . channel_url )
chatbot . send_message ( group_channel . channel_url , f"this is our invite link: { invite_link } " )
# wanna check invitations on start?
@ chatbot . event . on_ready
def check_invites ( _ ):
invites = chatbot . get_chat_invites ()
for invite in invites :
print ( f"invited to chat by { invite . inviter } with the message { invite . last_message . message } " )
chatbot . accept_chat_invite ( invite . channel_url )
return True
# and finally, run forever...
chatbot . run_4ever ( auto_reconnect = True )
# set auto_reconnect to True so as to re-connect in case remote server shuts down the connection after some period of time