Creating Dynamic Embed Links

CONTENTS

Home

Dynamic Embedding enable you to display a custom dashboard generated for each user per your business logic. Only the data defined by the dynamic embed link is available.

Dynamic Embedding requires you to host a web application server where the generation of the dynamic embed links are programmatically handled. bipp provides a REST API endpoint to generate the embed links. You must have the API Key of your registered application for authentication.

REST API

Here are examples using the REST API.

POST /app/v1/extapps/YOUR-APP-ID/embed/generate-link

-H 'Accept: application/json'
-H 'Content-Type: application/json'
-H 'X-Org-ID: YOUR-ORG-ID'
-H 'X-API-Key: YOUR-API-KEY'

{
	"id": "DASHBOARD ID",
	"name": "DASHBOARD NAME",
	"domains": [
    	"scheme://host:port"
	],
	"filters": [
    	{
        	"column": "NAME OF DB COLUMN AS PER DATAMODEL",
        	"comparator": "COMPARATOR OPERATOR",
        	"table": "NAME OF DB TABLE AS PER DATAMODEL",
        	"value": "FILTER VALUE",
        	"logical_operator": "AND / OR"
    	}
	]
}

domains one or more domains, separated by commas.
filters one or more filters can be specified and linked with the logical AND and OR operators.
comparator operators can be =, <>, <, >, <=, >=, BETWEEN, IN, LIKE, NOT IN, NOT BETWEEN, STARTS WITH, ENDS WITH, IS NULL, IS NOT NULL, IS EMPTY, IS NOT EMPTY.

Success

HTTP status code:

201 Created

The response is similar to:

{
	"embed_url": "http://home.localhost:8080/embed/dba7eea2-3d14-48d8-b615-9fe5649e283c?id=ee31e70d-f209-46a6-ba45-06ef4256fcf3&cid=6bdc83fcd28c49e1927d01d415e7b2e2.home.localhost&secret=dyXKLQ2pGujkPah05UZKMYa5tow9YEuGbgL9!HTBDRdkN3pR"
}

Failure:

HTTP status code:

400 BadRequest 401 Unauthorized 402 PaymentRequired 403 Forbidden 500 InternalServerError

Dynamic Embedding Examples

Here are example using various languages:

Golang

This example provides dynamic embedding using programmatic filtering in Golang. The server in run on port 9191 and serves a bipp embedded dashboard.

package main
import (
   "fmt"
   "log"
   "time"
   "strings"
   "io/ioutil"
   "net/http"
   "encoding/json"
)
const (
   port = ":9191"
   orgID = "O~27gKJhx7N"
   appID = "ee31e70d-f209-46a6-ba45-06ef4256fcf3"
   apiKey = "zg0s72c6x54nxxn97qjxd8ooqzdlmzpc2t4ujzgo8rzl2ik7"
   bippURL = "https://app.bipp.io"
)
var content = `<!DOCTYPE html>
<html>
<style>
h1 {text-align: center;}
div {text-align: center;}
</style>
<body style="background-color:powderblue;">
   <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
   <script src="https://unpkg.com/bipp"></script>
   <h1>bipp Dynamic Embedding Demo (Go Server)</h1>
   <div id='container'></div><script>
   const url = "%s";
   var w = window.innerWidth;
   var h = window.innerHeight;
   let config = { id : 'container', width: w, height: h, style: 'border:none;' }
   let bipp = new Bipp();
   bipp.load(url, config);
   </script>
</body>
</html>
`
func embedHandler(w http.ResponseWriter, r * http.Request) {
   reqURL: = fmt.Sprintf("%s/app/v1/extapps/%s/embed/generate-link", bippURL, appID)
 
   method: = "POST"
   payload: = strings.NewReader(`{
   "id": "D~ZpO3WhzSG",
   "name": "TestDashboard"
   "domains": [
   "http://localhost:9191"
   ],
   "filters": [
        {
            "column": "Region",
            "comparator": "=",
            "table": "_2020",
            "value": "Western Europe",
            "logical_operator": "AND"
        },
        {
            "column": "Region",
            "comparator": "=",
            "table": "_2020",
            "value": "North America and ANZ",
            "logical_operator": "OR"
        },
        {
            "column": "Region",
            "comparator": "=",
            "table": "_2020",
            "value": "Southeast Asia"
        }
 
 
   ]}`)
   client: = & http.Client {
       Timeout: 30 * time.Second,
   }
   req,
   err: = http.NewRequest(method, reqURL, payload)
   if err != nil {
       fmt.Println(err)
       return
   }
   req.Header.Add("Accept", "application/json")
   req.Header.Add("Content-Type", "application/json")
   req.Header.Add("X-Org-ID", orgID)
   req.Header.Add("X-API-Key", apiKey)
   res,
   err: = client.Do(req)
   if err != nil {
       fmt.Println(err)
       return
   }
   defer res.Body.Close()
   body,
   err: = ioutil.ReadAll(res.Body)
   if err != nil {
       fmt.Println(err) return
   }
   type response struct {
       EmbedURL string `json:"embed_url"`
   }
   var data response
   err = json.Unmarshal(body, & data)
   if err != nil {
       fmt.Println(err)
       return
   }
   w.WriteHeader(http.StatusOK)
   w.Header().Set("Content-Type", "text/html; charset=utf-8")
   fmt.Fprintf(w, content, data.EmbedURL)
}
func main() {
   http.HandleFunc("/", embedHandler)
   log.Println("HTTP Serving at " + port)
   log.Fatal(http.ListenAndServe(port, nil))
}

