How to use BlockSurvey as a headless form or a survey

Usually, form and survey tools allow you to create visually without knowing how to code. But it comes with a drawback. You cannot make it as flexible as you want. 

If you are building a website and want the forms to be closest to your brand, then you must code them for cohesiveness. This is where headless forms and surveys help. 

Without worrying about the backend of the data collection involved, you can build a front end of your choice and push the data to the headless provider.

What’s more? With BlockSurvey, you can do that with end-to-end encryption. 

Below is a sample subscription widget created using BlockSurvey in a headless way.

How can BlockSurvey be used as a headless form or survey?

Pre-requirement: 

tweet-nacl will be used to encrypt the survey answer. So, install dependencies using the given command,


npm install tweetnacl tweetnacl-util

Steps to implement:

  1. Get your BlockSurvey Account ID
  2. Get your BlockSurvey ID
  3. Get your Public Key
  4. Get all the questions id’s
  5. Form the answer object
  6. Encrypt using tweet-nacl
  7. Send encrypted payload to BlockSurvey API
  8. Demo Headless Form

1. Get your BlockSurvey Account ID

Go to My Account from the Dashboard and copy your Account ID.

const user_id = "compressstudio1.id.blockstack";

2 & 3: Get your BlockSurvey ID and BlockSurvey’s public key


In Design, Go to Settings -> Developer Settings (as shown in the screenshot below). You will find the BlockSurvey ID and the Public Key.

const blocksurvey_id = "ba6adeb6-69bd-48f7-ae4f-221f8565e7dc";

const surveyPublicKeyBase64 = "ZTaZo6vIPv5+ryGcQtd7dX2x/4haHwE4IkUtdMGXR1s=";

4. Get question id


This is available from the question reference.

Get all question IDs to populate the answer,

let questionId = "af0f7724-a82a-49b8-b15d-e725887443bd";

5. Form the answer object


Let us construct the payload to submit the BlockSurvey, Payload pattern,

const answerObject = {

"<questionId>": "[email protected]"

};

e.g.,

const answerObject = {"af0f7724-a82a-49b8-b15d-e725887443bd": "[email protected]"};

6. Encrypt answers using tweet-nacl


Now we have to encrypt the answer using tweet-nacl by following the below steps,

// Import required API’s

import { box, randomBytes } from 'tweetnacl';

import { decodeBase64, decodeUTF8, encodeBase64, encodeUTF8 } from 'tweetnacl-util';


const newNonce = () => randomBytes(box.nonceLength);


// Convert Survey's public key from Base64 to Uinit8Array

const surveyPublicKeyUnit8Array = decodeBase64(surveyPublicKeyBase64);


// Generate new pair of keys for each respondent

const respondentKeyPair = box.keyPair();


// Generate a shared key

const sharedKey = box.before(surveyPublicKeyUnit8Array, respondentKeyPair.secretKey);


// Encrypt the answerObject

const encryptedAnswerObj = encryptJsonByTweetnacl(sharedKey, answerObject);


// Write a function to encrypt JSON

const encryptJsonByTweetnacl = (sharedKey: Uint8Array, json: any, key?: Uint8Array) => {

const nonce = newNonce();

const messageUint8 = decodeUTF8(JSON.stringify(json));

const encrypted = key

? box(messageUint8, nonce, key, sharedKey)

: box.after(messageUint8, nonce, sharedKey);


const fullMessage = new Uint8Array(nonce.length + encrypted.length);

fullMessage.set(nonce);

fullMessage.set(encrypted, nonce.length);


const base64FullMessage = encodeBase64(fullMessage);

return base64FullMessage;

}

7. Construct the final payload and send it to BlockSurvey API

// Final payload

const finalPayload = {

"qid": blocksurvey_id,

"userId": user_id,

"ans" : {

"d": encryptedAnswerObj,

"p": encodeBase64(respondentKeyPair.publicKey)

}

}


// Send it to BlockSurvey API

await fetch('https://api2.blocksurvey.io/api/blocksurvey/answer', {

method: 'POST',

headers: {

'Accept': 'application/json',

'Content-Type': 'application/json'

},

body: JSON.stringify(finalPayload)

});

Once you submit, you should see the submitted answer on the results screen.


Full code for your reference,

import { box, randomBytes } from 'tweetnacl';

import { decodeBase64, decodeUTF8, encodeBase64, encodeUTF8 } from 'tweetnacl-util';


const newNonce = () => randomBytes(box.nonceLength);


const blocksurvey_id = "ba6adeb6-69bd-48f7-ae4f-221f8565e7dc";

const answerObject = {"af0f7724-a82a-49b8-b15d-e725887443bd": "[email protected]"};


// Survey public key - it is a base64

const surveyPublicKeyBase64 = "ZTaZo6vIPv5+ryGcQtd7dX2x/4haHwE4IkUtdMGXR1s=";


// Convert Survey's public key from Base64 to Uinit8Array

const surveyPublicKeyUnit8Array = decodeBase64(surveyPublicKeyBase64);


// Generate new pair of keys for each respondent

const respondentKeyPair = box.keyPair();


// Generate a shared key

const sharedKey = box.before(surveyPublicKeyUnit8Array, respondentKeyPair.secretKey);


// Encrypt the answerObject

const encryptedAnswerObj = encryptJsonByTweetnacl(sharedKey, answerObject);


// Write a function to encrypt JSON

const encryptJsonByTweetnacl = (sharedKey: Uint8Array, json: any, key?: Uint8Array) => {

const nonce = newNonce();

const messageUint8 = decodeUTF8(JSON.stringify(json));

const encrypted = key

? box(messageUint8, nonce, key, sharedKey)

: box.after(messageUint8, nonce, sharedKey);


const fullMessage = new Uint8Array(nonce.length + encrypted.length);

fullMessage.set(nonce);

fullMessage.set(encrypted, nonce.length);


const base64FullMessage = encodeBase64(fullMessage);

return base64FullMessage;

}


// Final payload

const payload = {

"qid": blocksurvey_id,

"userId": user_id,

"ans" : {

"d": encryptedAnswerObj,

"p": encodeBase64(respondentKeyPair.publicKey)

}

}


// Send it to BlockSurvey API

await fetch('https://api2.blocksurvey.io/api/blocksurvey/answer', {

method: 'POST',

headers: {

'Accept': 'application/json',

'Content-Type': 'application/json'

},

body: JSON.stringify(finalPayload)

});

8. Demo Headless Form

Click Here! to try out the sample headless form with React code by yourself.

Good luck setting up your headless form to collect answers on BlockSurvey.

If you are still running into issues, contact us at [email protected] anytime.

Still need help? Contact Us Contact Us