Using telebot register_next_step_handler structure I get error with mixed users' data - telegram-bot

I want to get user's nickname and after that to get user's screenshot. Than all the data will be send to Google Sheet. But I have the problem. When multiple users(at least 2) are using bot at the same time, their data are mixed up. For example first user's nickname is second user's nickname or first user's id is second user's id. Can I make a unique user session to store data in unique user class. It means for each user it will be created their own user class. Here is the code:
#bot.message_handler(commands=['start'])
def send_hello(message):
bot.send_message(message.chat.id, "Hi! Let`s start verification.")
msg = bot.send_message(message.chat.id, "Enter your nickname:")
bot.register_next_step_handler(msg, process_nickname)
def process_nickname(message):
user.name=message.text
user.id=message.from_user.id
msg = bot.send_message(message.chat.id, 'Super! Now send screenshot:')
bot.register_next_step_handler(msg, process_screenshot)
def process_screenshot(message):
fileID = message.photo[-1].file_id
file = bot.get_file(fileID)
file_path=file.file_path
metadata = {
'name': user.name,
'parents':[folder_id]
}
url=(f"https://api.telegram.org/file/bot{token}/{file_path}")
response = requests.get(url)
image_data = BytesIO(response.content)
media=MediaIoBaseUpload(image_data, 'image/jpeg')
serviceDrive.files().create(body=metadata,media_body=media,fields='id').execute()

Related

Shopify Multipass created_at Field

I am currently trying to implement a login to Shopify over the Storefront API via Multipass.
However, what it isn't clear to me from the Documentation on that Page, how the "created_at" Field is used. Since it states that this field should be filled with the current timestamp.
But what if the same users logs in a second time via Multipass, should it be filled with the timestamp of the second login.
Or should the original Multipass token be stored somewhere, and reused at a second login, instead of generating a new one?
Yes you need to set it always to the current time. I guess it stands for "token created at".
This is the code I use in Python:
class Multipass:
def __init__(self, secret):
key = SHA256.new(secret.encode('utf-8')).digest()
self.encryptionKey = key[0:16]
self.signatureKey = key[16:32]
def generate_token(self, customer_data_hash):
customer_data_hash['created_at'] = datetime.datetime.utcnow().isoformat()
cipher_text = self.encrypt(json.dumps(customer_data_hash))
return urlsafe_b64encode(cipher_text + self.sign(cipher_text))
def generate_url(self, customer_data_hash, url):
token = self.generate_token(customer_data_hash).decode('utf-8')
return '{0}/account/login/multipass/{1}'.format(url, token)
def encrypt(self, plain_text):
plain_text = self.pad(plain_text)
iv = get_random_bytes(AES.block_size)
cipher = AES.new(self.encryptionKey, AES.MODE_CBC, iv)
return iv + cipher.encrypt(plain_text.encode('utf-8'))
def sign(self, secret):
return HMAC.new(self.signatureKey, secret, SHA256).digest()
#staticmethod
def pad(s):
return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)
And so
...
customer_object = {
**user,# customer data
"verified_email": True
}
multipass = Multipass(multipass_secret)
return multipass.generate_url(customer_object, environment["url"])
How can someone login a second time? If they are already logged in, they would not essentially be able to re-login without logging out. If they logged out, the multi-pass would assign a new timestamp. When would this flow occur of a user logging in a second time and not being issued a brand new login? How would they do this?

Django how to maintain a session?

I'm developing an e-commerce site and I'm working on the shopping cart functionality. When the user is not connected I create a session for him so that he can add products to the basket which is normal, when the user decides to place this order I ask him to connect but when he connects he loses the session that I had created for him and another session is assigned to him. The cause is that once connected it loses all its products selected in the screen. After reading the documentation on django sessions I found nothing that could help me.
here is my code for more details:
models.py
class Cart(models.Model):
session_id = models.CharField(max_length=150)
product = models.ForeignKey(Products, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=0, validators=[MinValueValidator(1)])
updated = models.fields.DateTimeField(auto_now=True)
created = models.fields.DateTimeField(auto_now_add=True)
deleted = models.fields.BooleanField(default=False)
def __str__(self) -> str:
return str(self.product)
views.py
class FrontProductAddCart(View):
def post(self, request, product_pk):
session_id = request.session._get_or_create_session_key()
product = models.Products.objects.get(pk=product_pk)
objet, create = models.Cart.objects.get_or_create(session_id=session_id, product=product)
quantity = request.POST.get("quantity")
if quantity:
objet.quantity = quantity
objet.save()
else:
objet.quantity += 1
objet.save()
return HttpResponse(
"",
headers={
"HX-Trigger": json.dumps({
"product_add_cart": context_processors.get_total_number_products(request)
})
}
)

Telegram bot: How to get chosen inline result

