GithubHelp home page GithubHelp logo

tarampampam / webhook-tester Goto Github PK

View Code? Open in Web Editor NEW
150.0 6.0 24.0 7.29 MB

๐Ÿ”ญ The powerful tool to test webhooks and not only

License: MIT License

Go 68.42% JavaScript 1.60% Vue 24.69% TypeScript 5.29%
webhook tests golang vuejs push-notifications tester websocket http testing testing-tool go

webhook-tester's Introduction

Logo

WebHook Tester

Release version Project language Build Status Release Status Coverage Image size License

This application allows you to test and debug Webhooks and HTTP requests using unique (random) URLs. You can customize the response code, content-type HTTP header, response content and set some delay for the HTTP responses. The main idea is viewed here.

screencast

This application is written in GoLang and works very fast. It comes with a tiny UI (written in Vue.js), which is built in the binary file, so you don't need any additional assets for the application using. Websockets are also used for incoming webhook notifications in the UI - you don't need any 3rd party solutions (like pusher.com) for this!

๐Ÿ”ฅ Features list

  • Liveness/readiness probes (routes /live and /ready respectively)
  • Can be started without any 3rd party dependencies
  • Metrics in prometheus format (route /metrics)
  • Built-in tiny and fast UI, based on vue.js
  • Multi-arch docker image, based on scratch
  • Unprivileged user in docker image is used
  • Well-tested and documented source code
  • Built-in CLI health check sub-command
  • Recorded request binary view using UI
  • JSON/human-readable logging formats
  • Customizable webhook responses
  • Built-in Websockets support
  • Low memory/cpu usage
  • Free and open-source
  • Ready to scale

๐Ÿ“ท Screenshots

Dashboard Request details Help screen Session options
dash request help new-session

๐Ÿ—ƒ Storage

At the moment 2 types of data storage are supported - memory and redis server (flag --storage-driver).

The memory driver is useful for fast local debugging when recorded requests will not be needed after the app stops. The Redis driver, on the contrary, stores all the data on the redis server, and the data will not be lost after the app restarts. When running multiple app instances (behind the load balancer), it is also necessary to use the redis driver.

๐Ÿ“ข Pub/sub

Publishing/subscribing are used to send notifications using WebSockets, and it also supports 2 types of driver - memory and redis server (flag --pubsub-driver).

For multiple app instances redis driver must be used.

๐Ÿงฉ Installation

Download the latest binary file for your arch (to run on macOS use the linux/arm64 platform) from the releases page. For example, let's install it on amd64 arch (e.g.: Debian, Ubuntu, etc):

$ curl -SsL -o ./webhook-tester https://github.com/tarampampam/webhook-tester/releases/latest/download/webhook-tester-linux-amd64
$ chmod +x ./webhook-tester

# optionally, install the binary file globally:
$ sudo install -g root -o root -t /usr/local/bin -v ./webhook-tester
$ rm ./webhook-tester
$ webhook-tester --help

Additionally, you can use the docker image:

Registry Image
GitHub Container Registry ghcr.io/tarampampam/webhook-tester
Docker Hub tarampampam/webhook-tester

Using the latest tag for the docker image is highly discouraged because of possible backward-incompatible changes during major upgrades. Please, use tags in X.Y.Z format

โš™ Usage

This application supports the following sub-commands:

Sub-command Description
serve Start HTTP server
healthcheck Health checker for the HTTP server (use case - docker healthcheck)

And global flags:

Flag Description
--version, -v Display application version
--verbose Verbose output
--debug Debug output
--log-json Logs in JSON format

๐Ÿ–ฅ HTTP server starting

serve sub-command allows to use next flags:

Flag Description Default value Environment variable
--listen, -l IP address to listen on 0.0.0.0 (all interfaces) LISTEN_ADDR
--port, -p TCP port number 8080 LISTEN_PORT or PORT
--create-session Create a session on server startup with this UUID (example: 00000000-0000-0000-0000-000000000000) CREATE_SESSION
--storage-driver Storage engine (memory or redis) memory STORAGE_DRIVER
--pubsub-driver Pub/Sub engine (memory or redis) memory PUBSUB_DRIVER
--redis-dsn Redis server DSN (required if storage or pub/sub driver is redis) redis://127.0.0.1:6379/0 REDIS_DSN
--ignore-header-prefix Ignore incoming webhook header prefix (case insensitive; example: X-Forwarded-) []
--max-request-body-size Maximal webhook request body size (in bytes; 0 = unlimited) 65536
--max-requests Maximum stored requests per session (max 65535) 128 MAX_REQUESTS
--session-ttl Session lifetime (examples: 48h, 1h30m) 168h SESSION_TTL
--ws-max-clients Maximal websocket clients (0 = unlimited) 0 WS_MAX_CLIENTS
--ws-max-lifetime Maximal single websocket lifetime (examples: 3h, 1h30m; 0 = unlimited) 0 WS_MAX_LIFETIME

