Hur webhooks fungerar i HireHop

HireHop kan skicka ett meddelande med data till andra appar när vissa händelser utlöses inom HireHop. Detta meddelande kallas en webhook som automatiskt skickar relevant data till önskad plats.

WbhooksVad är en webhook?

En webhook skickar/skjuter ett meddelande, med data bifogad till meddelandet, när specifika saker händer i HireHop (en händelse). Webhooks skickas via HTTP (anropar en webbadress) och är ett sätt att skicka data till andra applikationer i realtid. Webhooks levererar relevant data till specifika applikationer när det händer, vilket innebär att den mottagande applikationen får data omedelbart efter händelsen inträffar, vilket är mycket effektivare och snabbare än polling efter dataändringar.

HireHop webhooks kan användas för att kommunicera direkt med andra appar eller skickas till en anslutning som Zapier, som kan göras för att formatera data och göra alla nödvändiga API-anrop tillbaka till HireHop eller till en annan applikation.

Konfigurera en webhook

I HireHop, gå till ”Inställningar” och klicka sedan på fliken ”Företagsinställningar” och knappen ”Webhooks” högst upp på sidan. I popup-fönstret, klicka på knappen ”Ny” och lägg till URL:en dit webhookmeddelandet ska skickas till och välj varje webhook som du vill att URL:en ska svara på. Du kan lägga till så många webhooks som du vill, men bör begränsa dem till endast de nödvändiga som den specifika webbadressen kommer att svara på.

En HireHop webhook kommer att POSTA data till din URL-slutpunkt som JSON, och kommer att innehålla följande eller liknande data.

{
    "time": "2022-03-29 07:50:42",
    "user_id": 1,
    "user_name": "John Smith",
    "user_email": "john@email.com",
    "company_id": 1,
    "export_key": "22u43mrjwe7u",
    "event": "invoice.status.updated",
    "data": { ... },
    "changes": {
        "FIELD_NAME": {
            "from": "gammal",
            "to": "ny"
        }, ...
    }
}

I JSON-exemplet ovan är följande fält:

  • time” är UTC-tiden och datumet då webhook skickades.
  • user_id” är ID för användaren som orsakade att händelsen utlöstes.
  • user_name” är deras användarnamn.
  • company_id”-fältet är den unika nummeridentifieraren för företaget som användaren arbetar för.
  • export_key” är värdet på exportnyckeln i företagsinställningar som kan användas som en säkerhetskontroll.
  • event” är namnet på webhook-händelsen som utlöstes.
  • data” är den data som hör till webhook-händelsen.
  • changes” är de fält som förändrats, vilket är vad de var till vad de ändrades till.

HireHop kommer inte att vänta på ett svar från den anropade URL:en eller rapportera ett HTTP-fel från att anropa den.

Exempel på PHP-kod för en URL-slutpunkt för att fånga webhook-data skulle vara:

<?php
	// Hämta JSON-data
	$postdata = file_get_contents('php://input');
	// Konvertera JSON-data till ett objekt
	$data_str = json_decode($postdata);
?>

 

Posted in API

HireHop Rest API – Komma igång -guide

HireHop är byggt ovanpå ett API, vilket betyder att allt du ser HireHop göra kan du också åstadkomma med hjälp av det omfattande API: et. Allt du behöver för att komma åt Rest API är en användartoken som tillämpas som GET eller POST på den relevanta URL -slutpunkten.

API -Tokens

För att generera en API -token, gå till sidan ”Inställningar” och välj fliken ”Användare”. Välj eller skapa en användare, medan den specifika användaren väljs, klicka på ”Meny” -knappen och sedan på ”API -token” -alternativet för att generera en token. Token visas sedan och kan kopieras till Urklipp med kopieringsknappen.

Token blir ogiltig om du ändrar e -postadressen eller lösenordet för vald användare, eller om du sedan loggar in på den användaren. För att förhindra att detta händer bör du skapa en dedikerad API -användare och för säkerhets skull ge den relevanta behörigheter och därmed begränsa den från allt du inte kommer att använda API för.

Av säkerhetsskäl bör du inte använda token i front -end JavaScript -kod, den ska endast användas på serversidan, som om en hacker erhåller token kan de ändra och få tillgång till dina data på HireHop, så håll din token hemlig. Om din token läcker, ändra bara lösenordet för API -användaren och generera en ny token.