Node.js

This example provides dynamic embedding using programmatic filtering in Node.js. The server in run on port 9191 and serves a bipp embedded dashboard.

const express = require('express');
const axios = require('axios');
 
const port = '9191';
const orgID = 'O~zNHknp0hV';
const appID = '28a2274d-2596-44d9-a4d0-607526855397';
const apiKey = 'rdhgstionbr65tt81vlc0lvwy47uroh5cnsum38pyf88wbie';
const bippURL = 'http://localhost:8080';
 
const content = `<!DOCTYPE html>
<html>
<style>
h1 {text-align: center;}
div {text-align: center;}
</style>
<body style="background-color:powderblue;">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/bipp"></script>
<h1>bipp Dynamic Embedding Demo (Node Server)</h1>
<div id='container'></div>
<script>
const url = '%s';
var w = window.innerWidth;
var h = window.innerHeight;
let config = { id : 'container', width: w, height: h, style: 'border:none;' }
let bipp = new Bipp();
bipp.load(url, config);
</script>
</body>
</html>`;
 
let app = express();
 
 
function embedHandler(req, res) {
 
 const url = `${bippURL}/app/v1/extapps/${appID}/embed/generate-link`;
 
 axios
   .post(
     url,
     {
       id: 'D~5UYBGNBjJ',
       name: 'Demography',
       domains: ['http://localhost:9191'],
 
       filters: [
         {
           table: "_2020",
           column: "Region",
           comparator: "="
         }
       ]
     },
     {
       headers: {
         'X-API-Key': apiKey,
         'X-Org-ID': orgID,
       },
     }
   )
   .then(function (response) {
     const { embed_url } = response.data;
 
     const data = content.replace('%s', embed_url);
     res.send(data);
   })
   .catch(function (error) {
     console.log(error);
   });
}
 
app.get('/', (req, res) => {
 embedHandler(req, res);
});
 
app.listen(port, function () {
 console.log('Running node server', 'on port ' + port);
});

Python

This example provides dynamic embedding using programmatic filtering in Python. The server in run on port 9192 and serves a bipp embedded dashboard.

#!/usr/bin/env python3
import sys, signal
import requests
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
PORT = 9192
ORGID = "O~27gKJhx7N"
APPID = "ee31e70d-f209-46a6-ba45-06ef4256fcf3"
APIKEY = "zg0s72c6x54nxxn97qjxd8ooqzdlmzpc2t4ujzgo8rzl2ik7"
BIPPURL = "https://app.bipp.io"
content = """<!DOCTYPE html>
<html>
<style>
h1 {text-align: center;}
div {text-align: center;}
</style>
<body style="background-color:powderblue;">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/bipp"></script>
<h1>bipp Dynamic Embedding Demo (Python Server)</h1>
<div id='container'></div>
<script>
const url = '%s';
var w = window.innerWidth;
var h = window.innerHeight;
let config = { id : 'container', width: w, height: h, style: 'border:none;' }
let bipp = new Bipp();
bipp.onmessage = (e) => {
console.log("bipp Embedded SDK", e.data);
}
bipp.load(url, config);
</script>
</body>
</html>"""
# A custom signal handle to allow us to Ctrl-C out of the process
def signal_handler(signal, frame):
   print( 'Exiting http server (Ctrl+C pressed)')
   try:
       if( server ):
           server.server_close()
   finally:
       sys.exit(0)
      
