Facebook messenger chatbot gives duplicate replies - python

I'm building a chatbot with wit.ai and python and integrating it with Facebook Messenger. I have set up webhooks as well as send function and fb_message function exactly like in this tutorial: https://github.com/wit-ai/pywit/blob/master/examples/messenger.py
My bot works fine when I test it in wit.ai or in console, but when I test it in actual Facebook Messenger, it gives each reply twice. It doesn't matter which function inside the bot gets called, I always get two replies.
My most simple action is this:
def defaultAnswer(request):
context = request['context']
return context
(This returns always the same string, which is defined in wit.ai engine.)

If your bot is subscribed to events other than pages_messaging, like messaging_deliveries, make sure you're handling this event as well.
What's happening is your that bot is receiving the message request, then receiving another one by another event, and your code is handling them both as messages.
I think this is the problem, and if it's not, give us more details about it.

Someone might have a case like mine.
My case:
I mistakenly subscribe my two different bots to one facebook page on the developer.facebook.com.
Due to the this mistake, when i write a specific command(e.g. restart) to my facebook page, bot replies exactly same two messages(e.g. "Bot Restarted", "Bot Restarted") to me.
It made me a crazy to find out the problem.
You should subscribe one bot to your facebook page at most.

I had this issue before and it turns out, the message_echoes was enabled. What happens essentially if this is enabled is that the Bot will try to echo whatever you text you entered.
My logic ended up catching the echo and then responded with the same response. I do have a handler to catch similar responses so I was able to avoid the infinite loop.

Related

How to communicate to an always running python script

