Python telegram bot cooldown function - python

I was stuck on my code due to the reason that it's not responding
because i want a bot that /price command has a cooldown and in the next time someone use /price command it will wont respond for 30 mins or prompt people to wait until the cooldown is done so that it will be less spammy on telegram groups when many people doing /price in a same time
def price(update, context):
if chat_data.get('last_time'):
if datetime.now()-last_time <= my_threshold:
return
chat_data['last_time'] = datetime.now()
update.message.reply_text(
'Bitcoin PRICE TRACKER \n'
'🤑 Price: $ ' + usd + '\n'
'📈 Marketcap: $ ' + usdcap + '\n'
'💸 24 Hour Volume: $ ' + usdvol + '\n'
'💵 24 Hour Change: % ' + usdchange + '\n'
'⚙️ Last Updated at: ' + lastat +'\n'
)
updater = Updater('mytoken', use_context=True)
updater.dispatcher.add_handler(CommandHandler('price', price))

What about something django-rest style, like a decorator?
import datetime
throttle_data = {
'minutes': 30,
'last_time': None
}
def throttle(func):
def wrapper(*args, **kwargs):
now = datetime.datetime.now()
delta = now - datetime.timedelta(minutes=throttle_data.get('minutes', 30))
last_time = throttle_data.get('last_time')
if not last_time:
last_time = delta
if last_time <= delta:
throttle_data['last_time'] = now
func(*args, **kwargs)
else:
return not_allowed(*args)
return wrapper
def not_allowed(update, context):
update.message.reply_text(text="You are not allowed.")
#throttle
def price(update, context):
update.message.reply_text(
'Bitcoin PRICE TRACKER \n'
'🤑 Price: $ ' + usd + '\n'
'📈 Marketcap: $ ' + usdcap + '\n'
'💸 24 Hour Volume: $ ' + usdvol + '\n'
'💵 24 Hour Change: % ' + usdchange + '\n'
'⚙️ Last Updated at: ' + lastat +'\n'
)
updater = Updater('mytoken', use_context=True)
updater.dispatcher.add_handler(CommandHandler('price', price))
Of course throttle is resetted everytime you restart the bot.
This, by the way, will spam "You are not allowed", so I you have a lot of user throttling, you change not_allowed function removing the reply.

Related

authHash from another language to python

The following is the api guide from bold360 website
accountId=[your account id]
apiSettingId=[your API setting id]
apiKey=[your API key]
auth="$accountId:$apiSettingId:$( date +"%s" )000"
authHash="$auth:$( echo -n "$auth$apiKey" | openssl dgst -sha512 | sed 's/^.* //')"
Questions: I don't really understand the last two lines of code mean.
$( date +"%s" )000
2.( echo -n "$auth$apiKey" | openssl dgst -sha512 | sed 's/^.* //')
what does it look like if this is in Python?
I wrote this in python
def millsecond(dt):
epoch = dt.utcfromtimestamp(0)
return (dt-epoch).total_seconds() * 1000.0
def makeAuth():
# seconds = time.time()
timestamp = int(millsecond(dt.now()))
token = str(accountId) + ":" + str(settingID) + ":" + str(timestamp) + api_key
hash = hashlib.sha512(token.encode('utf-8')).hexdigest()
auth = str(accountId) + ":" + str(settingID) + ":" + str(timestamp) + ":" + str(hash)
return auth
authHash = makeAuth()
url_runReport = "https://api.boldchat.com/aid/[AccountID]/data/rest/json/v1/runReport?auth=[auth]&ReportType=0&Grouping=chat_type&FromDate=2023-01-27T00:00:00-08:00&ToDate=2023-01-27T23:59:59-08:00"
response_runReport = requests.get(url_runReport)
runReport_data = response_runReport.json()
my result always shows
{'Status': 'error', 'Message': 'Expired authorization'}
My guess is authhash is not correct. Can someone teach me how to code the authHash in python? Thanks

How can I send a sms in Django?

