Giter VIP home page Giter VIP logo

node-webhooks's Introduction

node-webhooks Build Status NPM Version Coverage Status JavaScript Style Guide Dependency Status Patreon donate button

What WebHooks are used for

Webhooks are "user-defined HTTP callbacks". They are usually triggered by some event, such as pushing code to a repository or a comment being posted to a blog. When that event occurs, the source site makes an HTTP request to the URI configured for the webhook. Users can configure them to cause events on one site to invoke behaviour on another. The action taken may be anything. Common uses are to trigger builds with continuous integration systems or to notify bug tracking systems. Since they use HTTP, they can be integrated into web services without adding new infrastructure.

Install

npm install node-webhooks --save

Supporting Node.js 0.12 or above.

How it works

When a webHook is triggered it will send an HTTPS POST request to the attached URLs, containing a JSON-serialized Update (the one specified when you call the trigger method).

Debug

This module makes use of the popular debug package. Use the env variable to enable debug: DEBUG=node-webhooks. To launch the example and enable debug: DEBUG=node-webhooks node example.js

Usage

// Initialize WebHooks module.
var WebHooks = require('node-webhooks')

// Initialize webhooks module from on-disk database
var webHooks = new WebHooks({
    db: './webHooksDB.json', // json file that store webhook URLs
    httpSuccessCodes: [200, 201, 202, 203, 204], //optional success http status codes
})

// Alternatively, initialize webhooks module with object; changes will only be
// made in-memory
webHooks = new WebHooks({
    db: {"addPost": ["http://localhost:9100/posts"]}, // just an example
})

// sync instantation - add a new webhook called 'shortname1'
webHooks.add('shortname1', 'http://127.0.0.1:9000/prova/other_url').then(function(){
	// done
}).catch(function(err){
	console.log(err)
})

// add another webHook
webHooks.add('shortname2', 'http://127.0.0.1:9000/prova2/').then(function(){
	// done
}).catch(function(err){
	console.log(err)
});

// remove a single url attached to the given shortname
// webHooks.remove('shortname3', 'http://127.0.0.1:9000/query/').catch(function(err){console.error(err);})

// if no url is provided, remove all the urls attached to the given shortname
// webHooks.remove('shortname3').catch(function(err){console.error(err);})

// trigger a specific webHook
webHooks.trigger('shortname1', {data: 123})
webHooks.trigger('shortname2', {data: 123456}, {header: 'header'}) // payload will be sent as POST request with JSON body (Content-Type: application/json) and custom header

Available events

We're using an event emitter library to expose request information on webHook trigger.

var webHooks = new WebHooks({
    db: WEBHOOKS_DB,
    DEBUG: true
})

var emitter = webHooks.getEmitter()

emitter.on('*.success', function (shortname, statusCode, body) {
    console.log('Success on trigger webHook' + shortname + 'with status code', statusCode, 'and body', body)
})

emitter.on('*.failure', function (shortname, statusCode, body) {
    console.error('Error on trigger webHook' + shortname + 'with status code', statusCode, 'and body', body)
})

This makes possible checking if a webHook trigger was successful or not getting request information such as status code or response body.

The format for the events is built as eventName.result. The choosen library eventemitter2 provides a lot of freedom for listening events. For example:

  • eventName.success
  • eventName.failure
  • eventName.*
  • *.success
  • *.*

API examples

webHooks are useful whenever you need to make sure that an external service get updates from your app. You can easily develop in your APP this kind of webHooks entry-points.

  • GET /api/webhook/get Return the whole webHook DB file.

  • GET /api/webhook/get/[WebHookShortname] Return the selected WebHook.

  • POST /api/webhook/add/[WebHookShortname] Add a new URL for the selected webHook. Requires JSON params:

  • GET /api/webhook/delete/[WebHookShortname] Remove all the urls attached to the selected webHook.

  • POST /api/webhook/delete/[WebHookShortname] Remove only one single url attached to the selected webHook. A json body with the url parameter is required: { "url": "http://..." }

  • POST /api/webhook/trigger/[WebHookShortname] Trigger a webHook. It requires a JSON body that will be turned over to the webHook URLs. You can also provide custom headers.

Author

Rocco Musolino - @roccomuso

node-webhooks's People

Contributors

eloquence avatar roccomuso avatar yss14 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-webhooks's Issues

Adicionar arquivo de tipagem do typescript

adicionar suporte ao typescript:

declare module 'node-webhooks' {
import type { EventEmitter2 } from 'eventemitter2';

interface WebHookOptions {
db: string | Record<string, string[]>;
httpSuccessCodes?: number[];
}

type WebHookCallback = (
shortname: string,
jsonData: any,
headersData?: Record<string, string>
) => void;

class WebHooks {
constructor(options: WebHookOptions);

trigger(shortname: string, jsonData: any, headersData?: Record<string, string>): void;

add(shortname: string, url: string): Promise<boolean>;

remove(shortname: string, url?: string): Promise<boolean>;

getDB(): Promise<Record<string, string[]>>;

getWebHook(shortname: string): Promise<string[]>;

getListeners(): Record<string, WebHookCallback>;

getEmitter(): EventEmitter2;

}

export = WebHooks;
}

how can i add webhoock in memory bd

hello i want to reset all the webhoock when the server is restarted. i'm trying to remove the db param but i get an error like this:

db Must be a String path

Standard JS & nsp

Improvement:

  • refactor to be standard-compliant.

CI Tests:

  • feross/standard.
  • nsp

Why it triggers several times, depends upon the number of URL

I was trying to call the webhooks.trigger('ticket_upsert', { data: "1" }) and setup the webhooks like this

const db =  {
        "ticket_upsert" : [
            "https://webhook.site/563f5326-da57-4a1b-ba3b-82686832694f", 
            "https://webhook.site/563f5326-da57-4a1b-ba3b-82686832694f", 
            "https://webhook.site/563f5326-da57-4a1b-ba3b-82686832694f"
        ]
    }

 const webHooks = new nodeWebHooks({ db })

The problem is the webhooks pushes 3times on the same URL, so like the first url "https://webhook.site/563f5326-da57-4a1b-ba3b-82686832694f", was called 3 times. I was triggerring it once. I'm expecting that it will call only once, for each URL

----update

i guess the problem lies on instantiate of new nodeWebHooks({ db }), i did instantiate it on my class constructor, and that class was called 3 times on several places. Disregard this issue, i was able to solve it

Why only accept http status 200?

Why does node-webhooks only fire the success event, if the response has a http status code of 200?
In my opinion at least 201 till 204 are also valid and common response codes.

Retry support

Would it be possible to add retries, i.e:

retries: 3
retryDelay: 30

If the returned status code is not one of httpSuccessCodes or a timeout, automatically retry the request using the above logic. Defaults to 0 retries.

Emitter or Webhook trigger no longer works

`
// Initialize webhook
const webHooks = new Webhooks({
db: './webHooksDB.json',
httpSuccessCodes: [200, 201, 202, 203, 204],
})

    // Encode key
    const base64Key = Buffer.from(`/vnf-agent/vpp1/config/generator/v1/template/${state.projectName}`).toString('base64')
    const base65Key = Buffer.from(`/vnf-agent/vpp1/config/generator/v1/project/${state.projectName}`).toString('base64')


    // Add webhook watcher onto etcd /template keys
    webHooks.add("etcd", 'http://localhost:2379/v3beta/watch')
    webHooks.add("project", 'http://0.0.0.0:2379/v3beta/watch')

    // Trigger webhook & send watch request
    webHooks.trigger("etcd", { key: base64Key })
    webHooks.trigger("project", { key: base65Key })

    // Shows emitted events
    const emitter = webHooks.getEmitter()
    emitter.on("*.success", (name, statusCode, response) => {
        console.log('SUCCESS triggering webHook ' + name + ' with status code', statusCode, 'and body', body)

        // Create object from string response
        const body = JSON.parse(response)

        // Decode value
        let value = body.kvs[0].value.toString()
        value = Buffer.from(value, 'base64')

        // Decode tar
        let buffer = JSON.parse(value)
        buffer = Buffer.from(buffer.tar_file, 'base64')

        // Displays code to frontend
        fs.appendFile('public/code.txt', buffer, function (err) {
            if (err) throw err;
            console.log('Saved!');
        });

        // Create tar folder
        fs.appendFile('public/template.tgz', buffer, function (err) {
            console.log('Saved!');
        });

    })`

We're using our webhook to grab a response for a specified key on ETCD. Everything was good and working properly, where all of a sudden for some reason the code stopped working. We were originally getting an error such as:

