Telegram bot with aws lambda and API gateway - json

I am developing a telegram bot with python (telebot) , aws lambda and api gateway.
I have a problem in the lambda function and I can't understand why I have this kind of problem.
My lambda is this:
import telebot
import datetime
TOKEN = 'xxx'
def lambda_handler(event, context):
bot = telebot.TeleBot(TOKEN)
# Extract the message key over payload's body
message = json.loads(event['body'])
print(message)
# Split between three variables bellow
chat_id = message['chat']['id'] # Chat ID will guide your chatbot reply
sender = message['from']['first_name'] # Sender's first name, registered by user's telegram app
text = message['text'] # The message content
if text.lower().strip() == "/time":
current_time = datetime.strftime(datetime.now(), "%H:%M:%S")
bot.send_message(chat_id, "Right now its {} UTC.".format(current_time))
else:
pass
The error I get, running the test is this:
Response
{
"errorMessage": "'body'",
"errorType": "KeyError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 10, in lambda_handler\n message = json.loads(event['body'])\n"
]
}
The given json file:
{
"update_id": 0000000,
"message": {
"message_id": 000000,
"from": {
"id": 00000000,
"is_bot": false,
"first_name": "myname",
"last_name": "mysurname",
"username": "sursurname",
"language_code": "it"
},
"chat": {
"id": 000000,
"first_name": "myname",
"last_name": "mysurname",
"username": "sursurname",
"type": "private"
},
"date": 1654697178,
"forward_from": {
"id": 00000000,
"is_bot": false,
"first_name": "mysurname",
"last_name": "mysurname",
"username": "sursurname",
"language_code": "it"
},
"forward_date": 0000000000,
"text": "ciao"
}
}
I cannot understand why it is not able to read the body in any way, maybe I am in the wrong library? Do you have any suggestions to help me with this?

event['body'] is almost definitely not the correct key to access data passed through an event. The event passes information in a nested dictionary and you'll need to figure out how to drill down to the correct key.

I solved it by doing this:
json_str = json.dumps(event)
resp = json.loads(json_str)
chat_id = resp['message']['chat']['id']
message_text = resp['message']['text']
message_chat_id = resp['message']['chat']['id']
message_username = resp['message']['from']['first_name']
bot = telebot.TeleBot(TOKEN)
bot.send_message(chat_id, "Hey, I understood this message!, hi {}".format(message_username))

Related

json file into lua table

How is it possible to get the input of an json file:
{ "name": "John",
"work": "chef",
"age": "29",
"messages": [
{
"msg_name": "Hello",
"msg": "how_are_you"
},
{ "second_msg_name": "hi",
"msg": "fine"
}
]
}
into a Lua table? All json.lua scripts I found did not work for JSON with new lines. Does someone know a solution?
So piglets solution works for the string in the same script.
But how does it work with a JSON file?
local json = require("dkjson")
local file = io.open("C:\\Users\\...\\Documents\\Lua_Plugins\\test_file_reader\\test.json", "r")
local myTable = json.decode(file)
print(myTable)
Here then comes the error "bad argument #1 to 'strfind' (string expected, got FILE*)" on. Does someone see my fault?
local json = require("dkjson")
local yourString = [[{ "name": "John",
"work": "chef",
"age": "29",
"messages": [
{
"msg_name": "Hello",
"msg": "how_are_you"
},
{ "second_msg_name": "hi",
"msg": "fine"
}
]
}]]
local myTable = json.decode(yourString)
http://dkolf.de/src/dkjson-lua.fsl/home
I found the solution:
local json = require("dkjson")
local file = io.open("C:\\Users\\...\\Documents\\Lua_Plugins\\test_file_reader\\test.json", "r")
local content = file:read "*a"
file:close()
local myTable = json.decode(content)

Terraform HTTP Request body manipulation

I am using the data source http to perform GET requests on the FreshService API in Terraform
My code is as follows:
# Query FreshService
data "http" "example" {
url = ".../api/v2/changes/7195/tasks"
# Optional request headers
request_headers = {
Accept = "application/json"
Authorization = "XXXXXXXX"
}
}
output "freshservice_task_title" {
# Gets the root block volume id
value = "Targeting Volume ID: ${jsonencode(data.http.example.body)}"
}
The output is returning something like this:
{
"tasks": [
{
"id": XXXX,
"agent_id": XXXX,
"status": 3,
"due_date": "2021-04-07T09:30:00Z",
"notify_before": 0,
"title": "XXXXX",
"description": "",
"created_at": "2021-03-31T12:28:43Z",
"updated_at": "2021-04-07T12:43:55Z",
"closed_at": "2021-04-07T12:43:55Z",
"group_id": XXXXX
}
]
}
I need to iterate the tasks in Terraform to do some manipulation but i am not able to do so.
I tried toset(data.http.example.body.tasks) and tolist(data.http.example.body.tasks) but it says attribute doesn't exists.
Can someone please help?
The docs say that the body is raw response. I So I think you should use jsondecode, not jsonencode. Then you access tasks as follows:
jsondecode(data.http.example.body).tasks
or iterate (example):
[for task in jsondecode(data.http.example.body).tasks: task.status]

How to access the json data in react native mentioned in below pattern?

The json data is in the below pattern. And the Json data is coming from backend and getting through api and storing in a state variable.
{
"message": "user created successfully",
"status": "success",
"student": {
"class": "10",
"email": "user#gmail.com",
"name": "User",
"password": "user",
"phone_number": "some phone number",
"school": "1",
"section": "a"
}
}
I have stored the data which is returned through api in a state variable.
constructor(){
super();
this.state = {
jsonData: ''
}
}
And tried accessing using below fashion.
this.state.jsonData.status
but not able to access. How can I access the status value in react?
Please check type of jsonData in state when you call it using typeof or instanceof.
It maybe by you store fetched data in string type without check and manipulating.
If it is string type, convert it using JSON.parse