I'm sending InlineQueryResultArticle to clients and i'm wondering how to get chosen result and it's data (like result_id,...).
here is the code to send results:
token = 'Bot token'
bot = telegram.Bot(token)
updater = Updater(token)
dispatcher = updater.dispatcher
def get_inline_results(bot, update):
query = update.inline_query.query
results = list()
results.append(InlineQueryResultArticle(id='1000',
title="Book 1",
description='Description of this book, author ...',
thumb_url='https://fakeimg.pl/100/?text=book%201',
input_message_content=InputTextMessageContent(
'chosen book:')))
results.append(InlineQueryResultArticle(id='1001',
title="Book 2",
description='Description of the book, author...',
thumb_url='https://fakeimg.pl/300/?text=book%202',
input_message_content=InputTextMessageContent(
'chosen book:')
))
update.inline_query.answer(results)
inline_query_handler = InlineQueryHandler(get_inline_results)
dispatcher.add_handler(inline_query_handler)
I'm looking for a method like on_inline_chosen(data) to get id of the chosen item. (1000 or 1001 for snippet above) and then send the appropriate response to user.
You should set /setinlinefeedback in #BotFather, then you will get this update
OK, i got my answer from here
Handling user chosen result:
from telegram.ext import ChosenInlineResultHandler
def on_result_chosen(bot, update):
print(update.to_dict())
result = update.chosen_inline_result
result_id = result.result_id
query = result.query
user = result.from_user.id
print(result_id)
print(user)
print(query)
print(result.inline_message_id)
bot.send_message(user, text='fetching book data with id:' + result_id)
result_chosen_handler = ChosenInlineResultHandler(on_result_chosen)
dispatcher.add_handler(result_chosen_handler)

Retrieving more than (~3000) tweets per userId from twitter API.

I am new in twitter development. I am trying to download tweets of important news agency. I used the guidelines provided in http://www.karambelkar.info/2015/01/how-to-use-twitters-search-rest-api-most-effectively. to download the tweets. I know that twitter api has some limitations on the number of requests (180 req per 15 min) and each request can fetch at most 100 tweets. So I expect the following code to get 18K tweets when I run it for the first time. However, I can only get arround 3000 tweets for each news agency. For example nytimes 3234 tweets, cnn 3207.
I'll be thankful if you can take a look at my code and let me know the problem.
def get_tweets(api, username, sinceId):
max_id = -1L
maxTweets = 1000000 # Some arbitrary large number
tweetsPerReq = 100 # the max the API permits
tweetCount = 0
print "writing to {0}_tweets.txt".format(username)
with open("{0}_tweets.txt".format(username) , 'w') as f:
while tweetCount < maxTweets:
try:
if (max_id <= 0):
if (not sinceId):
new_tweets = api.user_timeline(screen_name = username, count= tweetsPerReq)
else:
new_tweets = api.user_timeline(screen_name = username, count= tweetsPerReq, since_id = sinceId)
else:
if (not sinceId):
new_tweets = api.user_timeline(screen_name = username, count= tweetsPerReq, max_id=str(max_id - 1))
else:
new_tweets = api.search(screen_name = username, count= tweetsPerReq, max_id=str(max_id - 1), since_id=sinceId)
if not new_tweets:
print "no new tweet"
break
#create array of tweet information: username, tweet id, date/time, text
for tweet in new_tweets:
f.write(jsonpickle.encode(tweet._json, unpicklable=False) +'\n')
tweetCount += len(new_tweets)
print("Downloaded {0} tweets".format(tweetCount))
max_id = new_tweets[-1].id
except tweepy.TweepError as e:
# Just exit if any error
print("some error : " + str(e))
break
print ("Downloaded {0} tweets, Saved to {1}_tweets.txt".format(tweetCount, username))
Those are the limitations imposed by the API.
If you read the documentation, you will see that it says
This method can only return up to 3,200 of a user’s most recent Tweets.
So, the answer is - normal API users cannot access that data.

Obj C - I can't find the user location via the Facebook Graph API

I'm building a iOS app with a Facebook login via the Facebook Graph API. So far the login works perfectly and I receive the users profile. I'm trying to display the location (place of residence, not his current location) of the user but can't seem to find it in the user data I get when the user is logging in.
This is the JSON I receive:
{
email = "";
"favorite_athletes" = (
{
id = 308994352528078;
name = "Belgian Falcon F16 Racing Team";
}
);
"first_name" = Bastiaan;
gender = male;
id = 10153090459134040;
"last_name" = Andriessen;
link = "https://www.facebook.com/app_scoped_user_id/10153090459134040/";
locale = "en_US";
name = "Bastiaan Andriessen";
timezone = 1;
"updated_time" = "2014-11-28T13:10:46+0000";
verified = 1;
}
The Facebook Docs says it does send the location with the profile but I as you can see I don't find it in the JSON:
https://developers.facebook.com/docs/reference/ios/current/protocol/FBGraphUser/
Does someone know how I could solve this?