Parse JSON POST body inside an autotask

Hi everyone,

I'm trying to run an autotask using webhook. The idea is to pass two values "ipfsCid" and "username" inside the body of the HTTP request that will be passed dynamically inside the smart contract call.

This is the call for the webhook

--header 'Content-Type: application/json' \
--data-raw '{   
    "ipfsCid": "QmfELgWd5V261TCSxKqferBAfoXVvwugKY59mntFMifoLT",
    "bytes32UserName": "0x656e7269636f0000000000000000000000000000000000000000000000000000"
}'

While this is the code of the autotask

const { DefenderRelaySigner, DefenderRelayProvider } = require('defender-relay-client/lib/ethers');
const ethers = require('ethers');

exports.handler = async function(event) {
  const provider = new DefenderRelayProvider(event);
  const signer = new DefenderRelaySigner(event, provider);
  // Use provider and signer for querying or sending txs from ethers, for example...
    let registry_ADDR = "0x2cFB3A82fAff819dB7fEBBCD75Bef6200a55dce4"
    
    let REGISTRY_ABI = [
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "domain",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "string",
          "name": "ownerData",
          "type": "string"
        }
      ],
      "name": "NewDomain",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "domain",
          "type": "bytes32"
        },
        {
          "internalType": "string",
          "name": "ownerData",
          "type": "string"
        }
      ],
      "name": "setDomain",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]
    
  const {
    body,    // Object with JSON-parsed POST body
    headers, // Object with key-values from HTTP headers
    queryParameters, // Object with key-values from query parameters
  } = event.request;
    
  var ipfsCid = JSON.parse(body).ipfsCid;
  var bytes32UserName = JSON.parse(body).bytes32UserName;
  const contract = new ethers.Contract(registry_ADDR, REGISTRY_ABI, signer);
  
  await contract.setDomain(bytes32UserName, ipfsCid)
  
}

When executing this post request I get an error message
'Unexpected token Q in JSON at position 0' as I'm not able to parse the body of the request correctly. Do you have any idea how to solve that?

1 Like

Hey @enricobottazzi

I just tried replicating the exact same example you provide but I added a console.log before the JSON.parse, and it seems that the JSON is already parsed so you can access the ipfsCid key directly.

Can you give it a try like that? Or log the body before parsing so we can be sure what's there?

Hope this helps, best!

1 Like

Hi @ernestognw, thanks for the reply. I realized that you are right. I can access ipfsCid directly from the body in this way
const ipfsCid = body.ipfsCid

For example I'll configure my webhook to return this ipfsCid

return ipfsCid

When calling the webhook (I'm using Postman for that) I see the ipfsCid inside the result of the API response. But this is formatted in a strange way :

{
    "autotaskRunId": "08c7cbd7-285e-49af-b586-7eb860454e54",
    "autotaskId": "09779553-0606-4adf-b372-55e09b284bf8",
    "trigger": "webhook",
    "status": "success",
    "createdAt": "2022-11-10T11:01:07.228Z",
    "encodedLogs": "QVVUT1RBU0sgU1RBUlQKRU5EIFJlcXVlc3RJZDogNDJkODI5NjYtYWE4MC00ZTM2LTg0MjUtZTMwNmFjMTExOWEzCkFVVE9UQVNLIENPTVBMRVRF",
    "result": "\"QmfELgWd5V261TCSxKqferBAfoXVvwugKY59mntFMifoLT\"",,
    "requestId": "42d82966-aa80-4e36-8425-e306ac1119a3"
}

Do you know if there's a way to return it in a cleaner way? Thanks

1 Like

Hey @enricobottazzi, that's amazing, I'm glad it worked.

Regarding your new question, the result field is a JSON stringified, so whatever value you put there will be serialized in order to be returned, and you can consume it on your application by just doing JSON.parse(response.result), this will remove the strange format.

Unfortunately, this is not something we can change since it's the default Autotask behavior and depends on the infra we're using. However, no other user has had a problem with this, only use the method I suggested.

Hope it helps :smiley: