Skip to main content

How to Build and Deploy a Webhook Service for Streams

Updated on
Jul 31, 2024

Overview

In this guide, we'll show you how to build and deploy a webhook service for receiving data from QuickNode Streams using various programming languages. Whether you're using Node.js, Python, Ruby, PHP, Java, Go, Rust, we've got you covered with step-by-step instructions.

With these examples, you can set up a webhook server in your preferred language, install the necessary dependencies, run the server, and expose it to the internet using ngrok. This will enable you to start receiving data from QuickNode Streams seamlessly.

What You Will Need


Table of Contents

Node.js (Express)

Setup Environment and Install Dependencies

mkdir nodejs-webhook
cd nodejs-webhook
npm init -y
npm install express body-parser

Create server.js

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

app.post('/webhook', (req, res) => {
console.log('Received webhook:', req.body);
res.status(200).send('Webhook received');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

Run the webhook

node server.js

Expose to the Internet

Use ngrok:

ngrok http 3000

Go (Gin)

Setup Environment and Install Dependencies

mkdir go-webhook
cd go-webhook
go mod init go-webhook
go get github.com/gin-gonic/gin

Create main.go

package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)

func main() {
r := gin.Default()
r.POST("/webhook", func(c *gin.Context) {
var json map[string]interface{}
if err := c.BindJSON(&json); err == nil {
fmt.Println("Received webhook:", json)
c.String(http.StatusOK, "Webhook received")
} else {
c.String(http.StatusBadRequest, "Bad request")
}
})
r.Run(":8080")
}

Run the Webhook

go run main.go

Expose to the Internet

Use ngrok:

ngrok http 8080

Python (Flask)

Setup Environment and Install Dependencies

mkdir python-webhook
cd python-webhook
python3 -m venv venv
source venv/bin/activate
pip install flask

Create app.py

from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
data = request.json
print('Received webhook:', data)
return 'Webhook received', 200

if __name__ == '__main__':
app.run(port=5000)

Run the webhook

node app.py

Expose to the Internet

Use ngrok:

ngrok http 5000

Ruby (Sinatra)

Setup Environment and Install Dependencies

mkdir ruby-webhook
cd ruby-webhook
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'sinatra'" >> Gemfile
bundle install

Create app.rb

require 'sinatra'
require 'json'

post '/webhook' do
request.body.rewind
payload = JSON.parse(request.body.read)
puts "Received webhook: #{payload}"
status 200
body 'Webhook received'
end

Run the Webhook

ruby app.rb -p 4567

Expose to the Internet

Use ngrok:

ngrok http 4567

PHP

Setup Environment and Run Webhook

mkdir php-webhook
cd php-webhook
echo "<?php
\$input = file_get_contents('php://input');
\$data = json_decode(\$input, true);
error_log('Received webhook: ' . print_r(\$data, true));
http_response_code(200);
echo 'Webhook received';
?>" > webhook.php
php -S localhost:8000

Expose to the Internet

Use ngrok:

ngrok http 8000

Java (Spring Boot)

Setup Environment and Install Dependencies

mkdir java-webhook
cd java-webhook
curl https://start.spring.io/starter.zip -d dependencies=web -d name=webhook -d packageName=com.example.webhook -o webhook.zip
unzip webhook.zip
cd webhook

Create WebhookController.java

package com.example.webhook;

import org.springframework.web.bind.annotation.*;

@RestController
public class WebhookController {

@PostMapping("/webhook")
public String handleWebhook(@RequestBody String payload) {
System.out.println("Received webhook: " + payload);
return "Webhook received";
}
}

Run the Webhook

./mvnw spring-boot:run

Expose to the Internet

Use ngrok:

ngrok http 8080

Rust (Actix-web)

Setup Environment and Install Dependencies

cargo new rust-webhook
cd rust-webhook

Add dependencies to Cargo.toml

[dependencies]
actix-web = "4.0.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Create src/main.rs

use actix_web::{post, web, App, HttpServer, Responder};
use serde::Deserialize;

#[derive(Deserialize)]
struct WebhookPayload {
// Define the expected fields in the payload
}

#[post("/webhook")]
async fn webhook(payload: web::Json<WebhookPayload>) -> impl Responder {
println!("Received webhook: {:?}", payload);
"Webhook received"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(webhook)
})
.bind("0.0.0.0:8080")?
.run()
.await
}

Run the Webhook

cargo run

Expose to the Internet

Use ngrok:

ngrok http 8000

More resources


We ❤️ Feedback!

If you have any feedback or questions about this documentation, let us know. We'd love to hear from you!

Also, check out the QuickNode Forum for more resources. Stay up to date with the latest by following us on Twitter (@QuickNode) or Discord.

Share this doc