Created
January 17, 2019 15:55
-
-
Save drbh/ff2b87d98fb96849c2ad2d99d4b9a3a3 to your computer and use it in GitHub Desktop.
This script directs websocket requests and sessions with DynamoDB and another Lambda function as the game logic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import time | |
import sys | |
import os | |
import base64 | |
import datetime | |
import hashlib | |
import hma | |
from botocore.vendored import requests | |
import boto3 | |
dynamodb = boto3.resource('dynamodb') | |
table = dynamodb.Table('go-quick') | |
def sign(key, msg): | |
return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest() | |
def getSignatureKey(key, date_stamp, regionName, serviceName): | |
kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp) | |
kRegion = sign(kDate, regionName) | |
kService = sign(kRegion, serviceName) | |
kSigning = sign(kService, 'aws4_request') | |
return kSigning | |
def send_message_to_channel(channelId, request_parameters): | |
method = 'POST' | |
service = 'execute-api' | |
host = '0qhm3hmwjc.execute-api.us-east-1.amazonaws.com' | |
region = 'us-east-1' | |
endpoint = 'https://0qhm3hmwjc.execute-api.us-east-1.amazonaws.com/dev-deploy/@connections/' + channelId | |
content_type = 'application/x-amz-json-1.0' | |
amz_target = '' | |
access_key = "YOUR_ACCESS_KEYS" | |
secret_key = "SECRET_KEY" | |
if access_key is None or secret_key is None: | |
sys.exit() | |
t = datetime.datetime.utcnow() | |
amz_date = t.strftime('%Y%m%dT%H%M%SZ') | |
date_stamp = t.strftime('%Y%m%d') | |
canonical_uri = '/dev-deploy/%40connections/' + channelId[:-1] + "%3D" | |
canonical_querystring = '' | |
canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + \ | |
'\n' + 'x-amz-date:' + amz_date + '\n' + 'x-amz-target:' + amz_target + '\n' | |
signed_headers = 'content-type;host;x-amz-date;x-amz-target' | |
payload_hash = hashlib.sha256( | |
request_parameters.encode('utf-8')).hexdigest() | |
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + \ | |
'\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash | |
algorithm = 'AWS4-HMAC-SHA256' | |
credential_scope = date_stamp + '/' + region + \ | |
'/' + service + '/' + 'aws4_request' | |
string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + \ | |
'\n' + hashlib.sha256(canonical_request.encode('utf-8')).hexdigest() | |
signing_key = getSignatureKey(secret_key, date_stamp, region, service) | |
signature = hmac.new(signing_key, (string_to_sign).encode( | |
'utf-8'), hashlib.sha256).hexdigest() | |
authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + \ | |
credential_scope + ', ' + 'SignedHeaders=' + \ | |
signed_headers + ', ' + 'Signature=' + signature | |
headers = {'Content-Type': content_type, | |
'X-Amz-Date': amz_date, | |
'X-Amz-Target': amz_target, | |
'Authorization': authorization_header} | |
r = requests.post(endpoint, data=request_parameters, headers=headers) | |
channels = {} | |
def play_game(word, card1, card2): | |
lambda_client = boto3.client('lambda') | |
obj = { | |
"Name": "play", | |
"Red": card1, | |
"Blue": card2, | |
"Word": word | |
} | |
print obj | |
response = lambda_client.invoke( | |
FunctionName='go-quick', | |
InvocationType='RequestResponse', | |
LogType='None', | |
Payload=json.dumps(obj), | |
) | |
res_json = json.loads(response['Payload'].read().decode("utf-8")) | |
print res_json | |
return res_json["Flag"] | |
def get_cards(channel): | |
response = table.get_item(Key={"channel": channel}) | |
dynamo_obj = response["Item"] | |
return dynamo_obj["card1"], dynamo_obj["card2"] | |
def get_new_cards(): | |
lambda_client = boto3.client('lambda') | |
obj = { | |
"Name": "deal", | |
"Red": "", | |
"Blue": "", | |
"Word": "" | |
} | |
response = lambda_client.invoke( | |
FunctionName='go-quick', | |
InvocationType='RequestResponse', | |
LogType='None', | |
Payload=json.dumps(obj), | |
) | |
res_json = json.loads(response['Payload'].read().decode("utf-8")) | |
return res_json["Red"], res_json["Blue"] | |
def submit_word(word, channel): | |
card1, card2 = get_cards(channel) | |
result = play_game(word, card1, card2) | |
return result | |
def lambda_handler(event, context): | |
print int(time.time()) | |
print json.dumps(event) | |
print table | |
if "body" in event: | |
obj = None | |
n = event["body"] | |
print n | |
try: | |
obj = json.loads(n) | |
except Exception as e: | |
print "bad event" | |
if obj is None: | |
pass | |
else: | |
action = obj["action"] | |
obj = obj["data"] | |
print "action", action | |
action = obj["action"] | |
print "action", action | |
if action == "init": | |
new_channel_name = event["requestContext"]["connectionId"] | |
channels[new_channel_name] = { | |
"status": "pending", | |
"player_1": obj["user"] | |
} | |
response = table.put_item( | |
Item={ | |
"channel": new_channel_name, | |
"status": "pending", | |
"player_1": obj["user"] | |
} | |
) | |
channelId = event["requestContext"]["connectionId"] | |
user1 = obj["user"] | |
request_parameters = json.dumps( | |
{ | |
"type": "started", | |
"user": user1, | |
"channelId": channelId, | |
"starttime": int(time.time()) | |
}) | |
send_message_to_channel(channelId, request_parameters) | |
print "Sent Start" | |
print new_channel_name | |
if action == "join": | |
channelId = event["requestContext"]["connectionId"] | |
user1 = channels[obj["channel"]]["player_1"] | |
response = table.get_item(Key={"channel": obj["channel"]}) | |
if "Item" in response: | |
dynamo_obj = response["Item"] | |
print dynamo_obj | |
card1, card2 = get_new_cards() | |
request_parameters = json.dumps( | |
{ | |
"type": "joined", | |
"user1": dynamo_obj["player_1"], | |
"user2": obj["user"], | |
"channel": dynamo_obj["channel"], | |
"card1": card1, | |
"card2": card2, | |
"guestchannel": channelId | |
}) | |
response = table.put_item( | |
Item={ | |
"channel": dynamo_obj["channel"], | |
"status": "inprogress", | |
"player_1": dynamo_obj["player_1"], | |
"player_2": obj["user"], | |
"card1": card1, | |
"card2": card2, | |
"questchannel": channelId | |
} | |
) | |
print response | |
send_message_to_channel(obj["channel"], request_parameters) | |
send_message_to_channel(channelId, request_parameters) | |
print "Sent Join" | |
if action == "submit": | |
user_won = submit_word(obj["word"], obj["channel"]) | |
response = table.get_item(Key={"channel": obj["channel"]}) | |
if "Item" in response: | |
dynamo_obj = response["Item"] | |
print dynamo_obj | |
user1 = dynamo_obj["player_1"] | |
user2 = dynamo_obj["player_2"] | |
request_parameters = json.dumps( | |
{ | |
"type": "message", | |
"user": obj["user"], | |
"word": obj["word"], | |
"flag": user_won, | |
"channel": dynamo_obj["channel"] | |
}) | |
send_message_to_channel( | |
dynamo_obj["channel"], request_parameters) | |
send_message_to_channel( | |
dynamo_obj["questchannel"], request_parameters) | |
request_parameters = json.dumps( | |
{ | |
"type": "message", | |
"user": obj["user"], | |
"word": obj["word"], | |
"flag": user_won, | |
"channel": dynamo_obj["channel"] | |
}) | |
if user_won: | |
send_message_to_channel( | |
dynamo_obj["questchannel"], request_parameters) | |
send_message_to_channel( | |
dynamo_obj["channel"], request_parameters) | |
print json.dumps(event) | |
return { | |
'statusCode': 200, | |
'body': json.dumps({"action": "message", "data": "hello from lambda"}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment