Logic Machine Forum
Ajax async comunication with AWS sqs - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Ajax async comunication with AWS sqs (/showthread.php?tid=6053)



Ajax async comunication with AWS sqs - Andrea Becagli - 18.07.2025

Hi, I have gained access to the Ajax Enterprise API I am having no issues using the REST API, but to receive real-time data from alarm sensors, I would like to use asynchronous requests.

now I was studying AWS SQS method and I saw that every request needs to be signed  AWS Signature Version 4. Have you ever implemented something like this in LM? Is it even possible? 

I found a few Lua libraries on the subject, but they usually depend on other libraries, which I'm not sure I can get.
Could someone help me Huh


RE: Ajax async comunication with AWS sqs - admin - 21.07.2025

Try this code (adapted from https://stackoverflow.com/questions/73244772/how-to-sign-post-request-with-aws-signature-version-4):
You will need to use socket.http and pass headers to the request.

Code:
require('encdec')

local access_key = "XXXX"
local secret_key = "XXXX"
local method = 'POST'
local service = 'execute-api'
local host = 'dfadfadfdafda.execute-api.us-east-2.amazonaws.com'
local region = 'us-east-2'
local base = "https://"
local content_type = 'application/json'
local request_parameters = '{"date":"today","content":"hello"}'
local canonical_uri = '/prod/events/add-event'

-- DynamoDB requires an x-amz-target header that has this format:
--     DynamoDB_<API version>.<operationName>
local amz_target = ''

function getSignatureKey(key, dateStamp, regionName, serviceName)
  local kDate = encdec.hmacsha256(dateStamp, 'AWS4' .. key, true)
  local kRegion = encdec.hmacsha256(regionName, kDate, true)
  local kService = encdec.hmacsha256(serviceName, kRegion, true)
  local kSigning = encdec.hmacsha256('aws4_request', kService, true)
  return kSigning
end

-- ************* TASK 1: CREATE A CANONICAL REQUEST *************
-- http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

-- Step 1 is to define the verb (GET, POST, etc.)--already done.

-- Step 2: Create canonical URI--the part of the URI from domain to query
-- string (use '/' if no path)
-- Create a date for headers and the credential string
local amz_date = os.date('!%Y%m%dT%H%M%SZ')
local date_stamp = amz_date:split('T')[1]

--// Step 3: Create the canonical query string. In this example, request
-- parameters are passed in the body of the request and the query string
-- is blank.
local canonical_querystring = ''

--## DOing step 6 first so that I can include the payload hash in the cannonical header, per https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
-- Step 6: Create payload hash. In this example, the payload (body of
-- the request) contains the request parameters.
--local payload_hash = hashlib.sha256(request_parameters.encode('utf-8')).hexdigest()
local payload_hash = encdec.sha256(request_parameters)

-- Step 4: Create the canonical headers. Header names must be trimmed
-- and lowercase, and sorted in code point order from low to high.
-- Note that there is a trailing \n.
local canonical_headers = 'host:' .. host .. '\n' .. 'x-amz-content-sha256:' .. payload_hash .. '\n' .. 'x-amz-date:' .. amz_date .. '\n'

-- Step 5: Create the list of signed headers. This lists the headers
-- in the canonical_headers list, delimited with ";" and in alpha order.
-- Note: The request can include any headers; canonical_headers and
-- signed_headers include those that you want to be included in the
-- hash of the request. "Host" and "x-amz-date" are always required.
local signed_headers = 'host;x-amz-content-sha256;x-amz-date'

-- Step 7: Combine elements to create canonical request
local canonical_request = method .. '\n' .. canonical_uri .. '\n' .. canonical_querystring .. '\n' .. canonical_headers .. '\n' .. signed_headers .. '\n' .. payload_hash

-- ************* TASK 2: CREATE THE STRING TO SIGN*************
-- Match the algorithm to the hashing algorithm you use, either SHA-1 or
-- SHA-256 (recommended)
local algorithm = 'AWS4-HMAC-SHA256'
local credential_scope = date_stamp .. '/' .. region .. '/' .. service .. '/' .. 'aws4_request'
local string_to_sign = algorithm .. '\n' ..  amz_date .. '\n' ..  credential_scope .. '\n' ..  encdec.sha256(canonical_request)

-- ************* TASK 3: CALCULATE THE SIGNATURE *************
-- Create the signing key using the function defined above.
local signing_key = getSignatureKey(secret_key, date_stamp, region, service)

-- Sign the string_to_sign using the signing_key
local signature = encdec.hmacsha256(string_to_sign, signing_key)
-- ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
-- Put the signature information in a header named Authorization.
local authorization_header = algorithm .. ' ' .. 'Credential=' .. access_key .. '/' .. credential_scope .. ', ' ..  'SignedHeaders=' .. signed_headers .. ', ' .. 'Signature=' .. signature

-- For DynamoDB, the request can include any headers, but MUST include "host", "x-amz-date",
-- "x-amz-target", "content-type", and "Authorization". Except for the authorization
-- header, the headers must be included in the canonical_headers and signed_headers values, as
-- noted earlier. Order here is not significant.
local headers = {
    ['X-Amz-Content-Sha256'] = payload_hash,
    ['X-Amz-Date'] = amz_date,
    -- ['X-Amz-Target'] = amz_target,
    ['Authorization'] = authorization_header,
    ['Content-Type'] = content_type
}

log(headers)