Använda en Token

En token bör anges som en GET- eller POST -parameter som kallas ”token”. Till exempel, för att ladda jobbdata för jobbnummer 52, anropar HireHop API -slutpunkten:

https://myhirehop.com/php_functions/job_refresh.php?job=52

Om du vill ringa samma slutpunkt med hjälp av en token skulle URL: en vara:

https://myhirehop.com/php_functions/job_refresh.php?job=52&token=dqwejk5GVT65909bHHBN7922pq5hxjm%207hmn

Kom ihåg att när du skickar token via GET (en URL -parameter som ovan) måste du koda token först med ett verktyg som https://meyerweb.com/eric/tools/dencoder.

Lägg upp Data

För att skapa eller redigera data i HireHop måste du använda en POST. När du postar data bör du bara ställa in de fält som du vill ändra, till exempel för att skapa eller redigera ett jobb med hjälp av slutpunkten https://myhirehop.com/php_functions/job_save.php och ställa in parametern ”jobb” till ”0 ”eller om det utelämnas skapas ett nytt jobb, allt annat redigerar det relevanta jobbnumret. Så för att redigera företagsnamnet i jobbnummer 52 bör postdata vara:

{
"job" : 52,
"name" : "New Name",
"token" : "dqwejk5GVT65909bHHBN7922pq5hxjm=-7hmn"
}

API-slutpunkter

Många API-slutpunkter är dokumenterade i API-dokumentationen, med många fler att följa.  För att fastställa slutpunkten för en uppgift i HireHop -appen, använd webbläsarkonsolen för att inspektera nätverkssamtalen och vilka parametrar som ställs in. En omfattande guide till URL -slutpunkter kommer snart att publiceras.

Prisgränser

HireHop tillåter varje användare 60 anslutningsförfrågningar inom en 1 minuts period. Om det finns fler än 60, returneras felet ”Säkerhetsvarning, för många transaktioner” (327).

Posted in API

Cross Domain-teckensnitt CORS – CSS-typsnitt laddas inte

Många användare har skapat några fantastiska dokument för användning i HireHop genom att använda HTML5, JavaScript och CSS-funktionalitet. För dessa dokument behöver användare ibland ett speciellt teckensnitt som de lagrar på sin server, men ibland verkar inte teckensnittet fungera i HireHop-dokumentet. Anledningen till detta är på grund av begränsningar av ursprungsresursdelning (CORS) i webbläsare.

Typsnitt som Inte Laddas in i Dokument

De flesta webbläsare tillåter inte förfrågningar över domäner, det beror på samma säkerhetspolicy för ursprung. Detta innebär att ibland kan du göra fel när du använder webb-teckensnitt från en annan domän och teckensnittet inte laddas i webbläsaren eller i HireHop-dokument.

<style type="text/css">
@font-face {
    font-family: 'OpenSans';
    src: url('https://my_server.com/fonts/OpenSans.woff2') format('woff2');
}
html, body{
    font: normal 16px OpenSans, sans-serif;
}
</style>

Lösningen

För att fixa begränsningar för ursprungsgränser för dina teckensnitt måste svaret från fjärrservern som är värd för teckensnittsfilerna innehålla huvudet Access-Control-Allow-Origin.

Om du använder teckensnittstjänster som Typekit eller Google Fonts, eller kanske innehållsleveransnätverk som BootstrapCDN, CdnJS eller JsDelivr för att ladda dina önskade teckensnitt behöver du inte göra någonting eftersom huvudet Access-Control-Allow-Origin är redan skickat in sitt svarhuvud.

Apache

Om du vill konfigurera en Apache-webbserver sätter du följande kod i filen httpd.conf eller .htaccess.

  1. Lägg till rubriker av MIME-typ på Apache:
    AddType application/vnd.ms-fontobject    .eot
    AddType application/x-font-opentype      .otf
    AddType image/svg+xml                    .svg
    AddType application/x-font-ttf           .ttf
    AddType application/font-woff            .woff
    AddType application/font-woff2           .woff2
    
  2. Aktivera resursdelning mellan ursprung (CORS) på Apache för mimtyperna:
    <IfModule mod_headers.c>
      <FilesMatch ".(eot|otf|svg|ttf|woff|woff2?)$">
        Header set Access-Control-Allow-Origin "*"
      </FilesMatch>
    </IfModule>
    

