Using python-telegram-bot, I have a bot running with very similar settings as for the other examples. On the other side i have parallel processes that allow me to send messages to users interacting with the bot periodically. The parallel proccess communicates with the users using:
bot = Bot(token=TELEGRAM_TOKEN)
def get_button_options():
keyboard = [[ InlineKeyboardButton("reply", callback_data='reply),]]
reply_markup = InlineKeyboardMarkup(keyboard)
return reply_markup
bot.send_message(chat_id=self.telegram_id, text=text, reply_markup=get_button_options())
The thing is, even if I'm capable to send messages to the user, the above code does not allow the user to interact with the bot (By that I mean that, once the user presses the button, the bot doesn't execute any callback). This is because I need either a CallbackQueryHandler or ConversationHandler within the bot.
However for the ConversationHandler I don't seem to find any appropiate entry_point, since it is a message sent from a parallel process. On the other hand, using the following CallbackQueryHandler (taken from the example) in the main bot doesn't seem to have any effect:
def button(update: Update, _: CallbackContext) -> None:
query = update.callback_query
# CallbackQueries need to be answered, even if no notification to the user is needed
# Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery
query.answer()
query.edit_message_text(text=f"Selected option: {query.data}")
in the main function, I have added the handler using updater.dispatcher.add_handler(CallbackQueryHandler(button))
Any ideas on how to solve that?
As said by #CallMeStag, the solution is the following:
ConversationHandler(
entry_points=[CallbackQueryHandler(button)])
the correct entry point is a CallbackQueryHandler, so then it captures the selected button
Related
I have created and deployed a telegram bot which can perform some simple chat and analytics functions.
I have set a couple of / commands via botfathers /setcommands functionality and they all work fine.
However in group chats I have a problem, when I add the bot he works normally however the set commands that you can execute via the menu always include an #bot_name at the end of each command which invalidates them.
If I type in the command myself and remove the #mention, the commands work normally.
How can I tackle this issue, is it something I need to set in my code or in botfather?
if ($cmd == "/command" || $cmd == "/command#BOT_USERNAME") {
// handle scenario
}
My suggestion is to modify your code and replace the '#your_bot' with an empty string '' from the command before processing it. That way you automatically handle both scenarios for each of the available commands.
Sadly, Telegram had a bug once or twice where it wouldn't register the #your_bot messages sent to it. Luckily that bug was live for a very short period of time.
I'd like to remove a slack bot from a channel using slack's API.
I've tried channels.kick but ofcourse, a bot is not a user so it can't be deleted that way. I haven't found any solutions so far on the interwet or on Slacks API documentation.
You are not correct. You can remove a bot user from a public channel or private channel using API methods just fine. I just tested it on a private channel to confirm.
So there must be another reason why this does not work for you. Please check if any of these reasons below apply to your case. Also, please provide the error message you are getting from the API, as that would greatly help to identify the reason.
Here are some potential reasons why kicking a bot user might not work for you:
wrong method: channels.kick only works for public channel, use groups.kick for private channels.
wrong token: bot tokens can not use the kick methods. You need to use a user access token to invoke that API method. (you would get the user_is_bot error)
trying to remove oneself: a user can not kick himself. (you would get the cant_kick_self error)
not using channel IDs: the kick methods require you to provide a channel ID, the name will not work. (you would get the channel_not_found error)
Based on your question I would assume you are getting the user_is_bot error, which let you to assume (incorrectly) that you can't kick a bot. In that case the solution would be to use a user token (not a bot token) to execute the method.
I feel I must be doing something wrong in the API. I am following the weather example with a missing location. The story works fine.
However when I use the API over http using postman for testing purposes I cannot get it to raise the action after sending back the location from the user, It always returns a stop message. I think I must be not sending the correct context across or similar.
My understanding is as follows:
send across message 'I want to know the weather'
raises action from wit: 'Weather' (works correctly)
Respond with 'missingLocation'
wit replies with msg 'Which location do you want to know the weather for?' (works correctly)
I respond with 'Paris' in the message (no context all with same session)
wit replies with finding the entity 'Paris' but a 'stop' and no action. Here I would expect to get an action request again with everything I need to know this time. This is what happens when I use the story and test using the bot messenger.
Any ideas from anyone? I expect I need to respond with something more than just 'Paris' in the message
Thanks.
Note: the question was asked by "scruffjinks" on github before with no answer
https://github.com/wit-ai/wit/issues/301
I want to make easy application with sending messages (rabbitmq). When run program I want to write messages and receive it (in same console). So how can I write a method "subcribe" which will be running all the time(after starting program) and waiting to receive message? and at same time of course i should be able to write a message
Create a supervised app (mix new my_app --sup ).
You implement two GenServer, one for receiving (MyApp.Reader) and the other one for sending (MyApp.Writer). You add both GenServer as worker in your supervisor spec.
I guess your RabbitMQ adapter (never used it with elixir so you'll have to double check) will also be supervised. Name it, and pass its name to both GenServer init method (via the args you pass when declaring your workers for example)
You can also implement your API for the writer directly in MyApp. Something like:
def send(message) do
GenServer.cast(:name_of_writer, $message)
end
You'll then be able to do: MyApp.send("some message")
Your receiver worker, would on its side, receive all messages, and print them to the CLi, either using inspect or the Logger module
Have a look at the GenServer docs, there is some code example that will help you.
I working on high-scalability web site for learning purpose. I decided to use CQS pattern and some ideas of CQRS. I have separate write and read layers used by command handlers and event handlers which system sends and receives from message buses (two separate message- buses).
I have some problem dealing with commands. I read that command shouldn't return anything. And now the point is: for example I have a form on with user can create an event or for example change something in his profile (photo or name). After user clicked save i want to show him, his profile or add a new event to his wall. But how can I know that his profile has been already updated when command is only send to the bus ? I How connect idea of command and CRUD operations ? Or maybe this wrong idea at all ?
Well first off, the split should not be between commands and events, but rather between domain and read models. You can't really map CQRS commands to CRUD operations as a general rule, although most of the commands in your system will change the state of your repositories. I will give you a general overview of how this works. Say you want to add a user, you create a command AddUserCommand and assign an id to that message. On the back end, you have an handler for that command and you're right that the command does not return nothing. Once that command is handled you should publish and event reflecting the change: UserWasAddedEvent. The id of this message will be unique, but it can and should have an id related to the command which you created in the UI. Your read models should handle the event and update a read model with the command status (waiting, processing, completedOnError, completedSuccessfully) depending on the event you published. On the UI after you submited the command, you should start querying the read models whith the ID of the command you created to get the status and then update your UI accordigly.
Your right that CQRS handlers return void, but you should bear in mind that typically in an architecture like this, the backend should return the validation results of the submited commands, not the handler itself but the infrastucture around your cqrs handlers.
Just update te UI on the assumption the command succeeds - which most of the time it will.
If validation is required on the user input, you could run validation as the user types or tabs to increase the likelyhood the command will succeed.