I want to create the bot with telepot that ask the users frequent questions.
For example first ask 'whats your name.?' then the user reply 'user-name',then ask how old are you? and the user reply his age and ...
I had written a code for this chat between user and bot,but sometimes I am getting error. Please guide me how can I make this bot with telepot.?
I want to make conversation between bot and users with telepot
I am no longer maintaining this library. Thanks for considering
telepot.
- the maintainer, nickoala
What you're looking for is DelegatorBot.
Consider this tutorial.
Consider this scenario. A bot wants to have an intelligent
conversation with a lot of users, and if we could only use a single
line of execution to handle messages (like what we have done so far),
we would have to maintain some state variables about each conversation
outside the message-handling function(s). On receiving each message,
we first have to check whether the user already has a conversation
started, and if so, what we have been talking about. To avoid such
mundaneness, we need a structured way to maintain “threads” of
conversation.
DelegatorBot provides you with one instance of your bot for every user, so you don't have to think about what happens when multiple users talk to it. (If it helps you, feel free to have a look at how I am using it.)
The tutorial's example is a simple counter of how many messages the user has sent:
import sys
import time
import telepot
from telepot.loop import MessageLoop
from telepot.delegate import pave_event_space, per_chat_id, create_open
class MessageCounter(telepot.helper.ChatHandler):
def __init__(self, *args, **kwargs):
super(MessageCounter, self).__init__(*args, **kwargs)
self._count = 0
def on_chat_message(self, msg):
self._count += 1
self.sender.sendMessage(self._count)
TOKEN = sys.argv[1] # get token from command-line
bot = telepot.DelegatorBot(TOKEN, [
pave_event_space()(
per_chat_id(), create_open, MessageCounter, timeout=10),
])
MessageLoop(bot).run_as_thread()
while 1:
time.sleep(10)
This code creates an instance of MessageCounter for every individual user.
I had written a code for this chat between user and bot,but sometimes I am getting error.
If your question was rather about the errors you're getting than about how to keep a conversation with state, you need to provide more information about what errors you're getting, and when those appear.
Related
I'm trying to use telethon and telebot to send notification from my code in python.
I have configureted everythings, but the code ask me the following:
receiver = InputPeerUser('user_id', 'user_hash')
I fund user_id, but I don't understand where I could catch my user_hash.
You must have an open dialogue with that user. Or you received a message from him. When all the dialogs are loaded, the information of that user comes with it.
If you don't have a 'user_hash', just enter 0.
I.e.:
userid=555555555
userhash=0
receiver=InputPeerUser(userid, userhash)
For those requests having a “limit” parameter, you can often set it to
zero to signify “return default amount”. This won’t work for all of
them though, for instance, in “messages.search” it will actually
return 0 items.
Reference:
https://telethonn.readthedocs.io/en/latest/extra/advanced-usage/accessing-the-full-api.html
Is there a Python Client-Side API for Discord?
I don't need much, just to listen to events like getting a call or a message.
Is it possible?
Note that selfbots are against TOS, and you could be banned without warning.
Sounds like you want a selfbot.
What you might be looking for is Discord.py, many selfbots are written in that, such as:
https://github.com/appu1232/Discord-Selfbot
If you would rather not get banned, discord.py is still good for scripting bots for servers.
Ok late answer but maybe someone can benefit from it so here goes.
Never use discord.py for selfbots. Discord.py was created to work on bot accounts not user accounts. That being said, a lot of things in discord.py will flag your account.
If you want, you can use what I'm currently developing with Merubokkusu: discum: discord selfbot api wrapper
Here's the classic ping-pong example:
import discum
bot=discum.Client(token=yourtoken)
#bot.gateway.command
def pingpong(resp):
if resp.event.message:
m = resp.parsed.auto()
if m['content'] == 'ping':
bot.sendMessage(m['channel_id'], 'pong')
bot.gateway.run()
Here's a ping-pong example where you don't reply to yourself:
import discum
bot=discum.Client(token=yourtoken)
#bot.gateway.command
def pingpong(resp):
if resp.event.message:
m = resp.parsed.auto()
if m['author']['id'] != bot.gateway.session.user['id']
if m['content'] == 'ping':
bot.sendMessage(m['channel_id'], 'pong')
bot.gateway.run()
here's another example, this one appends live messages to a list:
import discum
bot=discum.Client(token=yourtoken)
messagelist = []
#bot.gateway.command
def pingpong(resp):
if resp.event.message:
messagelist.append(resp.raw)
bot.gateway.run()
Also, if you're just doing this in the terminal and don't want to reinitialize your gateway every time, you can just clear the commands you've set
bot.gateway.clearCommands()
and clear the current (gateway) session variables
bot.gateway.resetSession()
Discum is intended to be a raw wrapper in order to give the developer maximum freedom. It's also written to be relatively-simple, easy to build-on, and easy-to-use. Hope this helps someone! Happy coding!
I am using python sdk of botframework for my bot design. I am using waterfall style of dialogs for my conversation design.
My bot starts with a dialog by asking user: "I can show documents for topic A, B, C. Of what topic you would like to see documents?"
To verify if the user has submitted right topic, I use custom Validator and using luis I verify if the user has entered correct topic.
In waterfall step of dialog, I use the topic entered by user to show him the respective topics. But here also I have to hit luis service again to extract the topic from the user message and then using that entity filter from the list of topics.
My question is: Is it possible to pass on the values from the promptValidatorContext to current step context or the next dialog in the waterfall dialog set.
As you can see with following sample code, I am hitting the luis app twice with the same user message, if it's possible to share values between promptValidatorContext and dialogContext, this would me help me avoid hitting luis service twice and could do the same job with one time hitting.
Sample code:
class MainDialog(ComponentDialog):
def __init__(self, dialog_id, luis_app):
self.dialog_id = dialog_id
self.luis_app = luis_app
self.add_dialog(TextPrompt('topic', self.TopicValidator))
self.add_dialog(WaterFallDialog('wf_dialog', [self.Welcome, self.Topic, self.FinalStep])
async def Welcome(self, step_context):
return await step_context.prompt(
'topic',
options = PromptOptions(
prompt = MessageFactory.text('Welcome to the bot, I can show you documents of topic Math, English, Science'),
retry_prompt = MessageFactory.text("I am sorry I didn't understand please try again with different wording")
)
)
async def TopicValidator(self, prompt_context: PromptValidatorContext):
for_luis = prompt_context.recognized.value
#hit the luis app to get the topic name
topic_name = self.luis_app(for_luis)
if topic_name in ['Math', 'Science', 'English']:
return True
else:
return False
async def Topic(self, step_context):
topic_name = self.luis_app(step_context.context.activity.text) #using the same user message as used in Validator function
#filter documents based on topics with custom function filter_doc
docs = filter_doc(topic_name)
return await step_context.prompt('docs', options = PromptOptions(prompt = docs))
async def FinalStep(self, step_context):
#code for final step
I really want to reiterate that I think you should use a choice prompt. Choice prompts are a lot more flexible than you seem to think. The choice recognition is really quite advanced and it is able to recognize a choice in the middle of a phrase and you can even provide synonyms just like in a LUIS list entity. There's an entire folder in the dialogs library dedicated to choice recognition. You think you're giving the user a better experience by using LUIS, but you're actually giving them a worse experience because they can't type an ordinal like 1 or 2 as their choice. Based on what you've told me, I'm certain that a choice prompt is the best option for you.
That being said, here's the information you asked for.
It's common practice to only call any given LUIS endpoint once per turn. If your LUIS model is global for your bot then it would make more sense to call it outside of that dialog, so I'll assume this LUIS model is specific to this dialog.
The most obvious solution would be to store the LUIS result in the turn state. You could store it like this:
prompt_context.context.turn_state[MY_KEY] = self.luis_app(for_luis);
And you could retrieve the value like this:
topic_name = step_context.context.turn_state[MY_KEY];
Another idea would to make luis_app a memoized function (a function that caches its own results). Since the best place for its cache would be the turn state, this isn't so different from the first idea. The main difference is that you'd be changing the luis_app code and leaving your dialog code as it is.
Another idea would be to put your LUIS result in the prompt result. You are free to modify the recognized value from within the validator as you please.
prompt_context.recognized.value = self.luis_app(prompt_context.recognized.value);
That value is accessed in the next step of the waterfall using step_context.result. I should mention that you can also modify the text property of the incoming activity, but that might be considered bad practice.
Finally, you could create your own prompt class that automatically uses a LUIS entity as its recognized value. Perhaps you could call it EntityPrompt or something.
I have a function that runs every hour with apscheduler, this verifies few conditions and according to this sends an email to an arrangement of emails
from mailsnake import MailSnake
mapi = MailSnake('XXXXXXXX', api='mandrill')
def functionEverHour():
users=Users.objects.all()
for users in users:
if users.notificated==False:
mapi.messages.send(message={'html':'sending emails', 'subject':'test', 'from_email':'tes#test.com', 'from_name':'example', 'to':[{'email':str(users.email)}]})
maybe putting this line (mapi = MailSnake('Xajnas12sjnjas', api='mandrill')) in the cycle avoid that kind of mistake?
what does exactly mapi = MailSnake ('Xajnas12sjnjas' api = 'mandrill') that opens a connection to mandrill and never closes and that's the reason I sent emails repetitive (is accumulative?)?
Thanks
This may or not be an error, but why are you doing users in users? It's probably not going to cause an error, but the naming isn't the best in my opinion. My suggestion would be to use naming: all_users = User.objects.all() and users_to_notify in all_users:
Not sure why you're using MailSnake, but this is something mandrill's API handles pretty well.
this is my suggestion about how to change your code. One thing is your method is doing too much. It's handling both the logic of finding the users to notify as well as send the emails. It's best practice to have a function and objects, etc handling only one responsibility.
def get_users_to_notify():
all_users=Users.objects.all()
users_to_notify = []
for user in all_users:
if user.notified==False:
users_to_notify.append(user)
return users_to_notify
def functionEverHour():
users = get_users_to_notify()
for user in user:
mapi.messages.send(message={'html':'sending emails', 'subject':'test', 'from_email':'tes#test.com', 'from_name':'example', 'to':[{'email':str(users.email)}]})
I'm attempting to write a quick load-test script for our ejabberd cluster that simply logs into a chat room, posts a couple of random messages, then exits.
We had attempted this particular test with tsung, but according to the authors, the muc functionality did not make it into this release.
pyxmpp seems to have this functionality, but darned if I can figure out how to make it work. Here's hoping someone has a quick explanation of how to build the client and join/post to the muc.
Thanks!
Hey I stumbled over your question a few times, while trying the same thing.
Here is my answer:
Using http://pyxmpp.jajcus.net/svn/pyxmpp/trunk/examples/echobot.py as a quickstart, all you have to do is import the MUC-Stuff
from pyxmpp.jabber.muc import MucRoomState, MucRoomManager
And once your Client is connected, you can connect to your room:
def session_started(self):
"""Handle session started event. May be overriden in derived classes.
This one requests the user's roster and sends the initial presence."""
print u'SESSION STARTED'
self.request_roster()
p=Presence()
self.stream.send(p)
print u'ConnectToParty'
self.connectToMUC()
def connectToMUC(self):
self.roomManager = MucRoomManager(self.stream);
self.roomHandler = MucRoomHandler()
self.roomState = self.roomManager.join(
room=JID('room#conference.server.domain'),
nick='PartyBot',
handler=self.roomHandler,
history_maxchars=0,
password = None)
self.roomManager.set_handlers()
To send a message, all you have to do is call self.roomState.send_message("Sending this Message")
To do stuff, inherit from MucRoomHandler and react on events. Notice the "set_handlers()" to roomManager though, it's is important, otherwise callbacks will not be called..