Webhook icon
Webhook
To automate your workflows, you need to sign an account first. It’s free.
Doc

This is an integration for making your flow function triggerable from webhooks in flows.network.

Code example

use webhook_flows::{create_endpoint, request_handler, send_response};

#[no_mangle]
#[tokio::main(flavor = "current_thread")]
pub async fn on_deploy() {
    create_endpoint().await;
}

#[request_handler]
async fn handler(_headers: Vec<(String, String)>, _subpath: String, _qry: HashMap<String, Value>, _body: Vec<u8>) {
    send_response(
        200,
        vec![(String::from("content-type"), String::from("text/html"))],
        "ok".as_bytes().to_vec(),
    );
}

When a request is received, the fn handler decorated by macro request_handler will be called. We get the headers, subpath, query and body then set the status, headers and body of the response using send_response.

You can set method as arguments of request_handler to specify which http method to reponse:

#[request_handler(GET, POST)]
async fn handler(_headers: Vec<(String, String)>, _subpath: String, _qry: HashMap<String, Value>, _body: Vec<u8>) {
    send_response(
        200,
        vec![(String::from("content-type"), String::from("text/html"))],
        "ok".as_bytes().to_vec(),
    );
}

In this case, request with methods other than GET and POST will receive METHOD_NOT_ALLOWED response. If no method has been speicified, all methods will be handled.

There is a route module for routing paths to different handler functions.

use webhook_flows::{
    create_endpoint, request_handler,
    route::{get, options, route, RouteError, Router},
    send_response,
};

#[request_handler]
async fn handler() {
    let mut router = Router::new();
    router
        .insert("/options", vec![options(opt)])
        .unwrap();

    router
        .insert(
            "/query/:city",
            vec![options(opt), get(query)],
        )
        .unwrap();

    if let Err(e) = route(router).await {
        match e {
            RouteError::NotFound => {
                send_response(404, vec![], b"No route matched".to_vec());
            }
            RouteError::MethodNotAllowed => {
                send_response(405, vec![], b"Method not allowed".to_vec());
            }
        }
    }
}

async fn opt(
    _headers: Vec<(String, String)>,
    _qry: HashMap<String, Value>,
    _body: Vec<u8>,
) {
    // send_response(...)
}

async fn query(
    _headers: Vec<(String, String)>,
    qry: HashMap<String, Value>,
    _body: Vec<u8>,
) {
    // Wildcard in the path will be set in the `qry`.
    let city =  qry.get("city");

    // send_response(...)
}

This time, we don't need any arguments in the fn handler decorated by macro request_handler. Instead we should construct a Router, fill it with pairs of path and (Vec<>, Handler), then call route on it. And In this circumstance, the handler fn would not receive the subpath argument.

The whole document is here.

Deployment

When your flow function has been deployed in Flows platform, you will see a section named Webhook Endpoint in your flow details. It will show a URL like https://code.flows.network/webhook/*** which is the entry for your webhook service.

You can also add one more /async/ level in the URL to make the function acting as async service. In this case, the URL should be looked like this: https://code.flows.network/webhook/async/***. It must be noted that webhook_flows::send_response has no effect to your async http request, and it will always response with code 204. In return you can make long running task in your function.