'body': KeyError in AWS Lambda function for Telegram Bot - python

I followed a guide to set up a Telegram Bot through AWS, so after preparing the function (and the gateway API) to handle a simple bot which answers with the same message i stumbled upon a KeyError on the word 'body'. Here's the code:
import json
from botocore.vendored import requests
TELE_TOKEN='700794743:AAFtypDtqP3-dOMC5dSX7DqtwVRGNuKZhH8'
URL = "https://api.telegram.org/bot{}".format(TELE_TOKEN)
def send_message(text, chat_id):
final_text = "You said: " + text
url = URL + "/sendMessage?text={}&chat_id={}".format(final_text, chat_id)
requests.get(url)
def lambda_handler(event, context):
message = json.loads(event['body'])
chat_id = message['message']['chat']['id']
reply = message['message']['text']
send_message(reply, chat_id)
return {
'statusCode': 200
}
'body': KeyError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 13, in lambda_handler
message = json.loads(event['body'])
KeyError: 'body'
I don't know what could possibly be wrong, maybe the 'event' json file doesn't actually have a 'body' parameter? Any help with this would be appreciated!

Related

AADSTS900144: The request body must contain the following parameter: 'grant_type' with Microsoft Defender for Endpoint API

I am attempting to authenticate with Microsoft Defender for Endpoint's API service by following this learn article:
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/run-advanced-query-sample-python?view=o365-worldwide#get-token
I typically use the "request" library for REST calls, so I didn't follow the above code snippet exactly. When running my version of the above code:
import json
import requests
MDE_CLIENT_ID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'
MDE_CLIENT_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
TENANT_ID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'
AUTHORITY = 'https://login.microsoftonline.com/'
MDE_URI = 'https://api.securitycenter.microsoft.com'
class RESTError(Exception):
def __init__(self, status_code, message):
self.status_code = status_code
self.message = str(self.status_code) + ' ' + json.dumps(message)
super().__init__(self.message)
def authenticate_mde():
headers = {
'content-type': 'application/x-www-form-urlencoded'
}
body = {
'resource': MDE_URI,
'client_id': MDE_CLIENT_ID,
'client_secret': MDE_CLIENT_SECRET,
'grant_type': 'client_credentials'
}
response = requests.post(AUTHORITY + TENANT_ID + '/oauth2/token', data = json.dumps(body), headers = headers)
if (response.status_code < 200 or response.status_code > 299):
raise RESTError(response.status_code, response.json())
return response.json()['access_token']
def main():
token = authenticate_mde()
print(token)
if (__name__ == '__main__'):
main()
When I run this code I receive a 400 error back from the authentication service complaining about a missing body parameter 'grant_type'. However, as you can see in the code, I clearly have that included in the same fashion as the code snippet from MSFT.
Traceback (most recent call last):
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 42, in <module>
main()
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 38, in main
token = authenticate_mde()
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 32, in authenticate_mde
raise RESTError(response.status_code, response.json())
__main__.RESTError: 400 {"error": "invalid_request", "error_description": "AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: e4d0d06e-aae6-4b6d-80e2-2b3997f74302\r\nCorrelation ID: 5788089d-f94e-4e9a-8667-d6e36c183af8\r\nTimestamp: 2023-01-06 17:00:23Z", "error_codes": [900144], "timestamp": "2023-01-06 17:00:23Z", "trace_id": "e4d0d06e-aae6-4b6d-80e2-2b3997f74302", "correlation_id": "5788089d-f94e-4e9a-8667-d6e36c183af8", "error_uri": "https://login.microsoftonline.com/error?code=900144"}
I also tried copying MSFT's code snippet exactly and inserting my own global var info but receive the same error. I have tried moving the body to url parameters, headers, splitting it up between body, params, and headers. No luck. I have tried different content-types in the header as well and tried without any headers. None seems to work and I am stumped at this point.
I resolved the issue. Passing 'resource' into the body was apparently screwing it up, even though their python example here shows that:
import json
import urllib.request
import urllib.parse
tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)
resourceAppIdUri = 'https://api.securitycenter.microsoft.com'
body = {
'resource' : resourceAppIdUri,
'client_id' : appId,
'client_secret' : appSecret,
'grant_type' : 'client_credentials'
}
data = urllib.parse.urlencode(body).encode("utf-8")
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
aadToken = jsonResponse["access_token"]
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/run-advanced-query-sample-python?view=o365-worldwide#get-token
Following the example they give for cURL here and using the 'scope' parameter instead fixed it.
curl -i -X POST -H "Content-Type:application/x-www-form-urlencoded" -d "grant_type=client_credentials" -d "client_id=%CLIENT_ID%" -d "scope=https://securitycenter.onmicrosoft.com/windowsatpservice/.default" -d "client_secret=%CLIENT_SECRET%" "https://login.microsoftonline.com/%TENANT_ID%/oauth2/v2.0/token" -k
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/exposed-apis-create-app-webapp?view=o365-worldwide#use-curl