i'm developing a python telegram bot and i have a script that is always running (for receiving new command from telegram) and i want the bot to send messages when the user perform a action in a website.
example: the user start the bot, the bot send a link to perform an action in the website (like login to the user's account and connect the telegram id with the user id) and then send a confirmation message on telegram that all's good.
my problem is how i can tell the python script that the action in the browser is done? for now i'm constantly query a database but my solution is pretty dumb because if the user don't perform any action the query can go forever.
any suggestion how to do it correctly?
thx <3
I see two viable solutions here:
Send the message directly from the website. While only one process is allowed to fetch updates at a time, you can make other requests from as many servers as you like. Depending on how your website works, you can make a plain HTTP request to the Bot API or use an API wrapper like python-telegram-bot or a wrapper in a different language to make the request. e.g. if you're running a php-based website, you could use a php API wrapper.
If for some reason 1. is not an option for you, you can try to inform your running process about the user login. the PTB FAQ have an entry that should help you get started. If your website & bot are running on the same server, it might be possible to make the update_queue directly available to the website process. If not, you can try to set up a webhook for your bot and post an update to the webhook that you then enqueue into the update_queue
Approach 1. has the downside that you don't have all the bot logic in one place, but it should be by far easier to implement than 2.
Disclaimer: I'm currently the maintainer of python-telegram-bot

How to use a user account to fetch/get messages (discord.py)

I have 2 discord client instances a bot and a user account. I have already figured out how to copy messages from one channel to another channel, basically a on_message event. However, I want to know if there is a way I can use the user account to fetch the messages, I've tried fetching messages in different guilds but they didn't work because the bot was not in the server and the bot is fetching messages. I've tried using the user account instance to do it but it didn't really work.
The comments were there as a guide for myself because I'm not that familiar with Python it's fairly new to me. If anyone knows how I can use the user account to get or fetch the messages I'd appreciate the help...
PS: I know that some of the code isn't needed, I haven't removed anything that isn't needed. I wanted to actually finish the project before inspecting it.
I just wanted to know that I have tried this myself and it is not possible. Because from discord.py's Docs. Which you can find down below, does not allow users (user account) to transfer data to a bot since you would need to request from discord API which leads to user getting banned (Very quickly) theere are some work arrounds but I would suggest not doing so since self botting is against the TOS of discord
https://discordpy.readthedocs.io/en/stable/
EDIT: Another thing is that discord API blocks users from fetching or getting anything using a user account with discord.py

how to send auto delete messages whit Telegram bot

I have a doubt. I've been looking for information and haven't found anything. I would like to know if it is possible to send a message with a bot which will be eliminated after a certain time. I'm working with c# but I think other examples will work for me. Thanks in advance.
I thought I would delete my own message after a while but I think it would not be a solution in a well active chat, since there are many messages coming in all the time and I would not know for sure what the id of the message I sent is. I would have to do another algorithm to find out what that id is, and what I was trying to see is if there was some simpler method already implemented in the api for these specific cases. Send messages using the bot with self-destruct after a while.
I'm not sure if telegram API provides that.
but you can implement it in the bot to do that, maybe with "time" or "schedule" in python

Can a Slack bot interact with another bot and trigger some functions of it in a channel?

I built a Slack bot and tried to make my bot interact with another bot in the a channel, but it seems not working.
For example, I want to use the voting function of Polly (a Slack bot).
Regular users like me send /polly "Which is better?" "Tacos" "Pizza" message and Polly will create a Slack poll in a channel. But when I made my bot send the same message in the same channel (I use python-slackclient and chat.postMessage method), the message just like a simple text, in other words, it didn't trigger Polly.
So, in a channel, how can a Slack bot interact with another bot and trigger some functions of it?
Did anybody ever do something like this?
update
https://github.com/ErikKalkoken/slackApiDoc/blob/master/chat.command.md
I tried this method but got another problem...
The error message is
{'error': 'missing_scope',
'needed': 'post',
'ok': False,
'provided': 'identify,bot:basic'}
The Oauth token requires "post" scope, but official documents show that "post" scope is deprecated. How do I make my token have "post" scope?
I have tried to make two bots interact and didn't find it to work. Slack somehow recognizes the source of the message and if the message is sent by a bot or an app, it fails to respond to it. I have even tried to post the message as a user through the slack API but did not get it to work.
However, Bots can use the chat.command method to invoke a slash command.
Unofficial documentation can be found here:
https://github.com/ErikKalkoken/slackApiDoc/blob/master/chat.command.md
You are correct that the undocumented chat.command requires the post scope to work, which is not available in the standard OAuth process (e.g. you can not choose it as scope on the Slack app config site.)
The only currently working solution that I know of it to use a legacy token.
See also this answer.

Handle multiple questions for Telegram bot in python

I'm programming a telegram bot in Python using the Telegram bot API. I'm facing the problem of managing questions that need an answer of the user. The problem arises when the program is waiting for an answer of one user and another user request information or ask another question before the first user responds.
The Telegram API uses a code to handle the request. When you ask for updates you include a code. If the code you send is higher than a request code, it is mark as handled and telegram delete it and no longer appears in the updates. This code is sequential, so if you mark update 3 as handled, updates 1 and 2 are erased as well.
The question is why is the best phytonic/elegant way to handle multiple requests that needs an answer for the users?
There is not a most pythonic way of doing this. It is a problem you have to program to solve.
Basically, you have to maintain some state variables concerning each user. When a new message arrives, the bot checks what state that user is in, and responds accordingly.
Suppose you have a function, handle(msg), that gets called for each arriving message:
user_states = {}
def handle(msg):
chat_id = msg['chat']['id']
if chat_id not in user_states:
user_states[chat_id] = some initial state ...
state = user_states[chat_id]
# respond according to `state`
This will do for a simple program.
For more complicated situations, I recommend using telepot, a Python framework I have created for Telegram Bot API. It has features that specifically solve this kind of problems.
For example, below is a bot that counts how many messages have been sent by an individual user. If no message is received after 10 seconds, it starts over (timeout). The counting is done per chat - that's the important point.
import sys
import telepot
from telepot.delegate import per_chat_id, create_open
class MessageCounter(telepot.helper.ChatHandler):
def __init__(self, seed_tuple, timeout):
super(MessageCounter, self).__init__(seed_tuple, timeout)
self._count = 0
def on_message(self, msg):
self._count += 1
self.sender.sendMessage(self._count)
TOKEN = sys.argv[1] # get token from command-line
bot = telepot.DelegatorBot(TOKEN, [
(per_chat_id(), create_open(MessageCounter, timeout=10)),
])
bot.notifyOnMessage(run_forever=True)
Run the program by:
python messagecounter.py <token>
Go to the project page to learn more if you are interested. There are a lot of documentations and non-trivial examples.
In my bots I use webhooking. If you can to use web hooks - do it, it's more comfortable way to interactive with telegram bots.
If you can't webhooking (ssl problems, for example), there is workaround for you. Use ForceReply in order to get previous bot answer and write logic based on user replies.
Check if update contains reply (reply_to_message key), then make bot answer based on this reply. These actions must be asynchronous in order to get high bot performance.
If you are python programmer, I recommend Tornado for these purposes.

Categories