How to edit a deferring message via discord.py on program restart or with requests module? - python-requests

i have this command:
#bot.tree.command(name="restart", description="Restart the bot")
#app_commands.check(is_owner)
async def restart(interaction: discord.Interaction):
await interaction.response.defer()
os.execl(sys.executable, sys.executable, *sys.argv)
and, as you can see, it restarts the program.
but what I want it to also do, is when it does restart, send a followup message editing the defered message telling the user (me) that the bot has restarted.
Edit:
I have an on_ready event registered that I could do this in, but I don't know exactly how to do it.
I tried looking at interactions.py but couldn't find the send function that is said to be tied to it in the docs.

Related

telegram use schedule message

I want to schedule a telegram bot message to be sent at a specific unixtime.
As from telegrams official api (https://core.telegram.org/api/scheduled-messages) that should be possible by setting the schedule_date flag.
To schedule a message, simply provide a future unixtime in the schedule_date flag of messages.sendMessage or messages.sendMedia.
However I was not able to set that flag. To be more precisely, I do not even know how to set a flag, or if I am using the correct api.
What I have tried is to use the api directly via the browser (could use curl as well) like so: https://api.telegram.org/botBOT:TOKEN/sendMessage?chat_id=ID&text=Test&schedule_date=1653503351
I also did not find any way to access this flag via https://pypi.org/project/pyTelegramBotAPI/#description https://telepot.readthedocs.io/en/latest/#send-a-message, nor https://github.com/nickoala/telepot.
I want to implement this feature in a python environment, but any working suggestion would be much appreciated.
EDIT:
I decided to save the intention to send a telegram bot message at a certain unixtime in a database. I then create an infinite loop that checks if there are any unsent messages before the current timestamp. If the loop detects such a message it sends the message and sets a flag, that that message has been sent.
And as promised, here is a fully dockerized example of that behaviour in action: https://github.com/Sokrates1989/nameTheCountDown-lightweight
It creates a bot that you can pass a name and the duration. Once the duration has passed it sends a message with the passed name. Basically a simple countdown that you can give several names, that run simltaniously. As it is a telegram chat, you can modify the way you are informed about the end of a countdown by modifying the notificaiton of that chat.
And here is the Bot in action: http://t.me/NameTheCountdownBot
We can't do this by bot API itself, and there's no schedule_date parameter in sendMessage method:
https://core.telegram.org/bots/api#sendmessage
And what you've read is for Telegram clients, not bot API consumers.
If you don't really need unixtime, you can simply create a table for scheduled messages with a text, chat_id and a publish_time column (like 22:15), and run a command every minute to look if there's a message for current time to send. Then send the message and delete the record.
Note that the python-telegram-bot library has a built-in solution for scheduling tasks: The JobQueue. This feature is based on the APScheduler library, which you can ofc also use without python-telegram-bot.
Disclaimer: I'm currently the maintainer of python-telegram-bot.
https://core.telegram.org/method/messages.sendScheduledMessages
Now you can send scheduled messages right away

Asterisk AMI events sometimes missing

I have a Python service which connects to Asterisk via AMI and listens for events to detect when a call has begun.
This seems to work on most of the Asterisk servers I connect to. However, on a few of our servers we just don't see any of the AMI events (e.g. Newstate) when the call happens, though we do later see the Cdr event once the call has completed.
I've confirmed that this isn't specific to the library we're using to connect to AMI (py-Asterisk), because I see exactly the same thing when I connect manually, e.g.
$ openssl s_client -connect my-asterisk-server:5039
...
Asterisk Call Manager/2.10.3
Action: Login
Username: manager
Secret: ThisIsWhereITypedTheActualPassword
Response: Success
Message: Authentication accepted
Event: FullyBooted
Privilege: system,all
Status: Fully Booted
Action: Events
EventMask: on
Response: Success
Events: on
In the above block, I manually connected to AMI, logged in as the same administrator my Python code is using, and ensured that all events are turned on (though my asterisk config should already be displaying all events I care about by default).
After this point what I see on some of my Asterisk servers is a series of expected events like Newstate, followed by an eventual Cdr event. On other servers, I see only the Cdr event, with nothing proceeding it. This is completely consistened within each server, meaning a server either always sends all of the expected events or it never does.
I've checked the versions of asterisk, the manager.conf config file, the extensions.conf dialplan, the asterisk console in verbose mode (i.e. connecting via asterisk -vvvr to the running process), and just generally comparing my config files to my actually-working Asterisk servers.
I'm stumped as to what could be causing this, or even what to try next. If it matters, here's what my manager.conf looks like:
[general]
tlsenable=yes
tlsbindaddr=10.0.0.123:5039
tlscertfile=/etc/pki/asterisk/ami.crt
tlsprivatekey=/etc/pki/asterisk/ami.key
[admin]
secret=TheActualPasswordIsOnThisLine
read=system,call,log,verbose,command,agent,user,originate,cdr
write=system,call,log,verbose,command,agent,user,originate,cdr
EDIT: After some further digging, it seems that the only events which are showing up are Cdr events, so even things like peer registration events don't show up. I've also confirmed that all of my Asterisk 13.19.0-1 servers are exhibiting this behavior, and the only working servers are running much older versions of Asterisk.
The weird thing is that calls do come through successfully, so the problem is not that I'm missing some necessary module. (Or maybe I am? Is there some "make events show up in AMI" module that I need to ensure is loaded?)
FURTHER EDIT: I was able to turn on CEL events (Channel Event Logging), and those events show up, but this is a different set of events than the standard Newchannel/Newstate/etc I'm looking for. In theory I could rewrite a large portion of my service to use the CEL events, but ideally I'd just turn on the standard Newstate/Newchannel/Hangup events.
It turns out the issue is that I was missing
enabled=yes
in my manager.conf. Hopefully this will be helpful to someone in the future: even if you're able to connect to AMI, log into AMI, receive some events from AMI, and send commands to AMI and get responses back, it might not be enabled, and this will suppress most of the core events like Newchannel, Newstate, etc.
One clue was that running manager show settings in the asterisk console returned this:
Global Settings:
----------------
Manager (AMI) No
...
which is apparently how it indicates that it's not enabled.

Firebase Functions: Could not load default credentials

I have a Firebase Function that subscribes to a Cloud PubSub topic. App is initialized very simply like this:
import * as admin from 'firebase-admin';
admin.initializeApp();
I'm getting this error:
"Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
at GoogleAuth.getApplicationDefaultAsync (/srv/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
at process._tickCallback (internal/process/next_tick.js:68:7)"
Here's the weird thing. It typically works. In other words, if I trigger it a second time it works. And a third time. Most often it seems to fail the first time it runs after a new firebase deploy and possibly on a "cold start."
Not sure what I'm doing wrong and why it would fail only on the first run.
SOLVED! This answer helped:
Error: Could not load the default credentials (Firebase function to firestore)
From within a Firebase Function for an API call, I was publishing to a Cloud PubSub topic like this:
pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I was not awaiting the response and was immediately sending the 2XX HTTP response back to the client. The execution seemed to continue fine, but obviously it did not behave as intended.
Sometimes the API response call itself would fail (and never publish the message), but sometimes not. In other cases, the publish would succeed but the Firebase Function subscribing to the topic would fail!
In all cases, this seemed to resolve itself after running the script a second time. For this reason, I still believe it had something to do with a cold start.
But since I changed it to await like this:
await pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I have not seen this problem happen again.

How to make async requests using HTTPoison?

Background
We have an app that deals with a considerable amount of requests per second. This app needs to notify an external service, by making a GET call via HTTPS to one of our servers.
Objective
The objective here is to use HTTPoison to make async GET requests. I don't really care about the response of the requests, all I care is to know if they failed or not, so I can write any possible errors into a logger.
If it succeeds I don't want to do anything.
Research
I have checked the official documentation for HTTPoison and I see that they support async requests:
https://hexdocs.pm/httpoison/readme.html#usage
However, I have 2 issues with this approach:
They use flush to show the request was completed. I can't loggin into the app and manually flush to see how the requests are going, that would be insane.
They don't show any notifications mechanism for when we get the responses or errors.
So, I have a simple question:
How do I get asynchronously notified that my request failed or succeeded?
I assume that the default HTTPoison.get is synchronous, as shown in the documentation.
This could be achieved by spawning a new process per-request. Consider something like:
notify = fn response ->
# Any handling logic - write do DB? Send a message to another process?
# Here, I'll just print the result
IO.inspect(response)
end
spawn(fn ->
resp = HTTPoison.get("http://google.com")
notify.(resp)
end) # spawn will not block, so it will attempt to execute next spawn straig away
spawn(fn ->
resp = HTTPoison.get("http://yahoo.com")
notify.(resp)
end) # This will be executed immediately after previoius `spawn`
Please take a look at the documentation of spawn/1 I've pointed out here.
Hope that helps!

authWithCustomToken not firing callback

When a user registers on my system, I create the user internally, and then allow the user to register with Firebase using the firebase client lib. This generates a session token for the user. Later, when a user starts the app again, the app automatically logs the user in like this:
ref.authWithCustomToken(sessionToken, function(error, authData) {...
debugger
I have verified that the sessionToken is available when the function is executed, but debugger is never reached, and no error is ever emitted.
Any help is appreciated!
I know it's a bit late, but I experienced a similar problem and it had me scratching my head for a while, so just in case it helps somebody else, here's what I found.
If I run authWithCustomToken with a token generated with one uid (uid1) and then run it again on the same ref with a different uid (uid2), the callback doesn't get fired the second time around.
In my case, I had declared the same ref in different modules that were used in the same node process and was trying to authenticate them with different uids. Although I had declared the ref twice, Firebase still saw it as the same ref because it was in the same process and referred to the same Firebase location. By declaring and authorising the ref in a parent module, I was then able to use onAuth in the child modules and the onAuth callbacks all fired as expected.
I had a similar problem with iOS, authWithCustomToken callback was never called right after install.
All consecutive launches worked fine.
My findings might be related so I thought I share them.
Problem was I called
func applicationWillResignActive(application: UIApplication) {
Firebase.goOffline()
}
func applicationWillEnterForeground(application: UIApplication) {
Firebase.goOnline()
}
in AppDelegate. Turns out if you call Firebase.goOnline() without logging in first it messes up the callback. Once I removed those two lines everything worked fine.

Resources