I am making a project on mobile-learning.
I am making a telegram bot that first sends a video to the user and if he is ready then sends the quiz.The bot does not wait for the ready condition and sends all messages at one go.I am using mysql database to fetches the video and quiz.
my code in handle(msg) that has problem is :
command=msg["text"].strip().lower()
bot.sendMessage(chat_id,"Say hi to see your options")
if content_type=='text' and chat_id in list1 and command=="hi":
video_link=get_fast_video_link(chat_id)
bot.sendVideo(chat_id,video=open(str(video_link),'rb'));print("video sent")
video_id=get_fast_video_id(chat_id)
list4=start_quiz(video_id)
id_q=list4[0]
question=list4[1]
answer=list4[2]
bot.sendMessage(chat_id,"Are you ready")
if command== "ready":
bot.sendMessage(chat_id,"Here is your question")
bot.sendMessage(chat_id,str(question))
if command==str(answer):
bot.sendMessage(chat_id,"You Are CORRECT")
bot.sendMessage(chat_id,"Let's move to the next video")
Instead of waiting for reply from user the bot sends all messages at one go.
I am new at making bots,and have basic knowledge,how can i make this project
Related
I'm trying to forward messages to channel when I receive messages from api.
I'm using
def trigger(messagecontent):
async def messagesender():
channel = ... #get channel id
await channel.send(messagecontent)
await bot.close()
#bot.event
async def on_ready():
await messagesender()
bot.run(token=Token)`
What happens is, when I receive message from api, I call trigger(messagecontent), the bot logs in, sends message and closes, then the rest of my external script (sync version) executes.
But on the next loop, when new message from api is received, trigger(messagecontent) gives error
Runtime: Session is closed
If I don't close the bot with bot.close(), my sync script will be stuck at discord part. This is why I need to close the bot.
I don't want to use webhooks because there are many channels where messages are to be sent using the same bot.
Why are you shutting down the bot via await bot.close()?
Ofc you will get that error if you shut down the bot.
Telegram introduced Bot API 5.1 with ChatMemberUpdated and the fields my_chat_member and chat_member in the Update class.
But how to track when the user stopped the bot now if I'm using ConversationHandler?
Previously, my bot was waiting for commands like /cancel or /stop.
conversation_handler = ConversationHandler(
entry_points=...,
states=...,
fallbacks=[
# ...
MessageHandler(Filters.regex('^/(cancel|stop)$'), flow_stop_chat),
# ...
],
allow_reentry=True,
name=current_bot_label,
persistent=True,
)
How to do that correctly now using ChatMemberUpdated?
Catch the update using ChatMemberHandler (new in PTB v13.4) and check update.my_chat_member.new_chat_member.status to see if your bot was blocked. However blocking a bot is not quite the same as simply sending a /cancel command, so I'd suggest to keep the MessageHandler (or better yet, change it to CommandHandler(['cancel', 'stop'], flow_stop_chat))
I'm having an issue with FCM on flutter. I have implemented messaging from my server so I'm storing my phone token for each user.
The thing is that when a user logs in for the very first time everything works properly, messages are being sent and user gets notified.
If I do not use the app during the weekend, on Monday I try to send a message by doing some actions on my app but messages are not being sent. I can see my token stored properly in my database.
I'm using firebase_messaging 2.1.0 for flutter.
This is how I get my token
_fireBaseMessaging.getToken().then((token){
_myPhoneToken = token;
});
1-I know token may change when:
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
But none of this happens.
Any advice on how to handle this scenario? thanks in advance.
UPDATE
Provided you have setup the FCM sdk the right way (but you said that it works the fist time you install the app, so I guess so).
Provided that you are sure that the device_token you are using is the one of the device on which you are expecting to receive the notification (check if it's still the same), you should get on this device your notification quite soon if you use "priority" : "high".
{
"to" : "device_token",
"priority" : "high",
"notification" : {
"sound": "default",
"body" : "Test Notification body",
"title": "Test Notification title"
}
}
This method call
_firebaseMessaging.getToken().then((String token)
return always the new token even if it has been updated. So if you print this out on your device and you send a notification on this token without error, there's no reason why you should not get the token if the device has a valid internet connection active.
It's true that the device token can change during time. If you uninstall and reinstall the app, you can see the token will change and if you try to send a notification on the old one, you will get an error.
If instead the token will change during application lifetime, you can be notify on your server side by listening:
_firebaseMessaging.onTokenRefresh.listen((newToken) {
_fcm_token = newToken;
// send the new fcm to your server
});
So first of all I suggest you to be able to send a notification to a device with Postman. Check if the token you are using is still the one on the device. Then you can try to uninstall and reinstall the application and try to use the old token. You will get an error. Then try to send to the new one, and you should get your notification.
Then wait for some days and try again, check if the token has changed or not and if it's not changed you should be able to send the notification without problems with the same token.
Also be aware that data message on Android if the app is terminated are still not supported.
Some networks/router/mobile can cut the connection between firebase library and firebase server due to inactivity (5min without message). This cut may be detected by the library up to 30min (FCM heatbeat interval).
These are some links discussing this issue:
https://github.com/firebase/quickstart-android/issues/307
Android: Delay in Receiving message in FCM(onMessageReceived)
I contacted firebase support but they told that since the issue is caused by external part they cannot fix it (I suggest decreasing heartbeat interval ...)
I fixed it in android using an interval job which apply these instructions:
context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT"));
context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));
You may write this specific code for Android side and should find something similar for ios side.
I know I create new bot, give it name, description from BotFather inside telegram
But this only adds the bot, when I modify my bot, code some functionality in python\lua\php etc - where should the code go and how telegram will know the behavior of my bot?
Who runs the new code, where should I upload my new additional code for my bot?
Does it go to telegram server and runs there on the cloud?
If so, how to upload it?
After you have setup your Bot's identity (#bot_name) with BotFather, the next step is to design the interaction/functions your Bot will perform.
Your bot code lives on YOUR server.
Requests from users interacting with your #bot_name will be routed from Telegram to your servers which ...
1) you have setup with a webHook (using the setWebhook method) so Telegram knows where to send your bot's requests
or
2) your bot polls Telegram's Bot-API repeatedly asking if there are any new updates (i.e. messages users sent to your bot) using the getUpdates method
Your bot receives these messages, and replies as directed by your bots "code or logic"
hope this helps.
You can run the code quite easily from your machine.
For example how I did it using NodeJS:
1)Install NodeJS on your machine (details - https://nodejs.org/en/download/package-manager/)
2)Install Node Telegram Bot API (https://github.com/yagop/node-telegram-bot-api)
3) create a file like this, filling in with necessary changes:
const TelegramBot = require('node-telegram-bot-api');
// replace the value below with the Telegram token you receive from #BotFather
const token = 'YOUR_TELEGRAM_BOT_TOKEN';
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});
// Matches "/echo [whatever]"
bot.onText(/\/echo (.+)/, (msg, match) => {
// 'msg' is the received Message from Telegram
// 'match' is the result of executing the regexp above on the text content
// of the message
const chatId = msg.chat.id;
const resp = match[1]; // the captured "whatever"
// send back the matched "whatever" to the chat
bot.sendMessage(chatId, resp);
});
// Listen for any kind of message. There are different kinds of
// messages.
bot.on('message', (msg) => {
const chatId = msg.chat.id;
// send a message to the chat acknowledging receipt of their message
bot.sendMessage(chatId, 'Received your message');
});
4) Finally launch your command console (like cmd on Windows) navigate to telegram bot directory where the script is located and type node index.js (assuming your file with the bot script like above is named index.js)
Following these steps you will have a fully functioning bot. As you make changes to index.js you can simply rerun the command "node index.js" in console.
The procedure is similar if you need to set up a bot on a server.
Hope this helps.
I have searched the web on my question but did not find anyone answering it. This looks weird as I am sure other people face similar issue.
At the moment my app is receiving push notification fine. I have a chat module where user can speak and whenever a new message is being sent, the other phone receive a push notification to update the chat.
You could say no issue there, but the problem is when the user is out of the application: he is still receiving those notifications showing a banner on the screen, and I want to dis-activate this. Basically I want push notification without alerts to the user. Is there a way to do that?
Thanks
Just leave the sound property of your push notification payload empty, omit the alert/text property and add "content-available":1 and your notification will be silent. This is often referred to as silent push notification or "push-to-sync".
See documentation here:
For a push notification to trigger a download operation, the
notification’s payload must include the content-available key with its
value set to 1. When that key is present, the system wakes the app in
the background (or launches it into the background) and calls the app
delegate’s
application:didReceiveRemoteNotification:fetchCompletionHandler:
method. Your implementation of that method should download the
relevant content and integrate it into your app
So your payload should least look like this:
{
"aps" : {
"content-available" : 1,
"sound" : ""
},
"chat-message" : "Hello World!"
}