def embed_url():
   url = "{bipp_url}/app/v1/extapps/{app_id}/embed/generate-link".format(bipp_url=BIPPURL, app_id=APPID)
   payload = json.dumps({
       "id": "D~L_GYXHDHW",
       "name": "My Dashboard",
       "domains": ["http://localhost:9192"],
	"filters": [
           {
               "column": "Region",
               "comparator": "=",
               "table": "_2020",
               "value": "Western Europe",
               "logical_operator": "AND"
           },
           {
               "column": "Region",
               "comparator": "=",
               "table": "_2020",
               "value": "North America and ANZ",
               "logical_operator": "OR"
           },
           {
               "column": "Region",
               "comparator": "=",
               "table": "_2020",
               "value": "Southeast Asia"
           }
       ]
   })
   headers = {
       'Accept': 'application/json',
       'Content-Type': 'application/json',
       'X-Org-ID': ORGID,
       'x-api-key': APIKEY
   }
  
   response = requests.request("POST", url, headers=headers, data=payload)
   return json.loads(response.text)['embed_url']# Install the keyboard interrupt handler
   signal.signal(signal.SIGINT, signal_handler)
 
class handler(BaseHTTPRequestHandler):
   def do_GET(self):
       self.send_response(200)
       self.send_header('Content-type','text/html; charset=utf-8')
       self.end_headers()
       body = content % embed_url()
       self.wfile.write(bytes(body, "utf8"))
try:
   with HTTPServer(('', PORT), handler) as server:
       print("Http Server Serving at port", PORT)
       server.serve_forever()
except KeyboardInterrupt:
   pass
server.server_close()

Ruby

This example provides dynamic embedding using programmatic filtering in Ruby. The server in run on port 9193 and serves a bipp embedded dashboard.

#!/usr/bin/env ruby
 
require "uri"
require "json"
require "webrick"
require "net/http"
PORT = 9193
ORGID = "O~27gKJhx7N"
APPID = "ee31e70d-f209-46a6-ba45-06ef4256fcf3"
APIKEY = "zg0s72c6x54nxxn97qjxd8ooqzdlmzpc2t4ujzgo8rzl2ik7"
BIPPURL = "https://app.bipp.io"
content = % Q( < !DOCTYPE html >
   <
   html >
   <
   style >
   h1 {
     text - align: center;
   }
   div {
     text - align: center;
   } <
   /style> <
   body style = "background-color:powderblue;" >
   <
   script src = "https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js" > < /script> <
   script src = "https://unpkg.com/bipp" > < /script> <
   h1 > bipp Dynamic Embedding Demo(Ruby Server) < /h1><div id='container'></div >
   <
   script >
   const url = "%s";
   var w = window.innerWidth;
   var h = window.innerHeight;
   let config = {
     id: 'container',
     width: w,
     height: h,
     style: 'border:none;'
   }
   let bipp = new Bipp(); bipp.onmessage = (e) => {
     console.log("bipp Embedded SDK", e.data);
   }
   bipp.load(url, config); <
   /script> <
   /body> <
   /html>)
   def embed_url() url = URI("%s/app/v1/extapps/%s/embed/generate-link" % [BIPPURL, APPID]) http = Net::HTTP.new(url.host, url.port); request = Net::HTTP::Post.new(url) request["Accept"] = "application/json"
   request["Content-Type"] = "application/json"
   request["X-Org-ID"] = ORGID request["x-api-key"] = APIKEY request.body = JSON.dump({
     "id": "D~MhNWm__RM",
     "name": "Western Europe Happiness Index 2020"
     "domains": [
       "http://localhost:9193"
     ],
     "filters": [{
       "column": "Region",
       "comparator": "=",
       "table": "_2020",
       "value": "Western Europe",
       "logical_operator": "AND"
     }]
   }) response = http.request(request) return JSON.parse(response.read_body)['embed_url']
   end server = WEBrick::HTTPServer.new(Port: PORT, DocumentRoot: '.') server.mount_proc("/") do |request, response |
     response.status = 200 response.content_type = "text/html; charset=utf-8"
   response.body = content % [embed_url()] end trap 'INT'
   do server.shutdown end
   server.start