NGINX

För att konfigurera en NGINX-webbserver, lägger du följande kod i /etc/nginx/nginx.conf eller din anpassade /etc/nginx/conf.d/custom.conf-fil.

  1. Lägg till rubriker av typen MIME på NGINX:
    application/vnd.ms-fontobject    eot;
    application/x-font-opentype      otf;
    image/svg+xml                    svg;
    application/x-font-ttf           ttf;
    application/font-woff            woff;
    application/font-woff2           woff2;
    
  2. Aktivera resursdelning mellan ursprung (CORS) på NGINX för MIME-typerna:
    location ~* .(eot|otf|svg|ttf|woff|woff2)$ {
        add_header Access-Control-Allow-Origin *;
    }
    

IIS

För att konfigurera Microsoft IIS lägger du till följande kod i web.config system.webServer-filen.

  • Aktivera resursdelning mellan ursprung (CORS) på IIS
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="access-control-allow-origin" value="*" />
          <add name="access-control-allow-headers" value="content-type" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
    

PHP

Om du inte kan ändra serverinställningarna kan du alltid använda PHP för att leverera teckensnittfilen.

  • Använd en serverskriptfil istället för en fysisk typsnittsfil
    <style type="text/css">
    @font-face {
        font-family: 'OpenSans';
        src: url('https://my_server.com/fonts/OpenSans.php') format('woff2');
    }
    html, body{
        font: normal 16px OpenSans, sans-serif;
    }
    </style>
    
  • Hur du åtgärdar problem mellan domäner @font-face med PHP
    <?php
    // fonts.php
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/font-woff2');
    echo @file_get_contents('/fonts/OpenSans.woff2');
    ?>
    
Posted in API

Customisation & Customising Widgets – HireHop API NoHTML Framework

HireHop is completely customisable, you can even add custom fields, all done using the HireHop JavaScript injection method, in which JavaScript files that you have written are inserted into HireHop pages.  If you look at the page source of a HireHop page, you will see <!– PLUGINS –>, it is after here where the JavaScript for your plugins will be inserted.

HireHop has been built from the ground up, developing our own framework that we call NoHTML, amalgamating existing technology and methodology to produce a framework that is easy to use, extendable and enables fast page loading, even on slow internet connections.

Apart from the main part of the page, the main parts of HireHop are dynamically built on the client machine using JavaScript and jQuery widgets, similar to REACT and JSX, but more simple and of course using the familiar jQuery framework.  For instance, if you load a Job page and inspect the page (press F12 for the browser’s object inspector), you will see a <div> element at the bottom of the page structured like so:

<div id=”notes_tab”></div>

As you can see the above <div> is just an empty div element. If you click on the ”Notes” tab, suddenly the above element is populated with elements.  Looking at your browser’s inspector you will also notice that the only data loaded from the server was some JSON and not the code in the notes tab.  The notes tab was built dynamically on the client machine using a jQuery UI Widget called $.custom.notes that is defined in the file /js/notes.js, and that used an ajax call to the server to get the data to populate it.

All the widget files on HireHop are compressed for speed, however to see the expanded source just add a .MAX to the end of the file’s name, for instance /js/notes.MAX.js.

To inject JavaScript into your webpages, if you go to Settings->Company Settings, and in Plugins add the url of your JavaScript file, which should be on an https server.  You can add multiple URLs which you can separate with a ”;” (semi-colon).

Extending A Widget

As these are jQuery UI Widgets, you can use a type of Object Orientated programming to overwrite parts of the HireHop widgets. For example, we are going to create a a small plugin that adds the word Hello after the Refresh button on the notes widget.

First create a JavaScript file on your web server and add the following code

$(document).ready(function(){
// Check if the notes widget exists
if(typeof($.custom.notes)!=”undefined”) {
// Redefine notes widget
$.widget(”custom.notes”, $.custom.notes, {
_init_main: function() {
// Call the old _init_main
this._super(arguments);
// Add an hello after the refresh button
$(”<span>”,{ html:” Hello” }).insertAfter(this.btnRefresh);
},
new_function_name: function() { }
});
}
});

