blog-teaser

Introduction to our powerful webhook free app feature

Introduction

The barKoder demo application, available on the iOS App Store and Google Play Store for Android, includes a feature that allows users to set up a webhook that triggers with each scan.

This free feature enables users to transmit scanned data to their server quickly, ensuring fast transfer of barcode information to their server-based application. It comes built into our demo application.

General settings

The webhook section is located at the top of the Settings page. It's disabled by default, but once enabled, configuration options become available. Enabling and setting the webhook feature is pretty straight forward. The most important step in it is the webhook configuration that is handling the actual payload to the webhook. The other setting are how we deal with the payload (should we send it encoded) and the feedback (should we wait for the feedback).

First let's look at how we can enable the webhook

Enable Webhook
Enable Webhook

 

Enable Webhook Feature

Note: To enable the webhook, you must first configure it by tapping on webhook configuration.

Once you enable the webhook the configuration options become available. Enabling the webhook also means that each scanned barcode (if the webhook is configured properly) will be sent to the webhook endpoint automatically. Your next step would be to actually configure the webhook configuration.

 

Webhook configuration

After tapping on webhook configuration, a dialog screen will ask for two parameters:

Webhook configuration
Webhook configuration

Webhook endpoint (enter webhook URL)

A URL that will receive requests sent by the barKoder app. The backend server can use any technology (Node.js, PHP, Python, etc.) as long as it handles POST requests. You can select which protocol will be used for the communication to the server. So your webhook endpoint will look something like this:

example.com/web-hook

The app packages the scan result and sends a POST request to this endpoint.

Secret word (enter secret word)

A secret key used as a passkey to generate a token called security_hash. The server uses this token to authenticate requests. This is explained in the SERVER SECTION, for now just know that this will be a random word that will be used to “encrypt” the data.

 

Webhook Confirmation Feedback

You can wait for confirmation from the server about the request status. The app expects a JSON formatted response with the following structure and will show a Toast notification after the scan if this option is enabled and if the return response is valid.

The message structure from the server should be formatted like this:

{
  status:Boolean //(true or false if the actions succeeded)
  message:String // String message describing the response
}
Webhook confirmation
Webhook Confirmation Feedback

 

If you disable this option, data will still be sent, but the app won't wait for confirmation.

 

Encode webhook data

When enabled, the barcode data sent to the server will be base64 encoded, this will help if you are scanning barcodes that contain unprintable characters and similar data that might get deformed via the transport. It's arguable if you really need this feature, but it's available as an option.

Encode Webhook Data
Encode webhook data

 

Pre-send procedure (or how does the app prepare the payload)

Before sending data to the webhook, the app prepares the request with three main variables:

  • security_data (Int) Unix Timestamp in seconds (10 digits)
  • security_hash (String) A hash created using the MD5 algorithm, derived from combining security_data and secret_word
  • data (String) A JSON formatted string containing the barcode information (type, value)

If "encode data" is enabled, the data will be base64 encoded before sending.

As noted earlier, the security_hash variable is crucial. It's created by combining security_data and the secret_word.

In summary, the app generates security_data as a UNIX timestamp, concatenates it with the secret word, and then hashes the resulting string using the MD5 algorithm.

 

Pseudo code:

let security_word = "VERY-SECRET-WORD"
let security_data = UNIX_TIMESTAMP
let security_hash = md5(security_data+security_word)

Swift example:

let securityData = String(format: "%.0f", Date().timeIntervalSince1970)
let securityHash = WebhookService.md5(string: "(securityData)(secretWord)")

let parameters: Parameters = [
    "security_data": securityData,
    "security_hash": securityHash,
    "data": jsonData
]

let request = AF.request(
    url,
    method: .post,
    parameters: parameters,
    encoding: JSONEncoding.default
)

request
    .validate()
    .responseDecodable(of: WebhookResponse.self, completionHandler: { response in
        switch response.result {
        case .success(let response):
            completion(.success(response))
        case .failure(let error):
            completion(.failure(error))
        }
    }
})

Server setup

 

We extract the security_data, security_hash, and data parameters from the incoming JSON request body.

To verify the integrity of the request, we generate an MD5 hash by concatenating security_data with your secret word and comparing it to the provided security_hash.

If the computed hash matches the one received, we proceed with processing the data payload (this is where your custom logic goes). If the hashes do not match, we return a 400 Bad Request response with an appropriate error message.

Make sure to replace "your_secret_word" with your actual secret key used for hashing, and ensure the request body includes all required fields in proper JSON format.

 

NodeJS example

main : async function(req,res){

   let post_data = req.body;
   let query_data = req.query;

   //here we grab both parameters sent by the APPlet security_data = post_data?.security_data ?? false;
    let security_hash = post_data?.security_hash ?? false;
    let data = post_data?.data ?? false

   //if security_data is missing in the post, there is no point to continue
   if(!security_data){

      res.writeHead(403, {
        'Content-Type': 'application/json'
      })
      res.end(JSON.stringify({ status:false,message:'Missing security_data!' }))
       return;
   }

  //same for security_hash, if it's missing why go on?
   if(!security_hash){

      res.writeHead(403, {
        'Content-Type': 'application/json'
      })
      res.end(JSON.stringify({ status:false,message:'Missing security_hash!' }))
       return;
   }

  //now here we can do a basic comparation of the data being sent.
  //what we want to achieve is the combination of the security_data that we receive
  //and the secret_word that was inputted in the app.


  //let's use crypto to create the hash
  let crypto = require('crypto')

  //ideally you'd have the secret key in an .env file away so the line would look something like this:
            //let hash = crypto.createHash('md5').update(security_data + process.env.SECRET_WORD).digest("hex")

  //however since this is just a simple showcase and not inteded to be used on a production server we can do:

  let secret_word = 'this-is-my-very-secret-word";

  let hash = crypto.createHash('md5').update(security_data + secret_word).digest("hex");

  //this value of hash needs to match the value that we are being sent by the app stored in security_hash

  if(security_hash === hash){
     console.log('This is a valid request and we can do something with the data');

    //here DO SOMETHING WITH THE DATA

    res.writeHead(200, {
      'Content-Type': 'application/json'
    })
    res.end(JSON.stringify({ status:true,message:'All good with the data, thanks!' }))
  }
  else{
    console.log('The hash check failed to match, so we might want to deny this request');
    res.writeHead(403, {
      'Content-Type': 'application/json'
    })
    res.end(JSON.stringify({ status:false,message:'Forbidden for you!' }))
  }


},

Final words

This feature should be enough for small sized projects to just use the powerful barcode scanning capabilities of the barKoder SDK in a real production setting without having to create a custom app that would require purchasing a license. 

 

Latest Barcode Scanner SDK Articles,
Tutorials, and News