Lambda function acting very strange only when I call the Lex bot - python
I have an app with the following flow:
Placed a phone call or use the chat UI to invoke a Lex bot via Get Customer Input block in Amazon Connect
The Lex bot asks for some information from the customer such as Name, company you're calling from, who referred you, and the product you're calling aobut.
The Lex bot is based on the order flowers sample and invokes a Lambda function with the salesforce API imported as a layer. The purpose of the SalesForce layer is to check if the caller is an existing contact in SalesForce and to check if the company they are calling from exists or not. If neither is true, then the Lambda function creates new records in SalesForce.
Once the bot understands what the customer is calling about it then places an outbound call to the customer using the phone number in their contact record in SalesForce, unless they don't have one, at which point it asks for their phone number and then places an outbound call to the customer and connects to an agent.
Whenever I use the Chat UI for this flow it works perfectly every time with no issues. However, ever few phone call I place I get something very weird happening. I'm able to get the system to recognize and repeat my name, the company I'm calling from, and the company who referred me every time. But when it breaks, it breaks at the spot where it asks me for the product I'm calling about. I tell it "I'm calling about air filters" and the system says "Hi Hersal Thomas, can you tell me which company you're contacting us from?" and I speak "Facebook" and it understands me and goes to the same point to where it asks me which product I'm inquiring about and when I speak "air filters" it loops back to the previous step where it says "Hi Hersal Thomas, can you tell me which company you're contacting us from?" It does this three times and then eventually connects my call to an agent.
Could there be a weird loop in the Lambda function that is causing this behavior?
Here is the Python 3.6 function:
"""
This sample demonstrates an implementation of the Lex Code Hook Interface
in order to serve a sample bot which manages orders for flowers.
Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console
as part of the 'OrderFlowers' template.
For instructions on how to set up and test this bot, as well as additional samples,
visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html.
"""
import math
import dateutil.parser
import datetime
import calendar
import time
import os
import logging
import json
from salesforce_api import Salesforce
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
""" --- Helpers to build responses which match the structure of the necessary dialog actions --- """
def get_slots(intent_request):
return intent_request['currentIntent']['slots']
def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message):
return {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'ElicitSlot',
'intentName': intent_name,
'slots': slots,
'slotToElicit': slot_to_elicit,
'message': {
"contentType": "PlainText",
"content": message
}
}
}
def close(session_attributes, fulfillment_state, message):
response = {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Close',
'fulfillmentState': fulfillment_state,
'message': message
}
}
return response
def delegate(session_attributes, slots):
return {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Delegate',
'slots': slots
}
}
""" --- Helper Functions --- """
def parse_int(n):
try:
return int(n)
except ValueError:
return float('nan')
def build_validation_result(is_valid, violated_slot, message_content):
if message_content is None:
return {
"isValid": is_valid,
"violatedSlot": violated_slot,
}
return {
'isValid': is_valid,
'violatedSlot': violated_slot,
'message': {'contentType': 'PlainText', 'content': message_content}
}
def isvalid_date(date):
try:
dateutil.parser.parse(date)
return True
except ValueError:
return False
def validate_user_informations(full_name, company, refered_from, product):
flower_types = ['lilies', 'roses', 'tulips']
if flower_type is not None and flower_type.lower() not in flower_types:
return build_validation_result(False,
'FlowerType',
'We do not have {}, would you like a different type of flower? '
'Our most popular flowers are roses'.format(flower_type))
if date is not None:
if not isvalid_date(date):
return build_validation_result(False, 'PickupDate', 'I did not understand that, what date would you like to pick the flowers up?')
elif datetime.datetime.strptime(date, '%Y-%m-%d').date() <= datetime.date.today():
return build_validation_result(False, 'PickupDate', 'You can pick up the flowers from tomorrow onwards. What day would you like to pick them up?')
if pickup_time is not None:
if len(pickup_time) != 5:
# Not a valid time; use a prompt defined on the build-time model.
return build_validation_result(False, 'PickupTime', None)
hour, minute = pickup_time.split(':')
hour = parse_int(hour)
minute = parse_int(minute)
if math.isnan(hour) or math.isnan(minute):
# Not a valid time; use a prompt defined on the build-time model.
return build_validation_result(False, 'PickupTime', None)
if hour < 10 or hour > 16:
# Outside of business hours
return build_validation_result(False, 'PickupTime', 'Our business hours are from ten a m. to five p m. Can you specify a time during this range?')
return build_validation_result(True, None, None)
def add_months(sourcedate, months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month // 12
month = month % 12 + 1
day = min(sourcedate.day, calendar.monthrange(year,month)[1])
return datetime.date(year, month, day)
def convertNumberToE164(number):
number = number.replace(' ', '')
number = number.replace('+', '')
number = number.replace('(', '')
number = number.replace(')', '')
number = number.replace('-', '')
if len(number) == 10:
number = '+1{}'.format(number)
else:
number = '+{}'.format(number)
return number
""" --- Functions that control the bot's behavior --- """
def get_customer_information(intent_request):
"""
Performs dialog management and fulfillment for ordering flowers.
Beyond fulfillment, the implementation of this intent demonstrates the use of the elicitSlot dialog action
in slot validation and re-prompting.
"""
logger.debug("event: ==================")
logger.debug(json.dumps(intent_request))
full_name = get_slots(intent_request)["full_name"]
company = get_slots(intent_request)["company"]
refered_from = get_slots(intent_request)["refered_from"]
product = get_slots(intent_request)["product"]
phone_number = get_slots(intent_request)["phone_number"]
agree_phone_call = get_slots(intent_request)["agree_phone_call"]
source = intent_request['invocationSource']
if source == 'DialogCodeHook':
# Perform basic validation on the supplied input slots.
# Use the elicitSlot dialog action to re-prompt for the first violation detected.
slots = get_slots(intent_request)
output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
# validation_result = validate_user_informations(full_name, company, refered_from, product)
# if not validation_result['isValid']:
# slots[validation_result['violatedSlot']] = None
# return elicit_slot(intent_request['sessionAttributes'],
# intent_request['currentIntent']['name'],
# slots,
# validation_result['violatedSlot'],
# validation_result['message'])
if full_name is not None and company is not None and refered_from is not None and product is not None:
if intent_request['currentIntent']['name'] == 'VoiceOmniIntent' and ('connect_channel' in output_session_attributes and output_session_attributes['connect_channel'] is not None and output_session_attributes['connect_channel'] == "VOICE"):
#if incoming from Voice
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
account_id = -1
if len(accounts) > 0:
account_id = accounts[0]['Id']
else:
acc_info = client.sobjects.Account.insert({'name': company})
account_id = acc_info['id']
full_name = full_name.title()
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, account_id))
if len(contacts) > 0:
client.sobjects.Contact.update(contacts[0]['Id'], {'phone': convertNumberToE164(output_session_attributes['phone_number'])})
output_session_attributes['contact_id'] = contacts[0]['Id']
else:
name_arr = full_name.split(' ')
first_name = name_arr[0] if len(name_arr) > 1 else ''
last_name = name_arr[0] if len(name_arr) == 1 else name_arr[1]
contact_res = client.sobjects.Contact.insert({'firstname': first_name, 'lastname': last_name, 'phone': convertNumberToE164(output_session_attributes['phone_number']), 'accountid': account_id})
output_session_attributes['contact_id'] = contact_res['id']
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': account_id})
return delegate(output_session_attributes, get_slots(intent_request))
else:
#if incoming from Chat
if phone_number is not None:
#once customer fills his phone_number
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
if len(accounts) > 0:
account_id = accounts[0]['Id']
full_name = full_name.title()
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, account_id))
if len(contacts) > 0:
client.sobjects.Contact.update(contacts[0]['Id'], {'phone': convertNumberToE164(phone_number)})
output_session_attributes['contact_id'] = contacts[0]['Id']
else:
name_arr = full_name.split(' ')
first_name = name_arr[0] if len(name_arr) > 1 else ''
last_name = name_arr[0] if len(name_arr) == 1 else name_arr[1]
contact_res = client.sobjects.Contact.insert({'firstname': first_name, 'lastname': last_name, 'phone': convertNumberToE164(phone_number), 'accountid': account_id})
output_session_attributes['contact_id'] = contact_res['id']
output_session_attributes['phone_number'] = convertNumberToE164(phone_number)
return delegate(output_session_attributes, get_slots(intent_request))
elif agree_phone_call is not None:
#once his company and phone_number are exist
if agree_phone_call.lower() == 'yes':
#if he agreed to phone call to his number
phone_number = convertNumberToE164(output_session_attributes['phone_number']) if ('phone_number' in output_session_attributes and output_session_attributes['phone_number'] is not None) else ''
return delegate(output_session_attributes, get_slots(intent_request))
else:
#asking his phone number
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
else:
#once customer fills full_name, company, refered_from, product
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
if len(accounts) > 0:
inserted_id = accounts[0]['Id']
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, inserted_id))
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': inserted_id})
if len(contacts) > 0 and contacts[0]['Phone'] is not None:
output_session_attributes['phone_number'] = convertNumberToE164(contacts[0]['Phone'])
output_session_attributes['contact_id'] = contacts[0]['Id']
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"agree_phone_call",
"I see that you’re a customer of ACME Manufacturing. Can we call you at {}? (Yes/No)".format(convertNumberToE164(contacts[0]['Phone'])))
logger.debug("{}\'s phone number is {}".format(full_name, convertNumberToE164(contacts[0]['phone'])))
else:
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
else:
acc_info = client.sobjects.Account.insert({'name': company})
inserted_id = acc_info['id']
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
logger.debug(close_date)
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': inserted_id})
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
# Pass the price of the flowers back through session attributes to be used in various prompts defined
# on the bot model.
# if flower_type is not None:
# output_session_attributes['Price'] = len(flower_type) * 5 # Elegant pricing model
return delegate(output_session_attributes, get_slots(intent_request))
# Order the flowers, and rely on the goodbye message of the bot to define the message to the end user.
# In a real bot, this would likely involve a call to a backend service.
output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
if intent_request['currentIntent']['name'] == 'VoiceOmniIntent' and ('connect_channel' in output_session_attributes and output_session_attributes['connect_channel'] is not None and output_session_attributes['connect_channel'] == "VOICE"):
output_session_attributes['full_name'] = full_name.title()
output_session_attributes['company'] = company
output_session_attributes['refered_from'] = refered_from
output_session_attributes['product'] = product
return close(output_session_attributes,
'Fulfilled',
{'contentType': 'PlainText',
'content': 'Thanks {}, we will connect you with our agent now.'.format(full_name)})
else:
output_session_attributes['full_name'] = full_name
output_session_attributes['company'] = company
output_session_attributes['refered_from'] = refered_from
output_session_attributes['product'] = product
output_session_attributes['phone_number'] = convertNumberToE164(phone_number)
return close(output_session_attributes,
'Fulfilled',
{'contentType': 'PlainText',
'content': 'Okay, our agent will call you shortly. Thanks.'})
""" --- Intents --- """
def dispatch(intent_request):
"""
Called when the user specifies an intent for this bot.
"""
logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name']))
intent_name = intent_request['currentIntent']['name']
# Dispatch to your bot's intent handlers
if intent_name == 'VoiceOmniIntent' or intent_name == 'ChatOmniIntent':
return get_customer_information(intent_request)
raise Exception('Intent with name ' + intent_name + ' not supported')
""" --- Main handler --- """
def lambda_handler(event, context):
"""
Route the incoming request based on intent.
The JSON body of the request is provided in the event slot.
"""
# By default, treat the user request as coming from the America/New_York time zone.
os.environ['TZ'] = 'America/New_York'
time.tzset()
logger.debug(json.dumps(event))
logger.debug('event.bot.name={}'.format(event['bot']['name']))
# return event
return dispatch(event)
Related
Staying login problem about CallbackURL after payment
my view is like : def get_user_pending_order(request): user_profile = get_object_or_404(Profile, user=request.user) order = Order.objects.filter(owner=user_profile, is_ordered=False) if order.exists(): return order[0] return 0 MERCHANT = 'xxx...xxx' ZP_API_REQUEST = "https://api.zarinpal.com/pg/v4/payment/request.json" ZP_API_VERIFY = "https://api.zarinpal.com/pg/v4/payment/verify.json" ZP_API_STARTPAY = "https://www.zarinpal.com/pg/StartPay/{authority}" amount = '' description = "text" # Required email = 'example#email.com' # Optional mobile = '09999999999' # Optional # Important: need to edit for realy server. CallbackURL = 'https://example.com/payment/verify/' def send_request(request): print(get_user_pending_order(request).owner.phone_number) req_data = { "merchant_id": MERCHANT, "amount": int(get_user_pending_order(request).get_total()), "callback_url": CallbackURL, "description": description, "metadata": {"mobile": mobile, "email": email} } req_header = {"accept": "application/json", "content-type": "application/json'"} req = requests.post(url=ZP_API_REQUEST, data=json.dumps( req_data), headers=req_header) authority = req.json()['data']['authority'] if len(req.json()['errors']) == 0: return redirect(ZP_API_STARTPAY.format(authority=authority)) else: e_code = req.json()['errors']['code'] e_message = req.json()['errors']['message'] return HttpResponse(f"Error code: {e_code}, Error Message: {e_message}") def verify(request): t_status = request.GET.get('Status') t_authority = request.GET['Authority'] if request.GET.get('Status') == 'OK': req_header = {"accept": "application/json", "content-type": "application/json'"} req_data = { "merchant_id": MERCHANT, "amount": int(get_user_pending_order(request).get_total()), "authority": t_authority } req = requests.post(url=ZP_API_VERIFY, data=json.dumps(req_data), headers=req_header) if len(req.json()['errors']) == 0: t_status = req.json()['data']['code'] if t_status == 100: user = request.user order_to_purchase = get_user_pending_order(request) order_to_purchase.is_ordered = True order_to_purchase.date_ordered=datetime.datetime.now() order_to_purchase.created_on_time=datetime.datetime.now() order_to_purchase.save() order_items = order_to_purchase.items.all() for order_item in order_items: order_item.product.quantity = order_item.product.quantity - 1 order_item.product.save() order_items.update(is_ordered=True, date_ordered=datetime.datetime.now()) subject = 'successful' c = { "refid":str(req.json()['data']['ref_id']), "ref_code":order_to_purchase.ref_code, "owner":order_to_purchase.owner, } email_template_name = "pay/after_pay_confirm_email.html" email_html = render_to_string(email_template_name, c) email_from = settings.EMAIL_HOST_USER send_mail(subject, email_html, email_from, [user.email], html_message=email_html) ctx = {'message_good':'good'} return render(request, 'pay/verify.html', ctx) elif t_status == 101: ... else: .... else: ... else: ... At first about user, is logged. and about send_request function it work totally fine...so it pass user into Payment gateway and after successful payment it come back to verify function by CallbackURL. to show success page and do order_to_purchase.is_ordered = True ... for me with my pc, phone, other android phones, ios, windows, linux. and about browsers like chrome Firefox it work correctly and everything is fine. but some clients tell me they face to 'AnonymousUser' object is not iterable after successful payment and when they back to verify. its kinda like that they logged out by pushing request to payment gateway. also i made purchase by that account exactly same way and i didn't face to that error. it show is that phone or browser problem that half of my clients faced to that. i have no idea what should i do!!!
Django Access Token Matching Query Does Not Exist
I have the following code I am trying to test: def customer_add_order(request): """ params: access_token restaurant_id address order_details(json format), example: [{"meal_id": 1, "quantity":2}, {"meal_id": 2, "quantity":3}] stripe_token return: {"status": "success"} """ if request.method == "POST": #Get token access_token = AccessToken.objects.get(token = request.POST.get("access_token"), expires__gt = timezone.now()) #Get profile customer = access_token.user.customer # Check if customer has a order that is not delivered if Order.objects.filter(customer = customer).exclude(status = Order.DELIVERED): return JsonResponse({"status": "fail", "error": "Your Last Order must be completed"}) # Check Address if not request.POST("address"): return JsonResponse({"status": "failed", "error": "Address is required."}) # Ger Order Details order_details = json.load(request.POST["order_details"]) order_total = 0 for meal in order_details: order_total += Meal.objects.get(id = meal["meal_id"]).price * meal[quantity] if len(order_details)>0: # Step 1 - Create an Order order = Order.objects.create( customer = customer, restaurant_id = request.POST["restaurant_id"], total = order_total, status = Order.PENDING, address = request.POST["address"] ) # Step 2 - Create Order details for meal in order_details: OrderDetails.objects.create( order = order, meal_id = meal["meal_id"], quantity = meal["quantity"], sub_total = Meal.objects.get(id = meal["meal_id"]).price * meal["quantity"] ) return JsonResponse({"status": "success"}) I enter the params in Postman, and use an access token that shows valid in django, and it hasn't expired. I am using the rest framework and the function is for API. I use the following function for creating Access Token: def create_user_by_type(backend, user, response, *args, **kwargs): request = backend.strategy.request_data() if backend.name == 'facebook': avatar = 'https://graph.facebook.com/%s/picture?type=large' % response['id'] if request.get("user_type") == "driver" and not Driver.objects.filter(user_id=user.id): Driver.objects.create(user_id=user.id, avatar = avatar) elif not Customer.objects.filter(user_id=user.id): Customer.objects.create(user_id=user.id, avatar = avatar) Also, the line if request.get("user_type") == "driver" and not Driver.objects.filter(user_id=user.id): previously had an error because I had it in an outdated format request["user_type"]. Not sure if this is correct syntax for what I want to do, but I can create Access Tokens through Postman.
The issue was I was using the params in Postman to enter the Access Token and other information, instead it should in in 'body' with form-data selected.
How to query the balance of a TRC20 token for a given TRX address?
I'd like to get the balance of a TRC20 token (in this case the WIN token) for a Tron wallet address that owns WIN tokens. I'm using the Python module tron-api-python and based on what i've read on GitHub and the docs the code for that should look something like this: from tronapi import Tron # Source for ABI: https://tronscan.org/#/token20/TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7/code contract_abi = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]' tron = Tron() contract = tron.trx.contract("TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7", abi=contract_abi) balance = contract.functions.balanceOf("TXRZqGMEXsGTX6AQtcSgYknos93hqw18P7") print(balance) But the result i get is: eth_abi.exceptions.NoEntriesFound: No matching entries for 'address' in encoder registry
You can use this API: import requests import json def get_balance(address, token_symbol): url = "https://apilist.tronscan.org/api/account" payload = { "address": address, } res = requests.get(url, params=payload) trc20token_balances = json.loads(res.text)["trc20token_balances"] token_balance = next((item for item in trc20token_balances if item["symbol"] == token_symbol), None) if token_balance == None: return 0 else: return int(token_balance["balance"]) The previous response broadcasts a transaction to read a constant function; you don't need to do that if you're only going to read the balance.
Found it myself. This is not the code to get the balance but to send the WIN token so for this to return the balance the function_selector and the parameters would need to change but the rest should be fine since both is based on triggering a smart contract. tron_kwargs = dict() tron_kwargs["private_key"] = your_privkey tron_kwargs["default_address"] = your_base58_address tron = Tron(**tron_kwargs) kwargs = dict() kwargs["contract_address"] = tron.address.to_hex(wink_base58_contract_address) kwargs["function_selector"] = "transfer(address,uint256)" kwargs["fee_limit"] = 100000 kwargs["call_value"] = 0 kwargs["parameters"] = [ { 'type': 'address', 'value': tron.address.to_hex(recipients_base58_address) }, { 'type': 'uint256', 'value': 8000000 } ] raw_tx = tron.transaction_builder.trigger_smart_contract(**kwargs) sign = tron.trx.sign(raw_tx["transaction"]) result = tron.trx.broadcast(sign)
Python output RETURN not working in an Api key sms script
I'm trying to make a python script that returns an account information from API Key The website : pvasms.com Tutorial in pvasms.com : http://smspva.com/new_theme_api.html I've found 2 scripts already on github : https://github.com/ooojustin/smspva/blob/master/smspva/smsrequest.py https://github.com/alihossein/smspva/blob/master/SmsPva.py I've tried both of them, i've replaced value with my Api Key, when i run : 0 Error but it didn't return anything import requests class SmsPva: def __init__(self): self._url = 'http://smspva.com/priemnik.php' self._api_key = 'myapikey' self._method_type = 'get' self._query_string = {} def get_number(self, id=1, country='ru', service='opt29'): """ Request for receiving a phone number for a certain service :return: """ self._query_string = {'metod': 'get_number', 'country': country, 'service': service, 'id': id, 'apikey': self._api_key} result = self.__make_request() return result def get_sms(self, id, country='ru', service='opt29'): """ Receiving a SMS for a certain service :return: """ self._query_string = {'metod': 'get_sms', 'country': country, 'service': service, 'id': id, 'apikey': self._api_key} result = self.__make_request() return result def get_balance(self, service='opt29'): """ User's balance request :param service: :return: """ self._query_string = {'metod': 'get_balance', 'service': service, 'apikey': self._api_key} result = self.__make_request() return result def get_userinfo(self, service='opt29'): """ User's balance request and karma (Your rating) :return: """ self._query_string = {'metod': 'get_userinfo', 'service': service, 'apikey': self._api_key} result = self.__make_request() return result def get_count_new(self, service='opt29', country='ru'): """ Request for the amount of free activations for a certain service :param country: :param service: :return: """ self.query_string = {'metod': 'get_count_new', 'service': service, 'country': country, 'apikey': self._api_key} result = self.__make_request() return result def denial(self, id, country='ru', service='opt29'): """ Cancel the order to number you got :return: """ self._query_string = {'metod': 'denial', 'country': country, 'service': service, 'id': id, 'apikey': self._api_key} result = self.__make_request() return result def __make_request(self): """ make request post or get , ... :return: """ try: if self._method_type == 'get': response = requests.get(self._url, self._query_string) elif self._method_type == 'post': pass if response.status_code == 200: return response.json() else: return response except Exception as e: return e
You should first change all country and service parts in code to what you want and then look at the methods in the class (like get_number) and the comments below them and see which one do you want to use. when you did these two steps write this underneath the code (without any indentations) request = SmsPva request.get_number() # change get_number with any other methods in the class that you want # you can do the last line over and over with other methods and then you can get the output by using print function like this: print(request.get_number()) and finally I recommend learning python in the future ;)
My react-native application can not fire PUT and POST http requests to my RESTful api made from web2py
my react-native application can not fire an http PUT and POST request, it GET but for PUT it can not here is my RESTful API built using a web2py. the API works because when i use curl, all the requests are fired correctly. Here is the RESTful API #request.restful() def api(): response.view = 'generic.'+request.extension def GET(*args,**vars): patterns = [ "/trip[trip]", # endpoint to get all client trips "/trip/{trip.id}", # endpoint to get trip details by id "/self[self_driver_trip]", # endpoint to get all self trips "/self/{self_driver_trip.id}", # endpoint to get a particular self trip "/driver-trip[driver_trip]", # endpoint to get all client trips "/driver-trip/{driver_trip.id}", # endpoint to get a particular client trip "/indi-trip[individual_trip]", # endpoint to get all trips "/indi-trip/{individual_trip.id}", # endpoint to get an individual trip "/get_companies[company]", # endpoint to get all companies "/company/{company.id}", # endpoint to get company details "/driver[driver]", # endpoint to get all drivers "/driver/{driver.id}", # endpoint to get driver details "/get_vehicles[vehicle]", # endpoint to get all vehicles "/vehicle/{vehicle.id}" # endpoint to get vehicle details ] parser = db.parse_as_rest(patterns, args, vars) if parser.status == 200: print(response.json(parser.response)) return response.json(parser.response) else: raise HTTP(parser.status, parser.error) def POST(pattern, **vars): if pattern == 'self': # Add a new self trip print("self") return dict(db.self_driver_trip.validate_and_insert(**vars)) elif pattern == 'driver-trip': # Add a new driver trip print('driver_trip') return dict(db.driver_trip.validate_and_insert(**vars)) elif pattern == 'trip': # Add new a trip print('we are here') return response.json(dict(db.trip.validate_and_insert(**vars))) elif pattern == 'indi-trip': # Add a new individual trip print('indi-trip') return dict(db.individual_trip.validate_and_insert(**vars)) elif pattern == 'company': # Add a new company print('company') return dict(db.company.validate_and_insert(**vars)) elif pattern == 'driver': # Add a new driver print('driver') return dict(db.driver.validate_and_insert(**vars)) elif pattern == 'vehicle': # Add a new vehicle print('vehicle') return dict(db.vehicle.validate_and_insert(**vars)) elif pattern == 'self_validate': # Validate a self user by phone number phone = request.vars.phone license_number = request.vars.license_number vehicle_id = request.vars.vehicle_id trip = db((db.self_driver_trip.phone == phone) & (db.self_driver_trip.license_number == license_number) &(db.self_driver_trip.vehicle_id == vehicle_id)).select().first() if trip is None: return response.json(dict(message= 'SELF_NOT_EXIST')), 400 elif trip.status != 'In Progress': return response.json(dict(message='SELF_COMPLETED')), 400 else: return response.json(trip), 200 elif pattern == 'company_validate': # validate a company(check if it exists) company = request.vars.company comp = db(db.company.name==company).select().first() if comp is None: return response.json(dict(message= 'Invalid Company Name')), 400 else: print('company validated') return response.json(dict(message='Success', comp_id= comp.id)), 200 elif pattern == 'driver_validate': # validate driver (check if record exists) company_id = request.vars.company_id print(company_id) password = request.vars.password print(password) driver = db((db.driver.company_id == company_id)&(db.driver.password==password)).select().first() if driver is None: return response.json(dict(message='Sorry, the credentials you entered are not valid')), 400 elif driver.status != "Available": current_trip = driver.current_trip print(current_trip) current_trip_type = driver.current_trip_type print(current_trip_type) return response.json(dict(message='DRIVER_UNAVAILABLE',current_trip=current_trip, current_trip_type=current_trip_type)) else: return response.json(dict(message='Welcome to Mercantile', driver_id=driver.id, company_id=driver.company_id)) elif pattern == 'vehicle_validate': # validate vehicle vehicle_id = request.vars.vehicle_id current_mileage = request.vars.current_mileage vehicle = db(db.vehicle.id == vehicle_id).select().first() if vehicle is None: return response.json(dict(message='Sorry, the car information you entered is not valid')), 400 elif vehicle.status != 'Available': return response.json(dict(message='Sorry, car is already in use')), 400 elif current_mileage < int(vehicle.current_mileage): return response.json(dict(message='MILEAGE_LOWER')), 400 elif (current_mileage - int(vehicle.current_mileage)) > 7: return response.json(dict(message='MILEAGE_GREATER')), 400 else: return response.json(dict( message= 'Vehicle Valid', vehicle_id= vehicle.vehicle_id, current_mileage= vehicle.current_mileage )), 200 else: raise HTTP(400) def PUT(pattern, record_id, **vars): if pattern == 'vehicle_mileage_update': vehicle = db(db.vehicle.id == record_id).select().first() current_mileage = request.vars.current_mileage db_mileage = int(vehicle.current_mileage) # TRIP LIMIT if (current_mileage - db_mileage) > 500: return response.json(dict(message='MILEAGE_OVERLOAD')), 400 elif current_mileage < db_mileage: return response.json(dict(message='MILEAGE_UNDERLOAD')), 400 else: return db(db.vehicle.id == record_id).update(**vars), 200 else: print("reached here in PUT") db(db[pattern].id == record_id).update(**vars) def DELETE(table_name, record_id): return db(db[table_name].id==record_id).delete() return dict(GET=GET, POST=POST, PUT=PUT, DELETE=DELETE) And now this is my code snippet from my react-native application that has to make an http PUT request to update the table called trip let response = await fetch( API_URL+'/trip', { method: 'POST', body: JSON.stringify({ driver_id: this.props.navigation.state.params.driver_id, start_mileage: parseInt(this.state.start_mileage), client: this.state.client, comp_id: this.state.comp_id, vehicle_id: this.state.vehicle_id, start_date: new Date().toLocaleString(), departure: this.state.departure, trip_type: this.state.trip_type, departure_geo_lat: this.state.dep_latitude, departure_geo_long: this.state.dep_longitude }), headers: { 'Content-Type': 'application/json' } } ) and the PUT request let response = await fetch( API_URL+'/driver/'+this.state.driver_id, { method: "PUT", body: JSON.stringify({ status: "On a Trip", current_trip_type: "Client", current_trip: responseJson.id }), headers: { 'Content-Type': 'application/json' } } ) NOTE: this works when i use a flask rest api but, i wanted to build the backend using web2py so i decided to make the RESTful api within web2py even for my android app to use. Why can't this work with web2py