Skip to content

Instantly share code, notes, and snippets.

@drbh
Created January 17, 2019 15:55
Show Gist options
  • Save drbh/ff2b87d98fb96849c2ad2d99d4b9a3a3 to your computer and use it in GitHub Desktop.
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.
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