I encountered a problem when trying to send sms using the SMSC service in Django project.
My Celery task for sending email and sms:
def order_created_retail(order_id):
# Task to send an email when an order is successfully created
order = OrderRetail.objects.get(id=order_id)
subject = 'Order №{}.'.format(order_id)
message_mail = 'Hello, {}! You have successfully placed an order{}. Manager will contact you shortly'.format(order.first_name, order.id)
message_sms = 'Your order №{} is accepted! Wait for operator call'
mail_sent = send_mail(
subject,
message_mail,
'email#email.com',
[order.email]
)
smsc = SMSC()
sms_sent = smsc.send_sms(
[order.phone],
str(message_sms)
)
return mail_sent, sms_sent
Email sends correctly, but for sms I get that error:
Task orders.tasks.order_created_retail[f05458b1-65e8-493b-9069-fbaa55083e7a] raised unexpected: TypeError('quote_from_bytes() expected bytes')
function from SMSC library:
def send_sms(self, phones, message, translit=0, time="", id=0, format=0, sender=False, query=""):
formats = ["flash=1", "push=1", "hlr=1", "bin=1", "bin=2", "ping=1", "mms=1", "mail=1", "call=1", "viber=1", "soc=1"]
m = self._smsc_send_cmd("send", "cost=3&phones=" + quote(phones) + "&mes=" + quote(message) + \
"&translit=" + str(translit) + "&id=" + str(id) + ifs(format > 0, "&" + formats[format-1], "") + \
ifs(sender == False, "", "&sender=" + quote(str(sender))) + \
ifs(time, "&time=" + quote(time), "") + ifs(query, "&" + query, ""))
# (id, cnt, cost, balance) или (id, -error)
if SMSC_DEBUG:
if m[1] > "0":
print("Сообщение отправлено успешно. ID: " + m[0] + ", всего SMS: " + m[1] + ", стоимость: " + m[2] + ", баланс: " + m[3])
else:
print("Ошибка №" + m[1][1:] + ifs(m[0] > "0", ", ID: " + m[0], ""))
return m
What am I doing wrong?
Thanks!
to solve this problem, I started investigating the functions that were giving out the error.
It turned out that I was passing an incorrect value. the function was expecting a string. And it took me a long time to figure out why editing didn't help.
It turns out that you have to RESET CELERY every time you make an edit.

Python schedule to run a function at specific day between time periods

I've got a function that accesses an API to check for train data at specific times. This is actually run 3 times for each journey, so I'd need to run each of the 3 at specific times.
I've tried using the schedule module to get this going but I can't seem to get it working. Here's my current code:
schedule.every().day.at("07:30").every(5).minutes.do(darwinChecker(train_station['home_station'], train_station['connect_station'], user_time['morning_time']))
But I get an AttributeError: 'Job' object has no attribute 'every'. The documentation states this happens if your code imports the wrong schedule module, but I've no other files under that name.
How would I go about running my function, say, every Friday from 07:30 till 08:40, every 5 minutes?
Edit: As per request, added my full code for what I'm trying to do:
import requests
import re
import schedule
import time
from darwin_token import DARWIN_KEY
jsonToken = DARWIN_KEY
train_station = {'work_station': 'bat', 'home_station': 'man', 'connect_station': 'wds'}
user_time = {'morning_time': ['0821', '0853'], 'evening_time': ['1733'], 'connect_time': ['0834', '0843']}
def darwinChecker(departure_station, arrival_station, user_time):
response = requests.get("https://huxley.apphb.com/all/" + str(departure_station) + "/to/" + str(arrival_station) + "/" + str(user_time), params={"accessToken": jsonToken})
response.raise_for_status() # this makes an error if something failed
data1 = response.json()
train_service = data1["trainServices"]
print('Departure Station: ' + str(data1.get('crs')))
print('Arrival Station: ' + str(data1.get('filtercrs')))
print('-' * 40)
try:
found_service = 0 # keeps track of services so note is generated if service not in user_time
for index, service in enumerate(train_service):
if service['sta'].replace(':', '') in user_time: # replaces sta time with values in user_time
found_service += 1 # increments for each service in user_time
print('Service RSID: ' + str(train_service[index]['rsid']))
print('Scheduled arrival time: ' + str(train_service[index]['sta']))
print('Scheduled departure time: ' + str(train_service[index]['std']))
print('Status: ' + str(train_service[index]['eta']))
print('-' * 40)
if service['eta'] == 'Cancelled':
# print('The ' + str(train_service[index]['sta']) + ' service is cancelled.')
print('Previous train departure time: ' + str(train_service[index - 1]['sta']))
print('Previous train status: ' + str(train_service[index - 1]['eta']))
if found_service == 0: # if no service is found
print('The services currently available are not specified in user_time.')
except TypeError:
print('There is no train service data')
try:
# print('\nNRCC Messages: ' + str(data1['nrccMessages'][0]['value']))
NRCCRegex = re.compile('^(.*?)[\.!\?](?:\s|$)') # regex pulls all characters until hitting a . or ! or ?
myline = NRCCRegex.search(data1['nrccMessages'][0]['value']) # regex searches through nrccMessages
print('\nNRCC Messages: ' + myline.group(1)) # prints parsed NRCC message
except (TypeError, AttributeError) as error: # tuple catches multiple errors, AttributeError for None value
print('There is no NRCC data currently available\n')
print('Morning Journey'.center(50, '='))
darwinChecker(train_station['home_station'], train_station['connect_station'], user_time['morning_time'])
# schedule.every().day.at("21:50").do()
# schedule.every(2).seconds.do(darwinChecker,train_station['home_station'], train_station['connect_station'], user_time['morning_time'])
schedule.every().day.at("07:30").every(5).minutes.do(darwinChecker,train_station['home_station'], train_station['connect_station'], user_time['morning_time'])
while True:
schedule.run_pending()
time.sleep(1)
# print('Connection Journey'.center(50, '='))
# darwinChecker(train_station['connect_station'], train_station['work_station'], user_time['connect_time'])
# print('Evening Journey'.center(50, '='))
# darwinChecker(train_station['work_station'], train_station['home_station'], user_time['evening_time'])`

Add function names to a string in Python

I'm just beginning to learn Python on my own, and I'm trying to write a code that will calculate the end time of a jog.
My code so far looks as follows:
def elapsed(t):
t = raw_input('Enter time (hh:mm:ss): ')
th, tm, ts = t.split(':')
return int(ts) + int(tm) * 60 + int(th) * 3600
def mile(m):
m = raw_input('How many miles? ')
return int(m)
start = elapsed('start')
warmup = elapsed('warmup')
wmile = mile('wmile')
tempo = elapsed('tempo')
tmile = mile('tmile')
cooloff = elapsed('cooloff')
cmile = mile('cmile')
hour = (start + warmup * wmile + tempo * tmile + cooloff * cmile) // 3600
minute = (start + warmup * wmile + tempo * tmile + cooloff * cmile - hour * 3600) // 60
second = (start + warmup * wmile + tempo * tmile + cooloff * cmile - hour * 3600) % 60
print('Your run ended at %02d:%02d:%02d' % (hour, minute, second))
In this code, the time prompts are all the same: "Enter time (hh:mm:ss):" I want each prompt to refer to its variable name, e.g., "Enter start time (hh:mm:ss)" or "Enter time (hh:mm:ss): (warmup)". Is there a way to do this?
Note: While this may technically be a duplicate, I have examined the similar questions, but decided that both the questions and the answers provided were on the more unspecific side, and therefore decided to ask my question anyway.
Yes, use the input to your function elapsed(t).
Right now it's being overwritten with the return from raw_input()
def elapsed(t):
t1 = raw_input('Enter time (hh:mm:ss): ({0})'.format(t))
th, tm, ts = t1.split(':')
return int(ts) + int(tm) * 60 + int(th) * 3600
or
def elapsed(t):
t1 = raw_input('Enter time (hh:mm:ss): (%s)' % t))
th, tm, ts = t1.split(':')
return int(ts) + int(tm) * 60 + int(th) * 3600
def enter_time(specify_string):
print("Please enter the", specify_string, 'time in format hh:mm:ss > ', end='')
hh, mm, ss = input().split(':')
return (hh, mm, ss)
start_time = enter_time('start')
finish_time = enter_time('finish')
>>>Please enter the start time in format hh:mm:ss >13:32:34
>>>Please enter the finish time in format hh:mm:ss >12:21:21
>>>start_time
(13, 32, 34)
Now you can call the function with string arguments in the function call, and it will generalise the function for different requirements.
It is better to move the time between functions in a more readable format, such as a tuple. You can make more functions, eg:
- Test valid time entered
- Convert tuple to seconds for calculations
- Convert seconds back to tuple format
ect.
Let me know if I misunderstood you.

Dictionary query

Below is a function that extracts information from a database which holds information about events. Everything works except that when I try and iterate through times in rows in HTML it is apparently empty. I will therefore assume that rows.append(time) is not doing what it should be doing. I tried rows.append((time)) and that did not work either.
def extractor(n):
date = (datetime.datetime.now() + datetime.timedelta(days=n)).date()
rows = db.execute("SELECT * FROM events WHERE date LIKE :date ORDER BY date", date = str(date) + '%')
printed_day = date.strftime('%A') + ", " + date.strftime('%B') + " " + str(date.day) + ", " + str(datetime.datetime.now().year)
start_time = time.strftime("%H:%M:%S")
for row in rows:
date_split = str.split(row['date'])
just_time = date_split[1]
if just_time == '00:00:00':
just_time = 'All Day'
else:
just_time = just_time[0:5]
times.append((just_time))
rows.append(times)
results.append((rows, printed_day, start_time, times))
Solved it:
replace
times.append((just_time))
rows.append(times)
with
row['times'] = just_time

Categories