Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

How does the webhook work?

Table of Contents

Webhook flow

Step 1: endpoint

Some endpoint use the webhook concept, especially endpoint that have a duration longer than 500ms. e.g. For example the endpoint: /backup/owner

Step 2: flow

  1. Post to the endpoint
    supply a return webhook_url, this URL must be public accessible
    URL must start with HTTPS

  2. After the long process is ready
    The webhook_url will be called from the Autoflex10 server with a get
    An id=<secret uuid> will be added to your supplied webhook_url

  3. Do a GET on the /webhook endpoint, to get the payload information e.g. an URL to a download file
    supply the <secret uuid> you got from the webhook call
    This endpoint will return the payload, mostly an URL

  4. Get the provided payload URL, in case of an file url, download the file with a GET on the URL.

Sample code

Below sample code in a single contained file. The code itself is TypeScript.

...

  1. Copy and Paste sample into a new TS file, name it: webhook_test.ts 

  2. Install Deno, see: https://deno.land/

  3. Supply, api_key, username and password (line 9, 10 & 11)

  4. Start ngrok, see: https://ngrok.com/download

  5. Supply ngrok, https url (line 17)

  6. Run this code: deno run --allow-net webhook_test.ts

  7. Check the output

Deno - Typescript sample to use webhook
Code Block
languagejs
// Af10 REST/API test script
// How to: Start ngrok, see belown, add needed info, start this script
// deno run --allow-net webhook_test.ts

import { soxa } from 'https://deno.land/x/soxa/mod.ts';
import { listenAndServe, ServerRequest } from "https://deno.land/std/http/server.ts";

// Needed for authentication
const api_key: string = '<your api_key>'
const username: string = '<username>';
const password: string = '<password>';

let url = 'https://www.autoflex10.dev/autoflex/servoy-service/velocity/webservice_v2'

// 1: Start ngrok, 2: paste ngrok URL on let callback = '...' 3: run script
// ngrok http --region eu 8855
let callback = 'https://<your_ngrok_id>.eu.ngrok.io'

// Token for Af10 REST/API
let token = await getToken();

// Call GET /authenticate, with parameters
async function getToken() {
  const config = {
    params: {
      api_key,
      username,
      password
    }
  }
  console.log('GET /authenticate');
  const result = await soxa.get(`${url}/authenticate`, config);
  if (result.status == 200) {
    if (result.data?.token) {
      console.log(result.data);
      return result.data?.token;
    }
  }
}

// Call POST /backup/owner, with the required params
async function postOwnerBackup() {
  console.log('POST /backup/owner');
  soxa.post(`${url}/backup/owner`, { webhook_url: callback }, {
    headers: {
      token
    }
  }).then(async (res) => {
    if (res.status === 202) {  // 202, request not yet finished
      listenAndServe
      const options = { port: 8855 };
      listenAndServe(options, async (req: ServerRequest) => {
        req.respond({});
        const secret = req.url.split('=')[1];
        console.log(`Callback received with secret-id: ${secret}`);
        getSecret(secret);
      });
      //Start server to get the callback
    }
    if (res.data.successCode == 202) {
      console.log(res.data);
      console.log('Waiting for webhook call...');
    }
  }).catch((err) => {
    console.log('error:', err)
  })
}

// Call GET /webhook with secret
async function getSecret(secret: string) {
  const result = await soxa.get(`${url}/webhook`, {
    headers: {
      token
    }, params: { id: secret }
  });
  if (result.status === 200) {
    if (result.data?.data?.url)
    console.log(`The secret url: ${result.data?.data?.url}`);
    Deno.exit()
  }
}

// Start this show!
postOwnerBackup();

...

Filter by label (Content by label)
showLabelsfalse
max10
sortmodified
showSpacefalse
reversetrue
cqllabel = "autoflex10apiautoflex10" and space = currentSpace ( )"API"