How do I refresh discord oauth2 token

So far this is my code
import requests, json
API_ENDPOINT = 'https://discord.com/api/v8'
CLIENT_ID = '82'
CLIENT_SECRET = 'db'
REDIRECT_URI = 'https://google.com'
def refresh_token(refresh_token):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
js = json.loads(open("token.json", "r").read())
for i in js:
js[i] = refresh_token(js[i]["refresh_token"])
open("token.txt", "w").write(json.dumps(js))
Every time I run it, I get a 400 error
Traceback (most recent call last):
js[i] = refresh_token(js[i]["refresh_token"])
File "c:\Users\c\Downloads\discord-oauth2-example-master\discord-oauth2-example-master\refresh.py", line 18, in refresh_token
r.raise_for_status()
File "C:\Users\c\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\requests\models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://discord.com/api/v8/oauth2/token
The code is taken directly from the discord website, so i have no idea what is going wrong. My original token grants are working but not this. Any ideas?
Thanks
I think you should provide the scope key in the data object itself. The scope is the key that you initially set when you created the access_token;
Example of scope key that is separated by whitespace:
identify email guilds
If you check the discord-oauth2 library, it requires us to pass the "scope" key into the data object
https://www.npmjs.com/package/discord-oauth2

Error when extracting data from JSON webhook

I am not able to access the data from the event in the python function
I am trying to get the name from the JSON
def handler(event, context):
resp = event
user_name = resp['body']['user']['name']
but I get the following error
ERROR] TypeError: string indices must be integers
Traceback (most recent call last):
File "/var/task/index.py", line 28, in handler
user_name = resp['body']['user']['name']
It seems that resp is of string type. load your response in JSON before accessing it.
import json
resp = json.loads(resp)
The below solution worked for me. The event body should be retrieved first
import json
def handler(event, context):
resp = json.loads(event["body"])
user_name = event['user']['name']

Getting error making calls with twilio python api

Getting this error when I try to make a call with the twilio python api:
Jacob-Mac-mini:downloads kovyjacob$ python3 twilio_call.py
Traceback (most recent call last):
File "/Users/kovyjacob/Downloads/twilio_call.py", line 11, in <module>
call = client.calls.create(
File "/Users/kovyjacob/Library/Python/3.9/lib/python/site-packages/twilio/rest/api/v2010/account/call/__init__.py", line 141, in create
payload = self._version.create(method='POST', uri=self._uri, data=data, )
File "/Users/kovyjacob/Library/Python/3.9/lib/python/site-packages/twilio/base/version.py", line 205, in create
raise self.exception(method, uri, response, 'Unable to create record')
twilio.base.exceptions.TwilioRestException:
HTTP Error Your request was:
POST /Accounts/['AC766eaf7ef8d79de658756223cee446df']/Calls.json
Twilio returned the following information:
Unable to create record: The requested resource /2010-04-01/Accounts/['AC766eaf7ef8d79de658756223cee446df']/Calls.json was not found
More information may be available here:
https://www.twilio.com/docs/errors/20404
I checked the link, but a) I'm not sure what the problem is exactly, and b) it doesn't say how to fix it.
This is the code:
from twilio.rest import Client
# Your Account Sid and Auth Token from twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ['AC766eaf7ef8d79de658756223cee446df']
auth_token = ['74ef4743a7a9a748cxxxxxxxxxxxxxxx']
client = Client(account_sid, auth_token)
call = client.calls.create(
twiml='<Response><Say>Ahoy, World!</Say></Response>',
to='+14372341004',
from_='+14243560675'
)
print(call.sid)
account_sid and auth_token should be passed as strings, not array with string inside.
Twillio Rest Client Source Code
Edit your code to:
account_sid = 'AC766eaf7ef8d79de658756223cee446df'
auth_token = '74ef4743a7a9a748cxxxxxxxxxxxxxxx'

