Embedding a Link with the SDK
Embedding a Link with the SDK
Once you have created an embed link you can add it to your registered external application using an iframe. The SDK includes a standalone javascript file (bipp.js) used by the external application to load the embeddable bipp dashboard.

Getting started with the SDK:
- Using SDK to load the dashboard
- Showing/hiding filter panel
- Determining the Dashboard Loaded
- Adding Filters
- Removing Filters
- Final HTML Example
Using SDK to load the dashboard
Below is a complete example, how you can embed a link into a webpage
<!DOCTYPE html>
<html>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/bipp"></script>
<div id='container'></div>
<script>
const url = "http://zwchaz.localhost:8080/embed/3d5e2483-71b9-42c4-b3fa-ab238eb70a58?id=14d9d31f-18e6-4876-bc2f-b4b047a4b9ff&cid=523a1c9464bc41639b33829bd4ad81e7.zwchaz.localhost&secret=seP9muK6w3CvoQQVpcA!j1S!qFoiQs72kCbu0BgDVwNXOU3l";
let config = { id : 'container', width: '1200px', height: '900px', style: 'border:none;' }
let bipp = new Bipp();
bipp.load(url, config);
</script>
</body>
</html>
This example code creates an iframe object and appends it in the container html element, url is the embed link created previously. Change the width and height of the iframe with config.
Showing/Hiding filter panel
Use config option filter_panel : true/false to show / hide the filter panel.
let config = { id : 'container', width, height, style: 'border:none;', filter_panel : false }
let bipp = new Bipp();
bipp.load(url, config);
Determining the Dashboard Loaded
You can set up a message to verify when the dashboard is fully loaded.
bipp.onmessage = (e) => {
console.log("message from embedded SDK", e.data);
// message from embedded SDK {source: "bippSDK", message: "ready"}
Adding Filters
You can add filters to the embedded dashboard.
bipp.addFilter(<filters>)
where filters
is an array of objects and each object represents a filter. A filter object has the following structure:
{
table,
column,
value,
params: {
mode
}
}
table
and column
are the underlying table name and column name
params
is an optional field.
mode
can have following values: IN, BETWEEN, <, >, <=, >=
value
is a string
If mode is IN
or BETWEEN
then value is an array of length two, containing two values.
Filter examples:
// single filter
filters = [{
table: 'trips',
column: 'payment_type',
value: 'CSH'
}];
// two filters
filters = [
{
table: 'trips',
column: 'payment_type',
value: 'CRD'
},
{
table: 'trips',
column: 'rate_code',
value: '34'
}
]
// filter mode = 'IN'
filters = [{
table: 'trips',
column: 'payment_type',
value: ['CSH', 'CRD'],
params: { mode: 'IN' }
}]
// filter mode = 'BETWEEN'
filters = [{
table: 'trips',
column: 'pickup_datetime',
value: ['2012-07-01', '2012-07-30'],
params: { mode: 'BETWEEN' }
}]
Removing Filters
To remove filters from the embedded dashboard, pass an array of filter objects. Each filter object requires two fields: table
and column
.
bipp.removeFilter(<filters>)
// Example
bipp.removeFilter(
[{
table: 'trips',
column: 'pickup_datetime'
}]
);
Final HTML Example
Here is an example:
<!DOCTYPE html>
<html>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/bipp"></script>
<div id='container'></div>
<script>
const url = "http://zwchaz.localhost:8080/embed/3d5e2483-71b9-42c4-b3fa-ab238eb70a58?id=14d9d31f-18e6-4876-bc2f-b4b047a4b9ff&cid=523a1c9464bc41639b33829bd4ad81e7.zwchaz.localhost&secret=seP9muK6w3CvoQQVpcA!j1S!qFoiQs72kCbu0BgDVwNXOU3l";
let config = { id : 'container', width: '1200px', height: '900px', style: 'border:none;' }
let bipp = new Bipp();
bipp.load(url, config);
</script>
</body>
</html>
Security
Embed link contains information which is required for login into the bipp server and once login is successful, the server returns an EmbedToken to the iframe. This embed token is used in all further communication between iframe and server. The embed token stores information like white listed domains, dashboard id and filters in encrypted form (AES 256) and can not be read by unauthorized persons.
Each embed link is associated with a website(s). So only websites which are white listed during embed link creation, can use that embed link. Any other website that tries to embed the link will get an authorization error.
Clients who want to write custom logic on server side and want to create embed links dynamically can do so by using bipp rest API, and can choose the dashboard and pass filters, choose domains while creating embed links. More about this is described in the next section.
Advance Usage
Bipp supports two modes of integration of embedded dashboards with your application:
- Static Embedding, where all users see the same dashboard data.
- Dynamic Embedding, where the embed links are custom generated as per the business logic. Using this mode, the users of your application sees only the data as defined by the embed link
In case of static embedding, you can directly embed Bipp dashboards in your existing application with the embed links using the code snippet shown in the previous section.
In case of dynamic embedding, you need to host a web application server where the generation of embed link, as per your business logic, is programmatically handled. Bipp provides a REST API endpoint which can be used to generate an embed link. This API requires the API Key of your registered application for authentication.
The REST API is described as below:
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"
}
]
}
More than one domain can be specified, separated by commas. Also, more than one filters can be specified and chained together through logical operators: AND
, OR
Comparator Operators can be one of "=", "<>", "<", ">", "<=", ">=", "BETWEEN", "IN", "LIKE", "NOT IN", "NOT BETWEEN", "STARTS WITH", "ENDS WITH", "IS NULL", "IS NOT NULL", "IS EMPTY", "IS NOT EMPTY"
On Success: 201 Created is returned with a response body 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"
}
On Failure, one of the following HTTP status codes is returned, along with the appropriate error message:
400 BadRequest
401 Unauthorized
402 PaymentRequired
403 Forbidden
500 InternalServerError
In next sections we will show how to do dynamic embedding with example code in different languages.
Node JS Example
Full code example for dynamic embedding using programmatic filtering in node JS. The code below runs a server at 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);
});
Golang Code Example
Full code example for dynamic embedding using programmatic filtering in Golang. The code below runs a server at 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))
}
Python Code Example
Full code example for dynamic embedding using programmatic filtering in Python. The code below runs a server at 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 Code Example
Full code example for dynamic embedding using programmatic filtering in Ruby. The code below runs a server at 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