Redis DSN format: redis://<user>:<password>@<host>:<port>/<db_number>

Server starting command example:

$ ./webhook-tester --log-json serve \
    --port 8080 \
    --storage-driver redis \
    --pubsub-driver redis \
    --redis-dsn redis://redis-host:6379/0 \
    --max-requests 512 \
    --ignore-header-prefix X-Forwarded- \
    --ignore-header-prefix X-Reverse-Proxy- \
    --create-session 00000000-0000-0000-0000-000000000000 \
    --ws-max-clients 30000 \
    --ws-max-lifetime 6h

After that you can navigate your browser to http://127.0.0.1:8080/ try to send your first HTTP request for the webhook-tester!

๐Ÿ‹ Using docker

Just execute in your terminal:

$ docker run --rm -p 8080:8080/tcp tarampampam/webhook-tester serve

Docker-compose

For running this app using docker-compose and if you want to keep the data after restarts, you can use the following example with a Redis server as a backend for the data:

version: '3.8'

volumes:
  redis-data: {}

services:
  webhook-tester:
    image: tarampampam/webhook-tester
    command: --log-json serve --port 8080 --storage-driver redis --pubsub-driver redis --redis-dsn redis://redis:6379/0
    ports: ['8080:8080/tcp'] # Open <http://127.0.0.1:8080>
    depends_on:
      redis: {condition: service_healthy}

  redis:
    image: redis:7-alpine
    volumes: [redis-data:/data:rw]
    ports: ['6379/tcp']
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 1s

Or you can use in-memory data storage only:

version: '3.8'

services:
  webhook-tester:
    image: tarampampam/webhook-tester
    command: serve --port 8080 --create-session 00000000-0000-0000-0000-000000000000
    ports: ['8080:8080/tcp'] # Open <http://127.0.0.1:8080/#/00000000-0000-0000-0000-000000000000>

Changes log

Release date Commits since latest release

Changes log can be found here.

Support

Issues Issues

If you find any package errors, please, make an issue in current repository.

License

This is open-sourced software licensed under the MIT License.

webhook-tester's People

Contributors

anhnguyenkim-agilityio avatar dependabot[bot] avatar hatamiarash7 avatar jetexe avatar renovate[bot] avatar tarampampam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

webhook-tester's Issues

Pretty print JSON request body

Currently, JSON request bodies (from a POST request, for example) are displayed in a single, horizontally scrollable code block (wraps by default on Safari).

Making use of JSON.stringify - or some other method - to pretty print JSON bodies in a more readable way would be a helpful improvement.

Thanks for the great project!

Config to init hooks

Hi,

First, thanks for that project, it works like a charm !
I've been looking for a self-hosted alternative to Pipedream/request-bin for a while without success, then by looking on webhook.site I found your project which is running great as a single docker image :)

I would like to suggest a feature to init some hooks endpoint from a config file.
Because when running the tester, URLs are self generated so we can't know automatically what the endpoint will be. So the point would be to have like a JSON or YAML config file with the list of named endpoint we want.

If not, is there a way to programmatically create an endpoint and get the endpoint URL as response ? (CLI or API)
edit: I've found I can call /api/session to create a new endpoint :)

Thanks.

Slow Loading multipart/form-data

When requests are multipart/form-data clicking on and off them is quite slow because the all the data is displayed. Would it be possible to have it only load when the user clicks on the Text or Binary buttons?

Question: Persist Webhook URL

Hi tarampampam,

First of all big thanks to this great project. It is really helpful to debug webhooks.

Currently, I have webhook-tester deployed in a docker-compose along the tools which send their webhooks to the webhook-tester.

When I take the docker-compose down and bring it up again i receive a new Webhook Url which I then need to reconfigure in the other tools. Is there a way to persist the Webhook Url from previous runs?

Thank you very much!