Google Oauth refresh_token invalid_grant

I wrote a small app to clean out errors in Google's Search Console (formally Google Webmaster Tools) using Oauth to connect accounts. This was running fine for the past two weeks, however, today I have noticed the the following error:
Error
Traceback (most recent call last):
File "/home/graingerkid/search_console_auto/scripts/error_count.py", line 97, in <module>
get_error_stats()
File "/home/graingerkid/search_console_auto/scripts/error_count.py", line 19, in get_error_stats
access_token = get_refreshed_tokens(refresh_token)
File "/home/graingerkid/search_console_auto/scripts/refresh_token.py", line 25, in get_refreshed_tokens
access_token = keys['access_token']
KeyError: 'access_token'
After investigating and trying to debug my code I realised I was not getting an access_token when requesting one with the refresh_token, here is the output:
Output
{
"error" : "invalid_grant"
}
Here is the function I wrote to grab the access_tokens (I've changed sensitive info):
Code
#-*- coding:utf-8 -*-
import json
import httplib2
import urllib
import pprint
def get_refreshed_tokens(refresh_token):
GOOGLE_CLIENT_ID = '98997543650-f0tn93u86vmts4j2m987654359shue6gu9g.apps.googleusercontent.com'
GOOGLE_CLIENT_SECRET = 'TFGZVLVG7VtnnrbNDTYFNBRgbfdFuENkBY'
h = httplib2.Http(".cache")
url = 'https://accounts.google.com/o/oauth2/token'
body = {
'client_secret': GOOGLE_CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
'client_id': GOOGLE_CLIENT_ID
}
headers = {'Content-type': 'application/x-www-form-urlencoded', 'cache-control': 'no-cache'}
response, content = h.request(url, 'POST', headers=headers, body=urllib.urlencode(body))
print content
keys = json.loads(content)
try:
access_token = keys['access_token']
except Exception as e:
pass
access_token = None
return access_token
get_refreshed_tokens('1/lWS6Fu3Hz5dMBPk9huVu6mt5yrnj5hrunhMEf7vs_UdibrBactUREZofsF9C7PrpE-j')
When requesting access to a users account I use the following:
google = oauth.remote_app('google',
base_url='https://www.google.com/accounts/',
authorize_url='https://accounts.google.com/o/oauth2/auth',
request_token_url=None,
request_token_params={'scope': 'https://www.googleapis.com/auth/webmasters https://www.googleapis.com/auth/userinfo.email',
'response_type': 'code',
'access_type':'offline',
'approval_prompt':'force'},
access_token_url='https://accounts.google.com/o/oauth2/token',
access_token_method='POST',
access_token_params={'grant_type': 'authorization_code'},
consumer_key=GOOGLE_CLIENT_ID,
consumer_secret=GOOGLE_CLIENT_SECRET)
Bearing in mind this worked fine for several weeks, I'm struggling to understand what's gone wrong, and searches on SO have not yielded answers.
Can anyone help with this?
(the accounts connected to these are mine, I have checked their access and the API access in Google API console is still intact, nothing has changed.)

Categories

Resources