A webhook in web development is a method of augmenting or altering the behavior of a web page, or web application, with custom callbacks. These callbacks may be maintained, modified, and managed by third-party users and developers who may not necessarily be affiliated with the originating website or application. The term \"webhook\" was coined by Jeff Lindsay in 2007 from the computer programming term hook.^[1]^
####### Introduction
In practical terms, a Webhook Event (also known as a webhook message) is a php object that contains information about something that's happened within the system. It could be that a booking was made, a guest created or a room updated. Each of these actions create a webhook event. During a run, several webhook events can be created.
The purpose is to package information in such a way that it can be sent off to remote services which may use that information. Perhaps the remote service could then use a REST API endpoint to retrieve information about a new guest or property, for example.
A Webhook Event
First, let's look at a basic Webhook Event
https://github.com/WoollyinWalesIT/bookyflow/blob/master/libraries/bookyflow/classes/bookyflow_properti es.class.php
Code often changes so the lines may be wrong, therefore I'll paste the code in here :
At the end of a run, if any Webhook Events exist then the webhook watcher processes them
https://github.com/WoollyinWalesIT/bookyflow/blob/master/core-minicomponents/j99994webhook_ watcher.class.php
Who can use Webhooks Events?
Plugins can use Webhook Events, for example the Beds24 plugin has a 07310 script, which is triggered by the webhook watcher above. It will look to see if the property is a Beds24 property and if so it will automatically set into motion steps to update Beds24 with the change (if appropriate).
Property managers can use Webhook Events to notify remote sites about a Webhook Event being triggered. To do that they have to create a new Webhook Integration in Frontend > Account Details > Webhooks. On this page they can save usernames and passwords of remote services that they want to send notifications to.
Only Property Managers can use Webhook Integrations. Super Property Managers cannot. This is because Webhook Integrations are associated with Property Manager accounts, not individual properties.
The reason why it\'s done this way is because webhook notifications are not necessarily done by any specific user, so setting up a tariff might be done by the property manager, whereas making a booking is done by a, potentially anonymous, user. As a result, typically actions are referenced against the property uid and not a property manager.
Webhook Integrations are linked to managers and not properties because it is the manager who has the relationship with the remote service. This allows a manager to create one Webhook Integrations for all of their properties, instead of one for each property.
When an action is performed, the manager for the property is found and any Webhook Event is triggered. Because super property managers do not have a relationship with any specific property, it is more difficult to find a manager for that property when triggering the event. In theory it would be possible to search for all super property manager\'s webhooks, however that would mean sending one webhook action/event to potentially many super managers and there\'s no telling what chaos could occur if that happened.
How can I use Webhook Events?
Remote services can take many forms. They can be your own server where you have created scripts that perform certain activities when they have been informed of something happening on your site, or they can be services like Zapier, which offers significant integrations to other tools such as Twitter, Slack, Facebook etc. So you could, for example, update a Slack chatroom when a new booking is added.
Different remote services will have different authentication and data requirements, therefore we provide 3 functional Webhook Integration plugins, plus a MailChimp plugin.
No Authentication
Basic Authentication
OAuth Authentication
These plugins will never cover all possible requirements that remote services may demand, however they provide enough functionality that you can build upon in case you need to connect to a service that has its own set of rules. You could copy or customise one of these existing webhook plugins to suit your own requirements.
####### Webhook Events List
Webhook Event blackbooking_added
Logs when black bookings are added.
File j02136saveblackbooking.class.php
BookyFlow Plugin black_bookings
Data Object Parameters
property_uid contract_uid
Webhook Event blackbooking_added
Logs when black bookings are added.
File j06001ajax_dashboard_save.class.php
BookyFlow Plugin black_bookings
Data Object Parameters
property_uid contract_uid
Webhook Event blackbooking_deleted
Logs when black bookings are deleted.
File j02138deleteblackbooking.class.php
BookyFlow Plugin black_bookings
Data Object Parameters
property_uid contract_uid
Webhook Event blackbooking_deleted
Logs when black bookings are deleted.
File j06001delete_multiple_blackbookings.class.php
BookyFlow Plugin black_bookings
Data Object Parameters
property_uid contract_uid
Webhook Event booking_added
Logs when a booking is added.
File j03020insertbooking.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid contract_uid
Webhook Event booking_cancelled
Logs when a booking is cancelled.
File bookyflow_generic_booking_cancel.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid contract_uid
Webhook Event booking_marked_noshow
Logs when a booking is marked as No Show.
File j06001mark_booking_noshow.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid contract_uid
Webhook Event booking_modified
Logs when a booking is modified.
File j03020insertbooking.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid contract_uid
Webhook Event booking_modified
Logs when a booking is modified.
File bookyflow_generic_booking_amend.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid contract_uid
Webhook Event booking_note_deleted
Logs when booking notes are deleted.
File j06001deletenote.class.php
BookyFlow Plugin [@webhook_event_plugin]
Data Object Parameters
contract_uid property_uid note_id
Webhook Event booking_note_saved
Logs when booking notes are added/edited.
File j06001savenote.class.php
BookyFlow Plugin core
Data Object Parameters
contract_uid property_uid note_id
Webhook Event booking_note_saved
Logs when booking notes are added/edited.
File functions.php
BookyFlow Plugin core
Data Object Parameters
contract_uid property_uid note_id
Webhook Event deposit_saved
Logs when deposit is added to a booking.
File j02202savedeposit.class.php
BookyFlow Plugin core
Data Object Parameters
contract_uid property_uid depositref
Webhook Event extra_deleted
Logs when optional extras are deleted.
File j02148deleteextra.class.php
BookyFlow Plugin optional_extras
Data Object Parameters
extras_uid
Webhook Event extra_saved
Logs when optional extras added/updated.
File j02146saveextra.class.php
BookyFlow Plugin optional_extras
Data Object Parameters
extras_uid
Webhook Event guest_checkedin
Logs when guests are checked in.
File j06001checkin.class.php
BookyFlow Plugin book_guest_in_out
Data Object Parameters
contract_uid property_uid
Webhook Event guest_checkedin_undone
Logs when guests checked in is undone.
File j06001undo_checkin.class.php
BookyFlow Plugin book_guest_in_out
Data Object Parameters
contract_uid property_uid
Webhook Event guest_checkedout
Logs when guests are checked out.
File j06001checkout.class.php
BookyFlow Plugin book_guest_in_out
Data Object Parameters
contract_uid property_uid
Webhook Event guest_checkedout_undone
Logs when guests checked out is undone.
File j06001undo_checkout.class.php
BookyFlow Plugin book_guest_in_out
Data Object Parameters
contract_uid property_uid
Webhook Event guest_deleted
Logs when a guest is deleted.
File j02226deleteguest.class.php
BookyFlow Plugin core
Data Object Parameters
guest_id property_uid
Webhook Event guest_saved
Logs when a guest\'s details are added/updated.
File j02224saveguest.class.php
BookyFlow Plugin core
Data Object Parameters
guest_id property_uid
Webhook Event guest_type_deleted
Logs when guest type deleted.
File jrportal_guest_types.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid guest_type_uid
Webhook Event guest_type_saved
Logs when guest types added.
File jrportal_guest_types.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid guest_type_uid
Webhook Event guest_type_saved
Logs when guest types updated.
File jrportal_guest_types.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid guest_type_uid
Webhook Event invoice_cancelled
Logs when an invoice is marked as cancelled.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event invoice_saved
Logs when an invoice is added.
File jrportal_invoice.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid invoice_uid
Webhook Event property_added
Logs when a property is added.
File bookyflow_properties.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_deleted
Logs when a property is deleted.
File j04910deleteproperty.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_published
Logs when a property is published.
File j02272publishprop.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_published
Logs when a property is published.
File bookyflow_suspensions.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_saved
Logs when a property is updated.
File bookyflow_properties.class.php
BookyFlow Plugin [@webhook_event_plugin]
Data Object Parameters
property_uid
Webhook Event property_settings_updated
Logs when property settings are updated.
File functions.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_unpublished
Logs when a property is unpublished.
File j02272publishprop.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event property_unpublished
Logs when a property is unpublished.
File bookyflow_suspensions.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event review_deleted
Logs when a review is added.
File bookyflow_reviews.class.php
BookyFlow Plugin core
Data Object Parameters
rating_id
Webhook Event review_published
Logs when a review is added.
File bookyflow_reviews.class.php
BookyFlow Plugin core
Data Object Parameters
rating_id
Webhook Event review_saved
Logs when a review is added.
File bookyflow_reviews.class.php
BookyFlow Plugin core
Data Object Parameters
rating_id
Webhook Event review_unpublished
Logs when a review is added.
File bookyflow_reviews.class.php
BookyFlow Plugin core
Data Object Parameters
rating_id
Webhook Event room_added
Logs when a room is added.
File jrportal_rooms.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid room_uid
Webhook Event room_deleted
Logs when a room is deleted.
File j06002delete_resource.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid room_uid
Webhook Event room_updated
Logs when a room is updated.
File jrportal_rooms.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid room_uid
Webhook Event room_updated
Logs when a room is deleted.
File jrportal_rooms.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid room_uid
Webhook Event rooms_multiple_added
Logs when multiple rooms may have been added. Because multiple rooms have been added, the remote service is advised to completely refresh their rooms list.
File j06002save_normalmode_tariffs.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event rooms_multiple_added
Logs when multiple rooms are added. Because multiple rooms have been added, the remote service is advised to completely refresh their rooms list.
File jrportal_rooms.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event tariff_cloned
Logs when tariffs updated.
File j06002save_clone_tariff.class.php
BookyFlow Plugin clone_tariffs
Data Object Parameters
property_uid
Webhook Event tariffs_updated
Logs when tariffs updated.
File j06002save_tariff_advanced.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event tariffs_updated
Logs when tariffs updated.
File j06002save_tariff_advanced.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
Webhook Event tariffs_updated
Logs when tariffs updated.
File j06002save_tariff_micromanage.class.php
BookyFlow Plugin advanced_micromanage_tariff_editing_modes
Data Object Parameters
property_uid
Webhook Event tariffs_updated
Logs when tariffs updated.
File j06002save_normalmode_tariffs.class.php
BookyFlow Plugin core
Data Object Parameters
property_uid
####### Creating Webhook Integration plugins
First I will introduce you to Webhook Integration plugins in BookyFlow.
Setup
To create a webhook integration that talks to a remote service you will need to install a webhook plugin before you can create a Webhook integration.
By default there are already several BookyFlow Webhook Integration plugins available through the plugin manager, feel free to download them to understand how they work.
{width="6.368042432195976in" height="4.07in"}
Install the Webhooks Authmethod Basic plugin now.
Visit the Property Manager\'s area in the frontend of your site. Once logged in you will see that you have a \"Webhooks\" option under the \"Account Details\" area of the BookyFlow Main Menu.
{width="5.479166666666667in" height="4.59375in"}
If you cannot see this option you may have disabled showing these options in the Site Configuration -> Misc tab, you will need to enable them first.
Webhooks page
Once you are on the Webhooks page, you can create new webhook integrations, delete existing Webhook integrations etc.
For most Webhook integration plugins you would need to provide a url and authentication information, however there can be exceptions. For example, BookyFlow uses webhook functionality to update Beds24 (the Channel Manager) when tariffs have been changed. The Beds24 plugin creates its own Webhook which only has a name, because the remote url and authentication functionality is hard coded in the Beds24 plugin itself.
In this example I have chosen \"Basic HTTP Authentication\" in the Authentication dropdown.
{width="5.677083333333333in" height="3.3958333333333335in"}
I have provided a hypothetical url, and the plugin then requests the username and password required.
Now click Save, and you\'re done. Every time one of the BookyFlow actions listed on the Webhook Methods is triggered, then the remote service will be informed about the action occuring in BookyFlow.
An Integration's code
Now that you've seen how a basic integration is set, you're ready to create your own Integration Plugin. The script in the basic Integration that is actually triggered by the webhook watcher is j07310watcher_authmethod_process_basic.class.php so you can use that as an example to work from.
If you haven\'t already, I would encourage you to read the Webhooks Introduction so that you have an idea of what a Webhook Integration plugin does. If you are interested in creating BookyFlow plugins in general, then a good place to start is the Hello World plugin example.
This page does not teach you to code. Instead it is designed to give you the basics of a Webhook plugin\'s structure so that experienced developers can quickly create their own plugins for sending information from BookyFlow installations to remote services when certain activities are performed.
As a result I will skip looking at the code itself. If you want to make your own webhook plugin I recommend that you install the \"Webhooks Authmethod None\" plugin in the BookyFlow Plugin Manager, then you can compare this guide to the files, and potentially use that plugin as a foundation for building your own code. It\'s released under the GPL so you are free to copy and adjust those files as needed.
Like almost all BookyFlow plugins, functionality is provided through Minicomponents. For a summary of the Minicomponent trigger numbers, see this page on Github.
{width="3.0833333333333335in"
height="1.3854166666666667in"}
There are 4 files in this plugin. You could of course create your own class files if needed, but they might not be required.
plugin_info.php
All BookyFlow should have a plugin info script. See the Hello World example for more information on them.
j00005webhooks_authmethod_none.class.php
This script is run whenever BookyFlow is run and it is used to include the language file in the
/language/ sub-directory. It isn't absolutely necessary, unless you plan to distribute the plugin to other BookyFlow users.
j07300webhooks_auth_method_none.class.php
This script is used to tell the webhook page that a certain webhook exists, and what language strings and settings it uses. This information is used both on the New Webhook page and when you change the Authentication Integration dropdown on that page.
j07310watcher_authmethod_process_none.class.php OR j07320watcher_authmethod_process_none.class.php
When an action is performed in BookyFlow, and BookyFlow finds that there is a Webhook Integration for that property\'s property manager, then the webhook handling is triggered, and the appropriate script is called to process the action.
This script is given the action\'s information and it\'s this script\'s responsibility to authenticate with the remote site, using the previously stored login information, and to send the body of the Webhook Event in whatever form that the remote service can use.
07310 scripts are processed immediately, whereas 07320 are treated as deferred tasks (more information below). Where possible I would strongly recommend that you use 07320 scripts. Debugging them is trickier but there is a shortcut (again, described below). This is because remote communications to other services might not be instantaneous and processing 07310 scripts could create a bottleneck whereas 07320 scripts do not.
####### Communication summary
Because a webhook\'s call to a remote service can be very time consuming, BookyFlow offers a 07320 trigger that communicates with remote services asynchronously. This allows the site visitor to continue doing something without needing to wait for the webhook to complete.
These tasks are then packaged up by the bookyflow_deferred_tasks class which writes a temporary file with the webhook\'s details to the temp data directory. Once that\'s done, then BookyFlow calls itself to tell itself that this new background task exists. The same bookyflow_deferred_tasks class will read in that file when BookyFlow receives the notification (j06000background_process.class.php) and triggers the 07320 that actually performs whatever the webhook is supposed to do.
Whilst this may seem a convoluted process, the reasoning for doing it is sensible. For example, when a tariff is updated in BookyFlow, a webhook is triggered to send the new pricing information to Beds24, if connected. Collecting and sending this information to Beds24 can take time and there\'s always a danger that the user could get frustrated while waiting for this to finish. When we use the background tasks method of calling ourselves then user activities continue as normal and the webhook tasks happen in an independent process that the user can\'t accidentally or deliberately prevent from completing.
This also means that arguably the webhook activities lag behind what the user has been doing, although typically only by a few seconds or so.
If you want to know if a webhook has been completed, check the Administrator > BookyFlow > Tools > Available logs > Webhooks.application.log. This should show you if and when the 07320 event was fired and any logging that you might create by adding the following to a webhook script :
logging::log_message(\"Blah blah was done\" , \'Webhooks\', \'DEBUG\' );
Debugging 07320 scripts
As a developer, you may find yourself needing to debug a webhook\'s 07320 script. Rather than having to constantly trigger a webhook by doing something, potentially time consuming in BookyFlow, there is a shortcut.
Let's assume that you have created a webhook plugin and have created the Webhook Integration in the BookyFlow frontend property manager\'s UI, you now want to test and or debug that the notification is going to the remote service.
First, put the site into Development mode (Administrator > BookyFlow > Settings > Site Configuration > Debugging tab). Once you have done that, the temporary files that are created and then deleted by the j06000background_process.class.php and bookyflow_deferrered_tasks scripts are not deleted after the webhook has been processed.
Next, perform the task that should trigger a webhook, for example create a booking, save a tariff etc.
Go to the Administrator > BookyFlow > Tools > Available logs > Core.application.log and in the search field you can enter something like this :
{width="2.78125in" height="0.3645833333333333in"}
When you do that you\'ll see a list of calls to the background_process script. An example might look something like
http://localhost:80/joomla_portal/index.php?option=com_bookyflow&no_html=1&jrajax=1&Itemid=1 03&lang=en&task=background_process&payload_source=GiJxalSBOqqkAlPGiUIgvhJQhgWno nOoSkxzNOtCUvVLOzkWBa
You can now copy that url into your browser\'s address bar to trigger the actual 07320 script without needing to laboriously create bookings, change tariffs etc.
If you want to see what was passed to the webhook 07320 script then look in
/bookyflow/temp/deferred_tasks for a file with the name of the payload source, eg
GiJxalSBOqqkAlPGiUIgvhJQhgWnonOoSkxzNOtCUvVLOzkWBa You can open that file in a text editor to see its contents.