MaxListenersExceededWarning: (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

Where once we fixed this (by properly calling webhook.remove()), the error went away but the emitter does not pick up anything. We know the key is being properly inserted into ETCD, and the emitter was working properly, except now it doesn't work at all with no change to the code itself. Is there something you could think of that might have caused this? We even went into your source code and tried to set the webhooks.emitter = new EventEmitter2({ newListener: true, wildcard: true }) as we noticed EventEmitter2 for us had newListener set to false on default for some reason. Thanks!

Pluggable Storage Adapter

@roccomuso thanks for the package, I'm using this node-webhooks in multiple projects/companies from around 3+ years

Simplicity and minimalist design of the node-webhooks helped in wide and faster adoption.

as the application scales, the reliability of the webhook delivery becomes challenging. Migrating from node-webhooks will additional learning for all developers across company.

After so much research, I thought to discuss with node-webhooks contributors to build

  • storage adapter
    • subscriptions
    • ingestion/deliveries - in case of spike/failures
    • logs
  • UI for debugging
    • at production
    • while development

This requirement might not be in the code of this repo. but to discuss about overall integrations i created issue here

when there is no storage adapter is specified, automatically fallback to normal module

configurations should be there to tune based on use cases

for Persistence

  • MongoDB
  • MySQL/SQLite

for Messaging

  • SQS/RabbitMQ
  • Redis

For Logging

  • ElasticSearch

For Debugging

  • UI for Developer Debugging and Production failure retries

Research

Actions

Phase1:

Travis CI

  • code refactor.
  • write tests.
  • configure Travis CI.
  • add Travis badge on the README.md

webHook does not carry json payload

hi,
I'm trying using WebHooks to call a php rest on localhost when an alarm is triggered.
The WebHook calls the rest, but there is no json payload in the request. Here are the data about http headers catched by my php rest:

Content-Type:application/json
host:localhost
content-length:0
Connection:close

also the data readed by the following instructions:
$request_body = file_get_contents('php://input');
$data = json_decode($request_body);
results empty

Extend the persistence layer to support more DB

API Example

var WebHooks = require('node-webhooks')
var InMemory = require('webhooks-memory-storage')
var FileStorage = require('webhooks-file-storage')

var webHooks = new WebHooks({
    db: new InMemory(),  // in-memory DB
    //db: new FileStorage('./webHooksDB.json'), // json file that store webhook URLs
    // redis, mongoDB, lokiJS, levelDB etc.
});

WebHooks Storage Implementation

Every webHooks store must be an EventEmitter and implement specific methods. The following methods are the list of required, recommended, and optional.

  • Required methods are ones that this module will always call on the store.
  • Recommended methods are ones that this module will call on the store if available.
  • Optional methods are ones this module does not call at all, but helps present uniform stores to users.

Static DB

I am looking to implement webhook calls. I don't need a dynamic DB so I would not make use of add, etc. Therefor it would be great to be able to use a static DB, checked into revision control along the project. What is the json syntax of the current db? Is the syntax stable?

EDIT:

Ok, found it. Scrolled down too fast.

DB Structure Example:
{
	"shortname1": [url1, url2, ...],
	"shortname2": [url3, url4, ...],
	 ...
	 ...
	"shortnameX": [urlZ, ...]
}

Would be nice to be able to set this as plain object.

Error on trigger webHookshortname1with status code null and body null

    // Initialize WebHooks module.
    var WebHooks = require('node-webhooks')
    // Initialize webhooks module from on-disk database
    var webHooks = new WebHooks({
        db: './webHooksDB.json', // json file that store webhook URLs
        httpSuccessCodes: [200, 201, 202, 203, 204], //optional success http status codes
    })
    webHooks.add('test', 'http://127.0.0.1:9000/test').then(function(){
        // done
    }).catch(function(err){
        console.log(err)
    })

    var emitter = webHooks.getEmitter()
    
    emitter.on('*.success', function (shortname, statusCode, body) {
        console.log('Success on trigger webHook' + shortname + 'with status code', statusCode, 'and body', body)
    })
    
    emitter.on('*.failure', function (shortname, statusCode, body) {
        console.log(shortname)
        console.error('Error on trigger webHook' + shortname + 'with status code', statusCode, 'and body', body)
    })`

While trigger the webhook "let wb = webHooks.trigger('test', {data: 123456}, {header: 'header'})" got this error Error on trigger webHookshortname1with status code null and body null

Documentation needs improving.

The documentation is very brief, uninformative, and assumes the reader already has knowledge of many things mentioned.

Request: Add url interpolation feature

In my use case, I have a service that looks something like: POST /resource/:id
and I want to direct my webhook to that service based on the POST request body sent into the webhook. So if the POST to /my-webhook is { id: 'xyz' }, it directs to /resource/xyz.

See PR here: #22

Call GET Function

Correct me if m wrong, I saw that the function accepts only POST request.
I wonder if there is a way to specify URL method.

additional data on trigger event

hello i need to send a additional data on trigger event for use it after on succes event, for example:

webHooks.trigger(shortName, payloadData, additionalData);

emitter.on('*.success', (shortname, statusCode, body, additionalData)=> {
            //here i need to use the data that i send as parameter in the trigger event
           //how can i do that?
});

thanks

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.