The above code is available in a file located at https://s.myhirehop.com/plugins/demo.js.

Explaining the code above line by line:

$(document).ready(function(){
First we wait for the document to be ready and all page elements and JavaScript files to be loaded.  In this case this is not necessary as the /js/notes.js file is loaded before the plugin script, however for this example we have left it in for reference.

if(typeof($.custom.notes)!=”undefined”) {
Next we test to see if the notes widget has been defined, if it has we will proceed to overwrite one part of it.

$.widget(”custom.notes”, $.custom.notes, {
Here we are initiating merging of a new JavaScript object containing functions into the notes widget.

_init_main: function() {
By naming a function the same as an existing one, it will be overwritten.

this._super(arguments);
This calls the inherited function, being the function we are overwriting.

$(”<span>”,{ html:” Hello” }).insertAfter(this.btnRefresh);
We then add a simple span element containing the word ”Hello” after the Refresh button. you could also use $(”<span> Hello</span>”).insertAfter(this.btnRefresh);.

new_function_name: function() { }
Finally, this does nothing and is not necessary for what we need to do, it just demonstrates that you can even add your own functions into the widget.

When you reload the HireHop page, you will see the word Hello after the refresh button if you did everything correctly.

Versioning

A huge advantage of using the HireHop NoHTML framework is that all the JavaScript is cached, resulting in fast page loading as the browser uses the JavaScript files in its cache.  This can be problematic when you update your plugin, as all the users using it, their browsers won’t download the updated version, and instead use their cached version, that is unless they clear their browser cache.

To overcome this, when adding your JavaScript URLs to the Plugins options, you can use a versioning parameter, for example for https://www.mywebsite.com/plugin.js you would enter it as https://www.mywebsite.com/plugin.js?v=1. After an update you can then change it to read https://www.mywebsite.com/plugin.js?v=2 which will force all browsers to reload the JavaScript file from your server.  If you don’t have a server to store the code on, you can always use GIST or Google Open Source.

Posted in API

Custom Fields – HireHop API

You can have an unlimited number of custom fields in HireHop specific to each record, a record being a job, project, test/service, asset, etc.  All custom fields can be used in documents, as long as they exist, otherwise they will just be blank.

Currently custom fields are only fully supported in Jobs and Projects. Custom fields can only be used using plugins.

Custom Fields Structure

When fetching a custom field for the currently edited record, there is a function called _get_custom_field_value(field) which will return NULL if the field is not set, a string, or a JavaScript object, depending on how you saved it.

You probably should save custom fields as a JavaScript object (like JSON) in the following format for more printing control, as if it is just a string, HireHop will treat it as a string:

"field_name" :
{
"value"  : "The value of the field",
"type"   : "The field type, default is text, it can also be number, currency, text, date, html and array"
"format" : "For date type only, eg "ddd, dddddd tt" // = "Mon, January 1 2017 12:00"
}

  • value is the value of the field in any format.
  • type tells HireHop how the field should be treated when merging it into a document. An array field will be displayed as JSON.
  • format tells HireHop how to format the field in the document, currently only available dates and is dependent on the users settings and how their date and time formats are set:
    • dddddd for a long date (like January 1 2018)
    • ddddd for a short date (like 01/01/2018)
    • dddd for the day of the week (like Monday)
    • ddd for the short day of the week (like Mon)
    • tt for the time (like 12:36 am).

The format part is only needed for dates and if it is not set, nothing will show.  You can merge formats together and add separators, for instance you can use dddd, dddddd tt which will give ”Monday, January 1 2018 12:00” if the user has set a date order as day month year. The value for a date type must be stored in the yyyy-mm-dd hh:mm format.

If you just save the field as a string and not a JavaScript object, that’s fine, HireHop will just treat it as a string.  Saving your custom fields as a JavaScript object will give you greater control, especially when HireHop prints them in a document.

Saving The Custom Fields

On all edit forms that support custom fields, there is a function called _save_custom_field_value(field, value).  This stores your fields to be saved later.  If you can’t find the function, please contact us.

Please note, that all changes must be written prior to saving.

When the custom fields are saved, they are merged with the existing fields, and any new fields passed with the same name as any existing ones, the new values will be set.

When saving the custom fields, for example using /php_functions.job_save.php directly as an API call, only parameters set will be updated, so if you only set the custom_fields post parameter, only the custom fields will change, all the other fields will stay as is.

Printing Custom Fields

All custom fields can be incorporated into documents just like normal fields and are prefixed with a single ”_” (underscore) character.  For example, for a custom field in a job called ”field_name”, you would load it by using the merge field ”job:_field_name”.

Naming Custom Fields

Some custom fields in documents merge fields together, for example tests merge with an asset in some document fields, so be careful not to use the same field name in an asset and a test.  Also, other plugins maybe added in the future written by yourself or from another source, so add a prefix that denominates you, for example plugins written HireHop by use the ”hh_” prefix, so a field written in a plugin by us might be called ”hh_NewName”.  Field names in document merges are not case sensitive, but they obviously are in JavaScript.

Searchable Custom Field

There is an additional field called CUSTOM_INDEX, that can be used for searching, filtering and listed in search results.  The field is a 45 character string value that can be set to NULL. To enable the field to be shown in the search results on the home page, change the allSearchCols global JavaScript variable by adding CUSTOM_INDEX to it:

if(allSearchCols.constructor===Array && doc_type==0 ) {
allSearchCols.push("CUSTOM_INDEX");
}

There is also a language setting for the custom field displayed name:

if(typeof(lang["customIndexTxt"])=="undefined" || lang["customIndexTxt"]=="") {
lang["customIndexTxt"] = "Custom field name";
}

The reason for the testing for undefined or blank above is just in case the user has set it in the language.

You can use the custom searchable field in the page by adding a lookup in the page or the editor.  On jobs there is a hidden tile that displays the  CUSTOM_INDEX field and can be shown and utilised like so in a plugin:

$("#job_tile_custom_index")
.show()
.click(function() {
window.open("https://www.my_external_app.com?id="+job_data["CUSTOM_INDEX"],"newwindow");
});

To save the CUSTOM_INDEX field in the relevant edit widget, using a custom plugin you can add a form element into the edit widget, for example like so:

// This adds the CUSTOM_INDEX field into the job edit widget
if(typeof($.custom.job_edit)!="undefined") {
// Redefine job_edit, move name to after telephone
$.widget("custom.job_edit", $.custom.job_edit, {
_init_main: function() {
// Call the old _init_main
this._super(arguments);
// Add an extra edit in the job edit
var table = this.default_disc.closest("table");
var tr = $("<tr>").appendTo( table);
$("<td>", { html: lang.customIndexTxt+ " :" }).appendTo(tr);
$("<input>", {
"name" : "custom_index", // Parameter to pass when saving
"class" : "data_cell",   // Setting class to data_cell tells HireHop it is a standard data field
"data-field" : "CUSTOM_INDEX", // Name of the field
"maxlength" : 45         // The CUSTOM_INDEX has a maximum length of 45 characters
})
.appendTo( $("<td>").appendTo(tr) );
// Change the memo height to compensate
this.job_edit_memo.height(110);
}
});
}

The CUSTOM_INDEX field is called xxx:custom_index in the document and is passed as a string into the document.

Global Custom Fields

Occasionally you might want to store a global counter, etc. for the whole company.  To read and store global custom fields use /php_functions/custom_fields_global_load.php and /php_functions/custom_fields_global_save.php.  Saving the data, you need to pass either a json string or json array:

$("#saving_dialog").dialog("open");
// This adds the CUSTOM_INDEX field into the job edit widget
$.ajax({
url: "/php_functions/custom_fields_global_save.php",
type: "post",
dataType: "json",
data: {
"fields":{"my_field":"any type of value"}
// or a json string
// "field":'{"my_field":"any type of value"}'
},
success: function(data)
{
$("#saving_dialog").dialog("close");
// HireHop reported an error
if(typeof(data.error) !== "undefined")
error_message(isNaN(parseInt(data.error)) ? data.error : lang.error[data.error]);
else
{
// All good, "data" is a javascript object (JSON) of all global custom fields
}
},
// Handle an http error
error: function(jqXHR, textStatus, errorThrown)
{
$("#saving_dialog").dialog("close");
error_message(lang.error[1]+" ("+errorThrown+").");
}
});

Posted in API