A Validation URL allows your system to inspect data entered from the Orca Scan mobile app before it is saved to your sheet. This not only allows you to reject invalid data, but also modify the data or provide meaningful feedback to the user about how to resolve an issue.
Suppose a user scans a QR Code containing an email address and enters some data. Orca Scan will HTTP POST the following JSON payload to your Validation URL:
{
"___orca_sheet_name": "Vehicle Checks",
"___orca_user_email": "hidden@requires.https",
"barcode": "hello@orcascan.com",
"notes": "Something important!"
}
If your system responds with a JSON object containing a title and message in the following format:
{
"title": "Try again",
"message": "Please provide more information"
}
That message will be present to the user within the app, preventing them from saving until the issue(s) are resolved.
Issues are considered resolved when your Validation URL returns an HTTP 200 response with no body. At that point, changes are applied to your sheet and the user is able to progress to the next task.
The following HTTP headers are sent with every request:
Parameter | Description |
---|---|
orca-request-type |
validation |
orca-secret |
Sheet assigned secret (check this to verify request) |
orca-sheet-id |
Unique ID of the Orca Scan sheet |
orca-sheet-name |
The name of the sheet making the request |
orca-timestamp |
UNIX epoch time of the request |
orca-user-email |
Email of user who triggered the request (requires HTTPS) |
You need to create an endpoint in your systems that accepts POST request. Once configured you will be able to control accept or reject data depending on your code. Check out the following example snippets.
const app = express();
app.use(express.json());
app.post('/', function(request, response){
data = request.body;
// dubug purpose: show in console raw data received
console.log("Request received: \n"+JSON.stringify(data, null, 2));
// orca system fields start with ___
// access the value of fields using field name
// example: data.Name, data.Barcode, data.Location
const name = data.Name
// validation example
if (name.length > 20) {
// return error message to show user
response.json({
"title": "Invalid Name",
"message": "Name cannot contain more than 20 characters",
}).send();
return;
}
// return HTTP Status 204 (no content)
response.status(204).send();
});
app.listen(3000, () => console.log('Example app is listening on port 3000.'));
[ApiController]
[Route("/")]
public class OrcaValidationDotNet : ControllerBase
{
[HttpPost]
[Consumes("application/json")]
public async Task<ActionResult> validationReceiver()
{
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);
// orca system fields start with ___
// access the value of fields using field name
// example: data.Name, data.Barcode, data.Location
string name = (data.Name != null) ? (string) data.Name : "";
// validation example
if (name.Length > 20) {
// return error message to show user
return Ok(new {
title = "Name is too long",
message = "Name cannot contain more than 20 characters"
});
}
}
// return HTTP Status 204 (no content)
return NoContent();
}
}
func validationHandler(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)
// orca system fields start with ___
// access the value of fields using field name
// example: data.Name, data.Barcode, data.Location
name := barcode.Name
// validation example
if (len(name) > 20) {
// return error message to show user
w.Write([]byte(`{
"title": "Invalid Name",
"message": "Name must be less than 20 characters"}
`))
return
}
// return HTTP Status 204 (no content)
w.WriteHeader(204)
}
@app.route('/', methods=['POST'])
def orca_validation():
if request.method == 'POST':
data = request.get_json()
# dubug purpose: show in console raw data received
print("Request received: \n"+json.dumps(data, sort_keys=True, indent=4))
# orca system fields start with ___
# access the value of fields using field name
# example: data["Barcode"], data["Location"]
name = data["Name"]
# validation example
if(len(name) > 20):
# return error message to show user
return json.dumps({
"title": "Invalid Name",
"message": "Name cannot contain more than 20 characters",
})
# return HTTP Status 204 (no content)
return '', 204
if (preg_match('/$/', $_SERVER["REQUEST_URI"])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
// orca system fields start with ___
// access the value of fields using field name
// example: data.Name, data.Barcode, data.Location
$name = $data["Name"];
// validation example
if (strlen($name) < 20) {
// return error message to show user
echo json_encode(array(
"title" => "Invalid Name",
"message" => "Name cannot contain more than 20 characters"
));
exit;
}
// return HTTP Status 204 (No Content)
http_response_code(204);
exit;
}
}
@RequestMapping(
value = "/",
method = RequestMethod.POST)
String index(@RequestBody Map<String, Object> data) throws Exception {
// dubug purpose: show in console raw data received
System.out.println(data);
// orca system fields start with ___
// access the value of fields using field name
// example: data.get("Barcode"), data.get("Location")
String name = data.get("Name").toString();
// validation example
if (name.length() > 20) {
// return error message to show user
JSONObject json = new JSONObject();
json.put("title", "Invalid Name");
json.put("message", "Name cannot contain more than 20 characters");
return json.toJSONString();
}
// return HTTP Status 204 (no content)
return "";
}
A fully working version for all programming languages can be found on GitHub.
A Validation URL can only be set on sheets created at cloud.orcascan.com. To add a Validation URL, select the sheet you would like to validate, then open the Integration Settings.
Now enter the Validation URL you would like Orca Scan to call as items are updated. Please note: this URL must be publicly accessible.
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.
You can now test the Validation URL by clicking the Test button. This will HTTP POST a JSON object to your server containing randomly generated data and display the result.
To test an error, simply have your endpoint return a JSON object containing a title and message and hit test again.
Finally, save the changes and you’re done. You can now select that sheet in the Orca Scan mobile app and test it.
We’re happy to help you get up and running, chat with us live or drop us an email.