How to read data from nested JSON structure in protractor

Below is my code and I want to extract data under "specs" part like description, status etc. however I'm getting undefined when I capture the data and print it in the console. I have tried
let web = JSON.parse(jsondata);
let TestSuite = web["suite1"]["description"]
and this is providing data in console however, when I use this,
let id = web["suite1"]["specs"]["id"]
its gives undefined. Please help!
{
"suite1": {
"id": "suite1",
"description": "Login",
"fullName": "Login",
"failedExpectations": [],
"status": "finished",
"specs": [
{
"id": "spec0",
"description": "Should able to login into the Distribution management Webpage",
"fullName": "Login Should able to login into the Distribution management Webpage",
"failedExpectations": [
{
"matcherName": "",
"message": "",
"stack": "",
"passed": false,
"expected": "",
"actual": ""
}
],
"passedExpectations": [],
"pendingReason": "",
"started": "2018-09-06T06:57:42.740Z",
"status": "failed",
"duration": "7 secs",
"stopped": "2018-09-06T06:57:49.255Z",
"browserLogs": []
}
]
} }
JSON.parse(JSON.stringify(json)).suite1.specs[0].id
specs contains an array of objects. First, you need to get the object from the array and then get a value of the object.
Try this:
let id = web["suite1"]["specs"][0]["id"]
OR
let id = web.suite1.specs[0].id
Hope this will work.
When you do ["suite1"]["specs"], you select array. You need an index, which is the 0-th one in this case.
You can check that by typing Object.prototype.toString.call( data["suite1"]["specs"]).
You can try with:
data["suite1"]["specs"][0]["id"]
Or use the object property notation
data["suite1"]["specs"][0].id

Unable to loop through JSON output from webservice Python

I have a web-service call (HTTP Get) that my Python script makes in which returns a JSON response. The response looks to be a list of Dictionaries. The script's purpose is to iterate through the each dictionary, extract each piece of metadata (i.e. "ClosePrice": "57.74",) and write each dictionary to its own row in Mssql.
The issue is, I don't think Python is recognizing the JSON output from the API call as a list of dictionaries, and when I try a for loop, I'm getting the error must be int not str. I have tried converting the output to a list, dictionary, tuple. I've also tried to make it work with List Comprehension, with no luck. Further, if I copy/paste the data from the API call and assign it to a variable, it recognizes that its a list of dictionaries without issue. Any help would be appreciated. I'm using Python 2.7.
Here is the actual http call being made: http://test.kingegi.com/Api/QuerySystem/GetvalidatedForecasts?user=kingegi&market=us&startdate=08/19/13&enddate=09/12/13
Here is an abbreviated JSON output from the API call:
[
{
"Id": "521d992cb031e30afcb45c6c",
"User": "kingegi",
"Symbol": "psx",
"Company": "phillips 66",
"MarketCap": "34.89B",
"MCapCategory": "large",
"Sector": "basic materials",
"Movement": "up",
"TimeOfDay": "close",
"PredictionDate": "2013-08-29T00:00:00Z",
"Percentage": ".2-.9%",
"Latency": 37.48089483333333,
"PickPosition": 2,
"CurrentPrice": "57.10",
"ClosePrice": "57.74",
"HighPrice": null,
"LowPrice": null,
"Correct": "FALSE",
"GainedPercentage": 0,
"TimeStamp": "2013-08-28T02:31:08 778",
"ResponseMsg": "",
"Exchange": "NYSE "
},
{
"Id": "521d992db031e30afcb45c71",
"User": "kingegi",
"Symbol": "psx",
"Company": "phillips 66",
"MarketCap": "34.89B",
"MCapCategory": "large",
"Sector": "basic materials",
"Movement": "down",
"TimeOfDay": "close",
"PredictionDate": "2013-08-29T00:00:00Z",
"Percentage": "16-30%",
"Latency": 37.4807215,
"PickPosition": 1,
"CurrentPrice": "57.10",
"ClosePrice": "57.74",
"HighPrice": null,
"LowPrice": null,
"Correct": "FALSE",
"GainedPercentage": 0,
"TimeStamp": "2013-08-28T02:31:09 402",
"ResponseMsg": "",
"Exchange": "NYSE "
}
]
Small Part of code being used:
import os,sys
import subprocess
import glob
from os import path
import urllib2
import json
import time
try:
data = urllib2.urlopen('http://api.kingegi.com/Api/QuerySystem/GetvalidatedForecasts?user=kingegi&market=us&startdate=08/10/13&enddate=09/12/13').read()
except urllib2.HTTPError, e:
print "HTTP error: %d" % e.code
except urllib2.URLError, e:
print "Network error: %s" % e.reason.args[1]
list_id=[x['Id'] for x in data] #test to see if it extracts the ID from each Dict
print(data) #Json output
print(len(data)) #should retrieve the number of dict in list
UPDATE
Answered my own question, here is the method below:
`url = 'some url that is a list of dictionaries' #GetCall
u = urllib.urlopen(url) # u is a file-like object
data = u.read()
newdata = json.loads(data)
print(type(newdata)) # printed data type will show as a list
print(len(newdata)) #the length of the list
newdict = newdata[1] # each element in the list is a dict
print(type(newdict)) # this element is a dict
length = len(newdata) # how many elements in the list
for a in range(1,length): #a is a variable that increments itself from 1 until a number
var = (newdata[a])
print(var['Correct'], var['User'])`