Provide local preservation support for CDN resources.

Suggestion

Some users who cannot connect to the Internet may not be able to use this program because they cannot get the CDN resources. Committing CDN resources to a git repository may not be an elegant way to handle this. A model that does not rely on CDNs is obviously more widely used.

Previously unsuitable PR: #147

Query params cause 404

When I make a request to a session and pass in query params a 404 is returned. I would expect them to be stored as part of the request and a 200 returned.

curl "https://127.0.0.1:8080/e808f6fc-ac62-46bc-a031-1da6302a5912?foo=bar"
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Error 404 - Not found</title>

  <style>
    body {
      background-color: #222;
      color: #aaa;
      font-family: 'Hack', monospace;
    }

    #error_text {
      position: absolute;
      top: 50%;
      left: 0;
      right: 0;
      text-align: center;
      margin-top: -35px;
      height: 30px;
      font-size: 2em;
    }
  </style>
</head>
<body>

<div id="error_text">Error 404: Not found</div>

<script>
  'use strict';

  const setCharAt = function (str, index, chr) {
    return (index > str.length - 1)
      ? str
      : str.substr(0, index) + chr + str.substr(index + 1);
  };

  const $errorText = document.getElementById('error_text');
  const text = $errorText.innerText;

  let progress = 0;

  const scrambleInterval = window.setInterval(() => {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=+<>,./?[{()}]!@#$%^&*~`\|'.split('');
    let message = text;

    for (let i = 0; i < text.length; i++) {
      if (i >= progress) {
        message = setCharAt(message, i, characters[Math.round(Math.random() * (characters.length - 1))]);
      }
    }

    $errorText.innerText = message;
  }, 800 / 60);

  window.setTimeout(() => {
    let revealInterval = window.setInterval(() => {
      if (progress < text.length) {
        progress++;
      } else {
        clearInterval(revealInterval);
        clearInterval(scrambleInterval);
      }
    }, 70);
  }, 500);
</script>
</body>
</html>

Central Panel Scrolling

When scrolling down the list of Requests in the sidebar, the main div scrolls as well and so after selecting the desired Request, you have to scroll all the way back up to actually see it.

Sidebar scrolling should be independent of the page scrolling.

Content-Type: text/xml not escaped

curl -X POST --location "https://web.hook.sh/$guid-here$" \
    -H "Content-Type: text/xml" \
    -d "<hello>world</hello>"

Shown as "world" (without tags)

Cannot open PDF sent as multipart/form-data

I'm sending a PDF file as multipart/form-data and when I click download, for some reason it saves it as a .bin. The contents look like a PDF but also happen to have the following at the start:

--b4baaa6a-3ea0-4490-9026-e81849d841d2
Content-Type: application/pdf
Content-Disposition: form-data; name="document"; filename="01234567891011_Confirmation_Signed.pdf"; filename*=utf-8''01234567891011_Confirmation_Signed.pdf

And this at the end:

--b4baaa6a-3ea0-4490-9026-e81849d841d2--

Even after removing those parts, the PDF cannot be opened. File attached as a .txt because it wouldn't let me upload a .bin.

Am I missing something here?

3a8e6dfa-2c93-4f67-af74-dc485f091998.txt

Add option to disable internal healthcheck in logs or configuring request logs

A lot of logs are generated by internal healthcheck requests. And basically, it looks like noise. Would be great to have an option to configure this behavior or options for configuring request logs.

{
    "level": "info",
    "ts": 1650000000.9604378,
    "msg": "HTTP request processed",
    "remote addr": "127.0.0.1",
    "useragent": "HealthChecker/internal",
    "method": "GET",
    "url": "/live",
    "status code": 200,
    "duration": 0.000026184
}

View recent sessions

Hi,

great tool. I use it for my tests but I am missing one feature. I great the sessions inside my tests and then delete it in the teardown. I would like to have a feature to view the latest session ids somewhere, so that I can jump into that without having to debug or log the session Id in my tests.

MAX_REQUESTS Environment Variable

Does setting a MAX_REQUESTS Environment Variable actually work? I have it set to 10000 but have noticed I only have the last 128 requests, which is the default amount

I've kept the Environment Variable as is and added --max-requests 10000 in the command, and now it stores more than 128.

I'm using the CREATE_SESSION Environment Variable and that works as expected so I don't think it is an issue with how the Environment Variables are picked up.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.