What is a WebHook Out?
A WebHook Out (also known as outgoing WebHook) allows software systems to notify external applications as events happen in real-time.
How does a WebHook Out work?
When an Orca Scan user performs an action such as add, update or delete, Orca sends an HTTP POST with the data for that item in JSON format a URL you provide.
What information does Orca Scan send when I add, update or delete data?
Let’s say you’re tracking vehicles; you create a sheet named Vehicle Checks with VIN, Make, Model, Year, Location, Condition and Notes columns and share that sheet with members of your team.
When a teammate scans a barcode, enters the required information and taps save, the following data is saved to your sheet and sent to your URL. The ___orca_action
property will vary depending on the performed action.
{
"VIN": "4S3BMHB68B3286050",
"Make": "SUBARU",
"Model": "Legacy",
"Model Year": "2011",
"Condition": "Poor",
"Location": "52.2034823, 0.1235817",
"Notes": "Needs new tires",
"___orca_action": "add",
"___orca_sheet_name": "Vehicle Checks",
"___orca_user_email": "hidden@requires.https",
"___orca_row_id": "5cf5c1efc66a9681047a0f3d"
}
We include a few extra fields prefixed with ___orca_
to help you make sense of the event:
Key | Type | Description |
---|---|---|
___orca_row_id |
string | Unique row ID |
___orca_user_email |
string | The registered email address of the user who performed the action - requires an HTTPS connection |
___orca_action |
string | The type of action that was performed. Values include add, update, delete and test, import:append, import:replace, clear:column, clear:sheet |
___orca_sheet_name |
string | Name of the sheet |
What information does Orca Scan send when I import data?
If you import data into a sheet, the payload sent to your URL is slightly different. It will contain a nested rows property containing the row data that was imported. The ___orca_action
field will contain either import:append
or import:replace
depend on the Action selected during import.
{
"___orca_action": "import:replace",
"___orca_sheet_name": "Sheet1",
"___orca_user_email": "name@email.com",
"rows": [
{
"Barcode": "757483456",
"Name": "John",
"Location": "",
"Date": "",
"quantity": "1",
"___orca_row_id": "5cf5c1efc66a9681047a0f31"
},
{
"Barcode": "12537468",
"Name": "Owen",
"Location": "",
"Date": "",
"quantity": "2",
"___orca_row_id": "5cf5c1efc66a9681047a0f32"
},
{
"Barcode": "85636462",
"Name": "Rhys",
"Location": "",
"Date": "",
"quantity": "3",
"___orca_row_id": "5cf5c1efc66a9681047a0f33"
}
}
What information does Orca Scan send when I clear data?
If you clear a column, Orca Scan sends the following payload:
{
"___orca_action": "clear:column",
"___orca_sheet_name": "Sheet1",
"___orca_user_email": "name@email.com",
"___orca_column_name": "Name"
}
If you clear a sheet, Orca Scan sends the following payload:
{
"___orca_action": "clear:sheet",
"___orca_sheet_name": "Sheet1",
"___orca_user_email": "name@email.com"
}
HTTP Headers
The following HTTP headers are sent with every request:
Parameter | Description |
---|---|
orca-request-type |
webhook-out |
orca-secret |
Sheet assigned secret (check this to verify request) |
orca-sheet-id |
Unique ID of the Orca Scan sheet |
orca-sheet-name |
Name of the sheet |
orca-timestamp |
timestamp of the request in UNIX epoch format |
orca-user-email |
Email of user who triggered the request (requires HTTPS) |
How do I create a WebHook Out?
In order to be able to receive data from Orca Cloud on your system, you have to define an endpoint that accepts POST requests as in the following example snippets. The endpoint used for this example is /orca-webhook-out
so, make sure the URL contains this endpoint when adding it to Orca Cloud.
const express = require('express');
const app = express();
app.use(express.json());
app.post('/orca-webhook-out', function(request, response){
data = request.body;
// dubug purpose: show in console raw data received
console.log("Request received: \n"+JSON.stringify(data, null, 2));
// get the name of the action that triggered this request (add, update, delete, test)
const action = data.___orca_action
// get the name of the sheet this action impacts
const sheetName = data.___orca_sheet_name
// get the email of the user who preformed the action (empty if not HTTPS)
const userEmail = data.___orca_user_email
// orca system fields start with ___
// access the value of fields using the field name
// example: data.Name, data.Barcode, data.Location
switch (action) {
case "add":
// TODO: do something when a row has been added
break;
case "update":
// TODO: do something when a row has been updated
break;
case "delete":
// TODO: do something when a row has been deleted
break;
case "test":
// TODO: do something when the user in the web app hits the test button
break;
}
response.sendStatus(200);
});
app.listen(3000, () => console.log('Example app is listening on port 3000.'));
[HttpPost]
[Consumes("application/json")]
public async Task<OkResult> WebHookReceiver()
{
// WebHooks send data as a HTTP POST, so extract JSON string from Request.Body
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
// get the raw JSON string
string json = await reader.ReadToEndAsync();
// convert into .net object
dynamic data = JObject.Parse(json);
// get the name of the action that triggered this request (add, update, delete, test)
string action = (data.___orca_action != null) ? (string)data.___orca_action : "";
// get the name of the sheet this action impacts
string sheetName = (data.___orca_sheet_name != null) ? (string)data.___orca_sheet_name : "";
// get the email of the user who preformed the action (empty if not HTTPS)
string userEmail = (data.___orca_user_email != null) ? (string)data.___orca_user_email : "";
// orca system fields start with ___
// access the value of fields using the field name
// example: data.Name, data.Barcode, data.Location
// decide on what action to take based on orca action
switch (action) {
case "add": {
// TODO: do something when a row has been added
} break;
case "update": {
// TODO: do something when a row has been updated
} break;
case "delete": {
// TODO: do something when a row has been deleted
} break;
case "test": {
// TODO: do something when the user in the web app hits the test button
} break;
}
}
// always return a 200 (ok)
return new OkResult();
}
type OrcaBarcode struct {
Barcode string
Date string
Description string
Example string
Name string
Quantity int
___autofocus string
___autoselect string
___lastSchemaVersion string
___orca_action string
___orca_row_id string
___orca_sheet_name string
___orca_user_email string
___owner string
___schemaVersion string
}
func webHookOutHandler(w http.ResponseWriter, r *http.Request) {
// Read body
body, err := ioutil.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
fmt.Println(err)
http.Error(w, err.Error(), 500)
return
}
// Parse JSON data
var barcode OrcaBarcode
jsonErr := json.Unmarshal([]byte(body), &barcode)
if jsonErr != nil {
fmt.Println(jsonErr)
http.Error(w, jsonErr.Error(), 500)
return
}
// dubug purpose: show in console raw data received
fmt.Println(barcode)
// get the name of the action that triggered this request (add, update, delete, test)
action := barcode.___orca_action
// get the name of the sheet this action impacts
sheetName := barcode.___orca_sheet_name
fmt.Println(sheetName)
// get the email of the user who preformed the action (empty if not HTTPS)
userEmail := barcode.___orca_user_email
fmt.Println(userEmail)
// orca system fields start with ___
// access the value of fields using the field name
// example: data["Name"], data["Barcode"], data["Location"]
switch action {
case "add":
// TODO: do something when a row has been added
case "update":
// TODO: do something when a row has been updated
case "delete":
// TODO: do something when a row has been deleted
case "test":
// TODO: do something when the user in the web app hits the test button
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
return
}
@app.route('/orca-webhook-out', methods=['POST'])
def webhook_out():
if request.method == 'POST':
data = request.get_json()
# get the name of the action that triggered this request (add, update, delete, test)
action = data["___orca_action"]
# get the name of the sheet this action impacts
sheet_name = data["___orca_sheet_name"]
# get the email of the user who preformed the action (empty if not HTTPS)
user_email = data["___orca_user_email"]
# orca system fields start with ___
# access the value of fields using the field name
# example: data["Name"], data["Barcode"], data["Location"]
if action == "add":
# TODO: do something when a row has been added
pass
elif action == "update":
# TODO: do something when a row has been updated
pass
elif action == "delete":
# TODO: do something when a row has been deleted
pass
elif action == "test":
# TODO: do something when the user in the web app hits the test button
pass
# always return a 200 (ok)
return "ok"
if (preg_match('/orca-webhook-out$/', $_SERVER["REQUEST_URI"])){
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
// get the name of the action that triggered this request (add, update, delete, test)
$action = $data["___orca_action"];
// get the name of the sheet this action impacts
$sheetName = $data["___orca_sheet_name"];
// get the email of the user who preformed the action (empty if not HTTPS)
$userEmail = $data["___orca_user_email"];
// orca system fields start with ___
// access the value of fields using the field name
// example: data.Name, data.Barcode, data.Location
switch ($action) {
case "add":
// TODO: do something when a row has been added
break;
case "update":
// TODO: do something when a row has been updated
break;
case "delete":
// TODO: do something when a row has been deleted
break;
case "test":
// TODO: do something when the user in the web app hits the test button
break;
}
return 'ok';
}
}
@RequestMapping(
value = "/orca-webhook-out",
method = RequestMethod.POST)
String index(@RequestBody Map<String, Object> payload) throws Exception {
// dubug purpose: show in console raw data received
System.out.println(payload);
// get the name of the action that triggered this request (add, update, delete, test)
String action = payload.get("___orca_action").toString();
// get the name of the sheet this action impacts
String sheetName = payload.get("___orca_sheet_name").toString();
// get the email of the user who preformed the action (empty if not HTTPS)
String userEmail = payload.get("___orca_user_email").toString();
// orca system fields start with ___
// access the value of fields using the field name
// example: data.Name, data.Barcode, data.Location
switch (action) {
case "add":
// TODO: do something when a row has been added
break;
case "update":
// TODO: do something when a row has been updated
break;
case "delete":
// TODO: do something when a row has been deleted
break;
case "test":
// TODO: do something when the user in the web app hits the test button
break;
}
return "ok";
}
A fully working version for all programming languages can be found on GitHub.
How do I add a WebHook Out URL to my sheet?
You can add a WebHook Out URL to any Orca Scan sheet using the following steps:
1. Create a new sheet
Let’s start by creating a sheet named Vehicle Checks using the Vehicle Information template.
2. Edit Sheet Integrations
With the new sheet selected, open the Integration Settings from the toolbar.
3. Add your WebHook Out URL
Now enter the URL you would like to be called as your data changes.
Security
You can provide a secret that will be sent to your server as an HTTP header with every request, allowing you to determine if the incoming request is from Orca Scan.
4. Test your WebHook Out
You can test your WebHook Out URL by clicking the Test button, this will send test data for every column in your sheet, along with the ___orca_action
with the value of test
.
To test a WebHook Out without any development, you can use a free service such as RequestBin, simply copy the temporary URL to your sheet and hit test.
5. Save the changes
Finally, save your changes and you’re done. Now every time someone scans a barcode and makes a change, your system will know about it.
WebHook questions?
We’re happy to help troubleshoot any issues you might have connecting Orca Scan to your system, simply chat with us live or drop us an email.