Module PostmarkApp: Difference between revisions

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search
mNo edit summary
m (Modification de la version du module et nouvelles fonctionnalités)
Tag: 2017 source edit
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Dolibarr module
[[Category:Complementary modules]]
|name=PostmarkApp
[[Category:PostmarkApp]]
|logo=
{{TemplateDocDevEn}}
|developer=Alex BORDARAUD - Lysis
{{TemplateDocUser}}
|contact=alex@lysis.net
=Informations=
|website=https://lysis.net
{{TemplateModuleInfo
|dolistore=
|modulename=PostmarkApp
|version=1.5.2
|editor=Alex BORDARAUD - Lysis https://lysis.net
|dolibarr_min=19.0
|webbuy=
|dolibarr_max=
|status=stable
|license=GPLv3
|version=1.5.27
|language=Multi (FR, EN, DE, ES, IT, PT, NL)
|minversion=
|maxversion=
|note=
}}
}}


'''PostmarkApp''' is a Dolibarr module that replaces the native email sending system with [https://postmarkapp.com Postmark], a professional transactional email service.


==Why use PostmarkApp?==
'''PostmarkApp''' is a professional Dolibarr module that integrates [https://postmarkapp.com Postmark], a transactional email service, to replace Dolibarr's native email sending system. It provides complete email traceability, real-time event tracking, and seamless integration with Dolibarr's Agenda module.


===English===
=Description=
 
==English==
 
PostmarkApp transforms your email communications in Dolibarr by providing enterprise-grade email delivery and tracking. Unlike standard SMTP, Postmark ensures high deliverability rates and provides detailed analytics on every email sent.
 
'''Key Benefits:'''
 
*'''100% Email Traceability''': Track every email from sending to delivery, opening, and link clicks
*'''Professional Delivery''': Postmark's infrastructure ensures 99.9% deliverability
*'''Real-time Notifications''': Instant webhook notifications for all email events
*'''Complete Integration''': All events automatically logged in Dolibarr's Agenda
*'''Multi-Entity Support''': Full compatibility with Dolibarr's MultiCompany module
*'''User Ownership''': Events are owned by the user who sent the email for proper notifications
*'''REST API (Dolibarr)''': Send emails externally with <code>DOLAPIKEY</code>; optional attachments (file path or base64); link to third parties and objects; automatic Agenda event (<code>POSTMARK_SENT</code>); configurable default sender (user vs company)
 
==Français==
 
PostmarkApp transforme vos communications email dans Dolibarr en fournissant une livraison et un suivi d'emails de niveau entreprise. Contrairement au SMTP standard, Postmark garantit des taux de délivrabilité élevés et fournit des analyses détaillées sur chaque email envoyé.
 
'''Avantages principaux<span> </span>:'''
 
*'''Traçabilité 100% des emails'''<span> </span>: Suivez chaque email de l'envoi à la livraison, l'ouverture et les clics
*'''Livraison professionnelle'''<span> </span>: L'infrastructure Postmark garantit 99,9% de délivrabilité
*'''Notifications en temps réel'''<span> </span>: Notifications webhook instantanées pour tous les événements email
*'''Intégration complète'''<span> </span>: Tous les événements automatiquement enregistrés dans l'Agenda Dolibarr
*'''Support Multi-Entités'''<span> </span>: Compatibilité complète avec le module MultiCompany de Dolibarr
*'''Propriété utilisateur'''<span> </span>: Les événements appartiennent à l'utilisateur qui a envoyé l'email pour des notifications correctes
*'''API REST (Dolibarr)'''<span> </span>: Envoi depuis l’extérieur avec <code>DOLAPIKEY</code>; pièces jointes (chemin serveur ou base64); liaison tiers et objet; événement agenda automatique (<code>POSTMARK_SENT</code>); expéditeur par défaut réglable : compte utilisateur ou société Dolibarr (mysoc)
 
=Features=
 
==Core Features==
 
*'''Email Sending via Postmark API'''
 
  * Intercepts all Dolibarr email sending via hooks
  * Sends emails through Postmark's REST API
  * Supports HTML and plain text emails (auto-converts if needed)
  * Handles attachments, CC, BCC, Reply-To headers
  * Supports multiple message streams (transactional, marketing)
  * Intercepts sends via Dolibarr hooks (<code>sendMail</code> on contexts <code>mail</code>, <code>sendmail</code>, <code>all</code>) and substitution of <code>dol_mail</code> (<code>postmarkapp_sendmail</code>) so code paths using <code>dol_mail</code> can also route through Postmark when the replacement mailer option is enabled
 
*'''REST API (native Dolibarr)'''
 
  * Endpoint <code>POST /api/index.php/postmarkappapi/send-email</code> (HTTPS)
  * Authentication: HTTP header <code>DOLAPIKEY</code> (user API key)
  * Required permission <code>postmarkapp->api</code> (admins implicitly allowed unless restricted by your Dolibarr configuration)
  * Body or query JSON: <code>to</code>, <code>subject</code>, <code>message</code>; optional <code>cc</code>/<code>bcc</code>, <code>fk_soc</code>, <code>fk_element</code> + <code>element_type</code>, <code>user_id</code>, <code>attachments[]</code> (<code>file_path</code> or <code>base64</code>)
  * <code>from_mode</code> (optional): <code>user</code> (From = API user email, fallback to company if missing) or <code>company</code> (From = Dolibarr main company « mysoc » email). If omitted, constant <code>POSTMARKAPP_DEFAULT_FROM_MODE</code> applies. No fallback to generic <code>MAIN_MAIL_DEFAULT_FROM</code> or <code>noreply</code>: HTTP 400 if no valid sender
  * Response fields include <code>from_mode</code> and <code>from_source</code> (<code>user</code>, <code>company</code>, <code>company_fallback</code>)
  * Localization of generated Agenda labels follows <code>Content-Language</code> then <code>Accept-Language</code>
  * Full reference: <code>API.md</code> in the module directory
 
*'''Real-time Event Tracking'''
 
  * '''Sent''': Email successfully sent via Postmark
  * '''Delivered''': Email delivered to recipient's mail server
  * '''Opened''': Recipient opened the email (first open only)
  * '''Clicked''': Recipient clicked a link in the email
  * '''Bounced''': Email delivery failed (hard/soft bounce)
  * '''Spam Complaint''': Recipient marked email as spam
 
*'''Dolibarr Integration'''
 
  * All events automatically created in Dolibarr's Agenda module
  * Events linked to original Dolibarr objects (invoices, proposals, orders, etc.)
  * Events linked to third parties and contacts
  * Parent-child relationships between events (Sent → Delivery → Open → Click)
  * User ownership: events belong to the user who sent the email
 
*'''Automatic Triggers'''
 
  * Six automatic triggers registered in Dolibarr's Agenda
  * Automatically enabled on module activation
  * Configurable in Setup > Modules > Agenda > Automatic events
  * Can trigger custom workflows based on email events
 
*'''Multi-Entity Support (MultiCompany)'''


'''Legal proof and dispute resolution''': Having precise tracking of email delivery, opening, and link clicks provides valuable evidence in case of disputes. You can prove that:
  * Full compatibility with Dolibarr's MultiCompany module
  * Entity field in database for data isolation
  * Configurable sharing between entities
  * Automatic entity assignment based on email sender's entity


*An invoice or quote was successfully delivered to your client
*'''Comprehensive Event Management'''
*The recipient opened the email and read it
*They clicked on links (payment, validation, etc.)


This traceability is essential for businesses that need to demonstrate that important information was transmitted and received.
  * Dedicated events list page with advanced filters
  * Filter by date, event type, recipient, subject, third party, contact, linked object, message ID
  * Search by object reference
  * Direct links to related Dolibarr objects
  * Link to ActionComm events


===Français===
*'''Webhook Management'''


'''Preuve, traçabilité et résolution de litiges'''<span> </span>: Disposer d'un suivi précis de la livraison, de l'ouverture et des clics sur les liens de vos emails constitue une preuve précieuse en cas de litige. Vous pouvez prouver que<span> </span>:
  * Automatic webhook creation via Postmark API
  * Manual webhook configuration support
  * Built-in webhook testing tools
  * Webhook signature validation (optional)


*Une facture ou un devis a bien été délivré à votre client
*'''Multi-language Support'''
*Le destinataire a ouvert l'email et l'a lu
*Il a cliqué sur les liens (paiement, validation, etc.)


Cette traçabilité est essentielle pour les entreprises qui doivent démontrer que des informations importantes ont été transmises et reçues.
  * Available in 7 languages: French, English, German, Spanish, Italian, Portuguese, Dutch
  * All interface elements translated
  * Event labels and descriptions translated


==Features==
*'''Administration pages'''


*'''Email Sending via Postmark API''' - All Dolibarr emails are sent through Postmark
  * Main setup: '''Setup → Modules → PostmarkApp''' (<code>admin/setup.php</code>)
*'''Delivery Tracking''' - Know when your emails are delivered
  * Tab '''About''' (<code>admin/about.php</code>): module metadata, README excerpt, contextual help on API sender rules and checking that rich-text help renders as HTML (not raw tags)
*'''Open Tracking''' - Track when recipients open your emails (first open only)
  * Tab '''Changelog''' (<code>admin/changelog.php</code>): rendered <code>ChangeLog.md</code> (version history)
*'''Click Tracking''' - Monitor which links are clicked in your emails
*'''Bounce Handling''' - Automatically handle bounced emails
*'''Spam Complaint Tracking''' - Be notified of spam complaints
*'''Dolibarr Events Integration''' - All email events are logged in Dolibarr's Agenda module
*'''Object Linking''' - Events are linked to related Dolibarr objects (invoices, proposals, orders, etc.)
*'''Multi-language''' - Available in 7 languages (FR, EN, DE, ES, IT, PT, NL)


==Requirements==
==Requirements==


*Dolibarr 19.0 or higher
===System Requirements===
*PHP 7.1 or higher with cURL extension
 
*Postmark account with Server API Token
*'''Dolibarr''': Version 19.0 or higher
*Agenda module must be enabled
*'''PHP''': Version 7.1 or higher
*'''PHP Extensions''': cURL (required for API calls)
*'''Postmark Account''': Active account with at least one server
*'''Server API Token''': From Postmark dashboard
*'''Agenda Module''': Must be enabled (mandatory dependency)
*'''REST API users''': Grant permission <code>postmarkapp->api</code> and assign a Dolibarr API key for each integration account
 
==Postmark Requirements==


==Installation==
*Verified Sender Signatures for the "From" email addresses
*Server API Token (found in Postmark > Servers > API Tokens)
*Webhook URL accessible from internet (for event tracking)
 
=Installation=
 
==Step-by-Step Installation==


#Download the module package <code>module_postmarkapp-x.y.z.zip</code>
#Download the module package <code>module_postmarkapp-x.y.z.zip</code>
#Extract to <code>htdocs/custom/postmarkapp/</code> or use Dolibarr's module deployment feature
#Extract to <code>htdocs/custom/postmarkapp/</code> directory
#Go to '''Home > Setup > Modules/Applications'''
#Go to '''Home > Setup > Modules/Applications'''
#Search for "PostmarkApp" and enable the module
#Search for "PostmarkApp" in the module list
#Click '''Enable''' to activate the module
#The module will automatically:
 
  * Create the <code>llx_postmarkapp_events</code> table
  * Register automatic triggers in Agenda
  * Configure MultiCompany sharing (if MultiCompany module is enabled)
 
#Configure the module in '''Setup > Modules > PostmarkApp > Settings'''
#Configure the module in '''Setup > Modules > PostmarkApp > Settings'''


==Configuration==
==Post-Installation==
 
After installation, verify:
 
*The <code>llx_postmarkapp_events</code> table exists in your database
*The Agenda module is enabled
*Automatic triggers are visible in '''Setup > Modules > Agenda > Automatic events'''
*For REST integrations: '''Users → Permissions''' includes <code>postmarkapp->api</code> where needed and API keys assigned


===Step 1: Server API Token===
===Step 1: Server API Token===
The Server API Token is the primary authentication method for Postmark.


#Log in to your Postmark account at https://postmarkapp.com
#Log in to your Postmark account at https://postmarkapp.com
#Select your server
#Navigate to '''Servers''' and select your server
#Go to '''API Tokens''' tab
#Go to the '''API Tokens''' tab
#Copy the '''Server API Token'''
#Copy the '''Server API Token''' (starts with a long alphanumeric string)
#Paste it in the PostmarkApp configuration page
#Paste it in the PostmarkApp configuration page under "Server API Token"
#Click '''Validate''' to test the connection
#Click '''Validate''' to test the connection
#If successful, you'll see a green confirmation message
'''Security Note:''' The token is stored encrypted in Dolibarr's constants table.


===Step 2: Options===
===Step 2: Options===


*'''Message Stream''': Select the message stream to use (default: "outbound")
*'''Message Stream''':
*'''Track Opens''': Enable/disable open tracking
 
*'''Track Clicks''': Enable/disable click tracking (requires HTML emails)
  * Select the Postmark message stream to use
*'''Replace Dolibarr Mailer''': Enable to route all emails through Postmark
  * Default: "outbound" (transactional emails)
  * Alternative: "broadcast" (marketing emails)
  * Streams are automatically loaded from your Postmark account
 
*'''Track Opens''':
 
  * Enable/disable open tracking
  * When enabled, Postmark tracks when emails are opened
  * Only the first open is tracked (PostFirstOpenOnly)
 
*'''Track Clicks''':
 
  * Enable/disable click tracking
  * '''Requires HTML emails''' - plain text emails cannot track clicks
  * When enabled, all links in emails are rewritten by Postmark for tracking
 
*'''Replace Dolibarr Mailer''':
 
  * Enable to route ALL Dolibarr emails through Postmark
  * When disabled, Dolibarr uses its native email system
  * Recommended: Keep enabled for consistent tracking
 
*'''API default sender (From)'''
 
  * Constant <code>POSTMARKAPP_DEFAULT_FROM_MODE</code>: <code>user</code> (default From = authenticated API user email) or <code>company</code> (default From = main company « mysoc » email from '''Home → Setup → Company/Organization''').
  * For <code>company</code> mode en production: the company email must be a verified Sender Signature in Postmark.
  * Constant <code>POSTMARKAPP_SOCIETE_FROM_CONFIRMED</code> + checkbox « Postmark confirmation » on the setup page: the administrator must explicitly confirm that the company From is authorized on Postmark.
  * Saving in <code>company</code> mode is '''refused''' if the mysoc email is missing or syntactically invalid.
  * Test email action uses the configured mode so verification matches production behaviour.
  * Per-request API override remains possible via <code>from_mode</code> (see '''REST API''' above).


===Step 3: Webhook===
===Step 3: Webhook Configuration (Optional but Recommended)===


Webhooks allow Postmark to notify Dolibarr of email events in real-time.
Webhooks allow Postmark to notify Dolibarr in real-time when email events occur.


'''Automatic Setup:'''
'''Automatic Setup:'''


*Click '''Create Webhook Automatically'''
#Ensure your Server API Token is validated
*The webhook URL will be registered with Postmark
#Click '''Create Webhook Automatically'''
#The module will:
 
  * Generate the webhook URL (format: <code>https://yourdomain.com/dolibarr/custom/postmarkapp/webhook.php</code>)
  * Create the webhook in Postmark via API
  * Configure it to listen for: Delivery, Open (First Open Only), Click, Bounce, Spam Complaint
 
#You'll see a confirmation message with the webhook ID


'''Manual Setup:'''
'''Manual Setup:'''


#Copy the webhook URL displayed in the configuration
#Copy the webhook URL displayed in the configuration page
#Go to Postmark > Servers > Your Server > Webhooks
#Log in to Postmark dashboard
#Add a new webhook with the copied URL
#Go to '''Servers > Your Server > Webhooks'''
#Enable: Delivery, Open (First Open Only), Click, Bounce, Spam Complaint
#Click '''Add Webhook'''
#Paste the URL
#Enable the following triggers:
 
  * Delivery
  * Open (select "First Open Only")
  * Click
  * Bounce
  * Spam Complaint
 
#Save the webhook
 
'''Testing Webhooks:'''
The configuration page includes test buttons to simulate webhook events:
 
*Test Delivery
*Test Open
*Test Click
*Test Bounce
 
These send test payloads to your webhook endpoint for verification.
 
===Step 4: Testing===
 
#Click '''Test Connection''' to verify API connectivity
#Click '''Send Test Email''' to send a test email to your logged-in user's email address
#The test email includes:
 
  * HTML and plain text versions
  * A trackable link to test click tracking
  * Metadata for webhook linking
 
#Check your email inbox and verify delivery
#Use the webhook test buttons to verify event processing
 
=MultiCompany Compatibility=
 
PostmarkApp is fully compatible with Dolibarr's MultiCompany module.
 
==How It Works==
 
*Each email event is stored with an <code>entity</code> field
*By default, events are isolated per entity (entity = current entity)
*Events can be shared between entities if MultiCompany sharing is enabled
 
==Configuration==
 
#Enable the MultiCompany module in Dolibarr
#Go to '''Setup > Modules > MultiCompany > Options'''
#Find the "PostmarkApp Events" sharing option
#Enable/disable sharing as needed
 
==Sharing Behavior==
 
*'''Sharing Disabled''': Each entity only sees its own email events
*'''Sharing Enabled''': Events can be shared between entities (entity IN (0, entity1, entity2, ...))
*The webhook automatically uses the entity from the original "Sent" event
 
==Entity Assignment==
 
*When an email is sent, the event is assigned to the current entity (<code>$conf->entity</code>)
*Webhook events inherit the entity from the original "Sent" event
*This ensures proper data isolation and sharing
 
=Technical Architecture=
 
==Module Structure==


==How it works==
<pre>
postmarkapp/
├── core/
│  ├── modules/
│  │  └── modPostmarkApp.class.php    # Module descriptor, menus, hooks, constants
│  └── substitutions/
│      └── postmarkapp.lib.php        # dol_mail → postmarkapp_sendmail
├── class/
│  ├── actions_postmarkapp.class.php  # Hook handlers (sendMail, mail_begin/end)
│  └── api_postmarkapp.class.php      # Dolibarr REST API (send-email)
├── lib/
│  ├── postmarkapp.lib.php            # Admin tabs, sender helpers (mysoc validation)
│  └── class/
│      ├── postmarkappmail.class.php  # Postmark API wrapper
│      └── lysistech.class.php        # Optional remote last-version URL helper
├── admin/
│  ├── setup.php                      # Configuration
│  ├── about.php                      # About + embedded help
│  └── changelog.php                  # Rendered ChangeLog.md
├── events.php                          # Events list page
├── webhook.php                          # Webhook endpoint
├── API.md                              # Detailed REST documentation
├── ChangeLog.md
└── langs/
    └── [lang]/
        └── postmarkapp.lang            # Translations
</pre>


Once enabled, all emails sent from Dolibarr will be routed through Postmark. The module intercepts the native email sending and replaces it with Postmark's API.
===Hooks System===


When a webhook is configured, Postmark will notify your Dolibarr installation of email events:
The module uses Dolibarr's hook system to intercept email sending:
 
*'''Hook contexts''' (registered in the module descriptor): <code>mail</code>, <code>sendmail</code>, <code>all</code>
*'''Primary hook''': <code>sendMail</code>
*'''Hook File''': <code>class/actions_postmarkapp.class.php</code>
*'''Hook Method''': <code>sendMail($parameters, &$object, &$action, $hookmanager)</code>
*'''Additional handlers''': <code>mail_begin</code>, <code>mail_end</code> where applicable for the same contexts
 
'''How It Works:'''
 
#Dolibarr prepares to send an email via <code>CMailFile</code>
#The hook intercepts the email before native sending
#Extracts email data (to, subject, body, attachments, etc.)
#Sends email via Postmark API using <code>PostmarkAppMail</code> class
#Logs the "Sent" event to database
#Returns 1 to prevent native Dolibarr email sending
 
===dol_mail substitution===
 
When substitution files are loaded, calls to Dolibarr <code>dol_mail()</code> can be diverted to Postmark via <code>postmarkapp_sendmail()</code> in <code>core/substitutions/postmarkapp.lib.php</code> (same prerequisites: module enabled, valid Server Token, Replace Mailer as required). Behaviour matches other intercepted sends (metadata trackid/objects when supplied in extra parameters).
 
===API Integration===
 
The module uses Postmark's REST API:
 
*'''Base URL''': <code>https://api.postmarkapp.com</code>
*'''Authentication''': <code>X-Postmark-Server-Token</code> header
*'''Endpoints Used''':
 
  * <code>POST /email</code> - Send email
  * <code>GET /server</code> - Test connection
  * <code>GET /message-streams</code> - List streams
  * <code>GET /senders</code> - List sender signatures
  * <code>GET /webhooks</code> - List webhooks
  * <code>POST /webhooks</code> - Create webhook
 
===Database Schema===
 
The module creates one custom table: <code>llx_postmarkapp_events</code>


{| class="wikitable"
{| class="wikitable"
!Event!!Description!!Dolibarr Code
!Column!!Type!!Null!!Default!!Description
|-
|rowid||INTEGER||NO||AUTO_INCREMENT||Primary key
|-
|email_id||VARCHAR(255)||NO|| ||Postmark MessageID (unique identifier)
|-
|-
|Sent||Email sent via Postmark||POSTMARK_SENT
|event_type||VARCHAR(50)||NO|| ||Event type (Sent, Delivery, Open, Click, Bounce, SpamComplaint)
|-
|-
|Delivered||Email delivered to recipient's server||POSTMARK_DELIVERY
|recipient||VARCHAR(255)||YES||NULL||Email recipient address
|-
|-
|Opened||Recipient opened the email||POSTMARK_OPEN
|subject||VARCHAR(255)||YES||NULL||Email subject line
|-
|-
|Clicked||Recipient clicked a link||POSTMARK_CLICK
|fk_soc||INTEGER||YES||NULL||Linked third party ID (llx_societe.rowid)
|-
|-
|Bounced||Email could not be delivered||POSTMARK_BOUNCE
|fk_contact||INTEGER||YES||NULL||Linked contact ID (llx_socpeople.rowid)
|-
|-
|Spam||Recipient marked as spam||POSTMARK_SPAM_COMPLAINT
|fk_element||INTEGER||YES||NULL||Linked element ID (depends on element_type)
|-
|element_type||VARCHAR(50)||YES||NULL||Element type (propal, facture, commande, etc.)
|-
|fk_user||INTEGER||YES||NULL||User ID who sent the email (for event ownership)
|-
|fk_actioncomm||INTEGER||YES||NULL||Linked ActionComm ID (llx_actioncomm.rowid)
|-
|event_data||TEXT||YES||NULL||JSON data from webhook (full payload)
|-
|entity||INTEGER||NO||1||Entity ID (for MultiCompany)
|-
|date_creation||DATETIME||NO|| ||Event timestamp
|}
|}


Each event creates an entry in Dolibarr's Agenda, linked to the original object.
'''Indexes:'''
 
*<code>idx_email_id</code> on <code>email_id</code>
*<code>idx_event_type</code> on <code>event_type</code>
*<code>idx_date_creation</code> on <code>date_creation</code>
*<code>idx_fk_soc</code> on <code>fk_soc</code>
*<code>idx_fk_contact</code> on <code>fk_contact</code>
*<code>idx_fk_element</code> on <code>fk_element</code>
*<code>idx_fk_user</code> on <code>fk_user</code>
*<code>idx_entity</code> on <code>entity</code>


==Database==
===Supported Object Types===


The module creates one custom table:
The module can link email events to various Dolibarr objects:


{| class="wikitable"
{| class="wikitable"
!Column!!Type!!Description
!Object Type!!Description!!Table
|-
|propal||Customer Proposal||llx_propal
|-
|-
|rowid||INTEGER||Primary key
|commande||Customer Order||llx_commande
|-
|-
|email_id||VARCHAR(255)||Postmark MessageID
|facture||Customer Invoice||llx_facture
|-
|-
|event_type||VARCHAR(50)||Event type
|expedition||Shipment||llx_expedition
|-
|-
|recipient||VARCHAR(255)||Email recipient
|contrat||Contract||llx_contrat
|-
|-
|subject||VARCHAR(255)||Email subject
|fichinter||Intervention||llx_fichinter
|-
|-
|fk_soc||INTEGER||Linked third party ID
|facture_fourn||Supplier Invoice||llx_facture_fourn
|-
|-
|fk_contact||INTEGER||Linked contact ID
|order_supplier||Supplier Order||llx_commande_fournisseur
|-
|-
|fk_element||INTEGER||Linked element ID
|supplier_proposal||Supplier Proposal||llx_supplier_proposal
|-
|-
|element_type||VARCHAR(50)||Element type (propal, facture, etc.)
|project||Project||llx_projet
|-
|-
|fk_actioncomm||INTEGER||Linked ActionComm ID
|ticket||Ticket||llx_ticket
|-
|-
|event_data||TEXT||JSON data from webhook
|member||Member||llx_adherent
|-
|-
|date_creation||DATETIME||Event timestamp
|reception||Reception||llx_reception
|-
|expensereport||Expense Report||llx_expensereport
|}
 
===Automatic Triggers===
 
The module registers 6 automatic triggers in Dolibarr's Agenda system:
 
{| class="wikitable"
!Trigger Code!!Label Key!!Description Key!!Rang
|-
|POSTMARK_SENT||PostmarkTriggerSent||PostmarkTriggerSentDesc||50100
|-
|POSTMARK_DELIVERY||PostmarkTriggerDelivery||PostmarkTriggerDeliveryDesc||50101
|-
|POSTMARK_OPEN||PostmarkTriggerOpen||PostmarkTriggerOpenDesc||50102
|-
|POSTMARK_CLICK||PostmarkTriggerClick||PostmarkTriggerClickDesc||50103
|-
|POSTMARK_BOUNCE||PostmarkTriggerBounce||PostmarkTriggerBounceDesc||50104
|-
|POSTMARK_SPAMCOMPLAINT||PostmarkTriggerSpam||PostmarkTriggerSpamDesc||50105
|}
 
These triggers are:
 
*Automatically registered on module activation
*Automatically enabled (constants <code>MAIN_AGENDA_ACTIONAUTO_*</code> set to 1)
*Configurable in '''Setup > Modules > Agenda > Automatic events'''
*Can trigger custom workflows based on email events
 
===Permissions===
 
The module defines '''three''' permissions:
 
*'''postmarkapp_read''': View email events (required for events list page; menu '''Tools → PostmarkApp events''' / <code>events.php</code>)
*'''postmarkapp_setup''': Configure the module (required for setup page)
*'''postmarkapp_api''': Call the Dolibarr REST endpoint <code>postmarkappapi/send-email</code>
 
Permissions are checked using:
<code>if ($user->hasRight('postmarkapp', 'read'))</code>
<code>if ($user->hasRight('postmarkapp', 'setup'))</code>
<code>if ($user->hasRight('postmarkapp', 'api'))</code>
 
===Remote version check (optional)===
 
The module descriptor can expose <code>LysisTech::getLastModuleVersionUrl()</code> so Dolibarr may query a remote « last version » string. Restricted outbound HTTPS environments may log failures unrelated to runtime sending. Define <code>DOLIBARR_LYSIS_SKIP_VERSION_CHECK</code> in <code>conf/conf.php</code> to silence that check when needed (same pattern as other Lysis-published modules).
 
===Menu===
 
*Events list appears under '''Tools''' (not a dedicated top-level main menu).
 
===Important module constants===
 
In addition to token and webhook settings, noteworthy keys include:
 
*<code>POSTMARKAPP_DEFAULT_FROM_MODE</code>: <code>user</code> or <code>company</code> — default REST API sender mode
*<code>POSTMARKAPP_SOCIETE_FROM_CONFIRMED</code>: admin confirmation flag for Postmark-aligned company sender
*<code>MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML</code>: enforced by activation when HTML/click-tracking behaviour is desired (already documented above)
 
===Webhook Processing===
 
The webhook endpoint (<code>webhook.php</code>) processes incoming Postmark events:
 
#Receives POST request from Postmark with JSON payload
#Validates webhook signature (optional, if configured)
#Extracts event data (type, recipient, message ID, metadata)
#Searches for original "Sent" event by MessageID
#Retrieves linked objects (third party, contact, element) from original event
#Creates ActionComm event in Dolibarr's Agenda
#Sets event ownership to original sender's user ID
#Links event to original ActionComm (parent-child relationship)
#Stores detailed event data in <code>llx_postmarkapp_events</code> table
#Returns HTTP 200 to Postmark
 
===SQL Queries and MultiCompany===
 
All SQL queries use <code>getEntity()</code> function for MultiCompany compatibility:
 
<code>SELECT * FROM llx_postmarkapp_events WHERE entity IN (getEntity('postmarkapp_events'))</code>
 
This ensures:
 
*Data isolation per entity (by default)
*Data sharing when MultiCompany sharing is enabled
*Proper entity assignment on insert
 
==How It Works==
 
===Email Sending Flow===
 
#User triggers email sending in Dolibarr (e.g., sending an invoice)
#Dolibarr prepares <code>CMailFile</code> object with email data
#PostmarkApp hook intercepts via <code>sendMail</code> hook
#Module extracts:
 
  * Recipient(s), subject, body (HTML/text), attachments
  * Linked objects (from <code>trackid</code> or metadata)
  * Current user ID (for event ownership)
 
#Email sent via Postmark API
#Postmark returns MessageID
#Module logs "Sent" event to database with:
 
  * MessageID, recipient, subject, linked objects, user ID, entity
 
#Returns 1 to prevent native Dolibarr email sending
 
===Webhook Event Flow===
 
#Postmark detects email event (delivery, open, click, bounce, spam)
#Postmark sends POST request to webhook URL with JSON payload
#Webhook endpoint receives and validates request
#Searches for original "Sent" event using MessageID
#Retrieves:
 
  * Linked objects (third party, contact, element)
  * User ID who sent the email
  * Entity ID
  * Original ActionComm ID
 
#Creates new ActionComm event:
 
  * Type: AC_EMAIL
  * Code: POSTMARK_[EVENT_TYPE]
  * Label: Translated event label
  * Owner: Original sender's user ID
  * Parent: Original ActionComm ID
  * Linked to: Third party, contact, element
 
#Stores event in <code>llx_postmarkapp_events</code> table
#Returns success to Postmark
 
===Event Linking===
 
Events are automatically linked to Dolibarr objects:
 
*'''From trackid''': Parses Dolibarr's trackid format (e.g., "pro1" = proposal ID 1)
*'''From metadata''': Extracts <code>fk_soc</code>, <code>fk_contact</code>, <code>fk_element</code>, <code>element_type</code>
*'''From recipient email''': Searches third parties and contacts by email address
*'''From MessageID''': Webhook events link to original "Sent" event via MessageID
 
==Event Types==
 
{| class="wikitable"
!Event Type!!Description!!When It Occurs!!Dolibarr Code!!ActionComm Type
|-
|Sent||Email sent via Postmark||Immediately after API call||POSTMARK_SENT||AC_EMAIL
|-
|Delivery||Email delivered||When recipient's server accepts||POSTMARK_DELIVERY||AC_EMAIL
|-
|Open||Email opened||First time recipient opens email||POSTMARK_OPEN||AC_EMAIL
|-
|Click||Link clicked||When recipient clicks a tracked link||POSTMARK_CLICK||AC_EMAIL
|-
|Bounce||Delivery failed||Email rejected by recipient's server||POSTMARK_BOUNCE||AC_EMAIL
|-
|Spam Complaint||Marked as spam||Recipient reports email as spam||POSTMARK_SPAMCOMPLAINT||AC_EMAIL
|}
|}


==Troubleshooting==
==Troubleshooting==


===Emails not sending===
===Emails Not Sending===


#Check that <code>POSTMARKAPP_REPLACE_MAILER</code> is enabled
#Verify <code>POSTMARKAPP_REPLACE_MAILER</code> constant is set to 1
#Verify the Server API Token is valid
#Check Server API Token is valid (use "Test Connection" button)
#Check Dolibarr logs for error messages
#Verify "From" email address is a verified Sender Signature in Postmark
#Ensure the "From" address is a verified Sender Signature in Postmark
#Check Dolibarr logs (<code>dolibarr.log</code>) for error messages
#Ensure cURL extension is enabled in PHP
#Verify internet connectivity from server to Postmark API


===Webhooks not received===
===Webhooks Not Received===


#Verify the webhook URL is accessible from the internet
#Verify webhook URL is accessible from internet (test with curl or browser)
#Check that webhooks are created in Postmark dashboard
#Check webhook is created in Postmark dashboard
#Test webhooks using the built-in test buttons
#Verify webhook triggers are enabled (Delivery, Open, Click, Bounce, Spam)
#Check server logs for incoming requests
#Test webhooks using built-in test buttons in configuration page
#Check server logs for incoming POST requests to <code>webhook.php</code>
#Verify webhook URL doesn't require authentication (webhook uses NOLOGIN)


===Click tracking not working===
===Click Tracking Not Working===


Click tracking requires emails to be sent in HTML format. Plain text emails cannot track clicks.
*Click tracking requires emails to be sent in HTML format
*Plain text emails cannot track clicks
*Ensure <code>MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML</code> is enabled
*Verify "Track Clicks" option is enabled in configuration
*Check that links in emails are not already rewritten by another system
 
===REST API errors (send-email)===
 
#'''401 / 403''': Confirm header <code>DOLAPIKEY</code>, user login bound to that key has <code>postmarkapp->api</code>, module PostmarkApp enabled
#'''400 (sender)''': No valid From — set the API user email, or configure a valid '''Company''' email matching a Postmark Sender Signature; in <code>company</code> mode check setup validation and confirmation checkbox
#Consult <code>dolibarr.log</code> and full examples in '''API.md'''
 
===Events Not Appearing in Agenda===
 
#Verify Agenda module is enabled
#Check automatic triggers are enabled in '''Setup > Modules > Agenda > Automatic events'''
#Verify user has permission to view ActionComm events
#Check <code>llx_postmarkapp_events</code> table has data
#Verify webhook is receiving and processing events (check logs)
 
===MultiCompany Issues===
 
#Verify MultiCompany module is enabled
#Check entity field exists in <code>llx_postmarkapp_events</code> table
#Verify sharing configuration in '''Setup > Modules > MultiCompany > Options'''
#Check SQL queries use <code>getEntity('postmarkapp_events')</code>
#Verify entity is correctly assigned on email send


==Screenshots==
==Screenshots==


<!-- Add screenshots here -->
<!-- Add screenshots here when available -->
 
=Changelog=
 
===Current release (module descriptor: 1.5.27)===
 
See also <code>ChangeLog.md</code> inside the package and the '''Changelog''' tab in administration.
 
===Version 1.5.25===
 
*Documentation reminders: REST API sender configuration (<code>user</code> / <code>company</code>, confirmation), About page help (API response fields <code>from_mode</code> / <code>from_source</code>, HTTP 400 if no sender, HTML rendering of help)
 
===Version 1.5.24===
 
*Module icons: addition of correct <code>img/</code> files so Dolibarr <code>img_object</code> URLs no longer return 404
 
===Version 1.5.23===
 
*'''Changelog''' tab in administration; '''About''' page aligned with Dolibarr module info layout
 
===Version 1.5.22===


==Changelog==
*'''About''' page displays <code>ChangeLog.md</code> correctly again alongside README
 
===Version 1.5.10===
 
*'''Default REST sender''' constants <code>POSTMARKAPP_DEFAULT_FROM_MODE</code> and <code>POSTMARKAPP_SOCIETE_FROM_CONFIRMED</code>
*'''Setup''' UI: sender mode selection, displayed mysoc email, link to company card, mandatory Postmark confirmation in company mode, save blocked if enterprise email invalid, test mail aligned with mode
*'''REST''' <code>send-email</code>: optional <code>from_mode</code>, <code>user_id</code>, response metadata <code>from_mode</code> / <code>from_source</code>, structured errors instead of anonymous <code>noreply</code> fallback
*Helpers <code>postmarkapp_get_mysoc_sender()</code>, <code>postmarkapp_is_valid_sender_email()</code>


===Version 1.5.2 (2026-01-06)===
===Version 1.5.2 (2026-01-06)===


*Added MultiCompany compatibility
*Added entity field to database
*Implemented getEntity() in all SQL queries
*Added MultiCompany sharing configuration
*Added user ownership for events (fk_user field)
*Enhanced object type support (supplier invoices, orders, projects, tickets, etc.)
*Improved event linking (from trackid, metadata, recipient email)
*Simplified event notes and labels
*Simplified event notes and labels
*Removed duplicate "Sent" event
*Removed duplicate "Sent" event (relies on Dolibarr's native system)
*Added bilingual documentation
*Added bilingual documentation
*Added multi-language support
*Added multi-language support (7 languages)
*Added automatic trigger activation
*Enhanced webhook processing with entity inheritance
*Added comprehensive event filters
*Added reference search for linked objects
 
===Version 1.5.0 (2026-01-06)===
 
*Initial release
*Postmark API integration
*Webhook handling
*Event tracking
*Agenda integration
*Object linking


==Links==
=Links=


*[https://postmarkapp.com Postmark Official Website]
*[https://postmarkapp.com Postmark Official Website]
*[https://lysis.net Lysis - Developer Website]
*[https://lysis.net Lysis - Developer Website]


==License==
=License=


This module is distributed under the [https://www.gnu.org/licenses/gpl-3.0 GNU General Public License v3 (GPLv3)].
This module is distributed under the [https://www.gnu.org/licenses/gpl-3.0 GNU General Public License v3 (GPLv3)].


==Professional Services / Services professionnels==
=Professional Services / Services professionnels=


===English===
===English===
Line 203: Line 744:


*Installation and configuration of the PostmarkApp module
*Installation and configuration of the PostmarkApp module
*REST API integrations (<code>DOLAPIKEY</code>, <code>from_mode</code>, attachments)
*Postmark account setup and sender signature verification
*Postmark account setup and sender signature verification
*Webhook configuration and testing
*Webhook configuration and testing
*Integration with your existing Dolibarr workflows
*Integration with your existing Dolibarr workflows
*MultiCompany configuration and data migration
*Custom development and feature requests
*Training for your team
*Training for your team


Contact us for a personalized quote.
Contact us for a personalized quote: https://lysis.net


===Français===
===Français===
Line 215: Line 759:


*L'installation et la configuration du module PostmarkApp
*L'installation et la configuration du module PostmarkApp
*Les intégrations API REST (<code>DOLAPIKEY</code>, <code>from_mode</code>, pièces jointes)
*La création de votre compte Postmark et la vérification des signatures d'expéditeur
*La création de votre compte Postmark et la vérification des signatures d'expéditeur
*La configuration et les tests des webhooks
*La configuration et les tests des webhooks
*L'intégration avec vos processus Dolibarr existants
*L'intégration avec vos processus Dolibarr existants
*La configuration MultiCompany et la migration de données
*Le développement sur mesure et les demandes de fonctionnalités
*La formation de vos équipes
*La formation de vos équipes


Contactez-nous pour un devis personnalisé.
Contactez-nous pour un devis personnalisé<span> </span>: https://lysis.net


==Author==
=Author=


'''Alex BORDARAUD'''<br />
'''Alex BORDARAUD'''<br />
Website: https://lysis.net
Website: https://lysis.net
[[Category:Modules complémentaires]]

Latest revision as of 06:42, 4 May 2026

Informations


Module name PostmarkApp
Editor / Editeur Alex BORDARAUD - Lysis https://lysis.net
Download or buy page / Page achat ou téléchargement
Status / Statut / Estado Stable
Prerequisites / Prérequis


Last update date / Date mise à jour fiche / Fecha última actualización 2026-05-4
Note / Nota


PostmarkApp is a professional Dolibarr module that integrates Postmark, a transactional email service, to replace Dolibarr's native email sending system. It provides complete email traceability, real-time event tracking, and seamless integration with Dolibarr's Agenda module.

Description

English

PostmarkApp transforms your email communications in Dolibarr by providing enterprise-grade email delivery and tracking. Unlike standard SMTP, Postmark ensures high deliverability rates and provides detailed analytics on every email sent.

Key Benefits:

  • 100% Email Traceability: Track every email from sending to delivery, opening, and link clicks
  • Professional Delivery: Postmark's infrastructure ensures 99.9% deliverability
  • Real-time Notifications: Instant webhook notifications for all email events
  • Complete Integration: All events automatically logged in Dolibarr's Agenda
  • Multi-Entity Support: Full compatibility with Dolibarr's MultiCompany module
  • User Ownership: Events are owned by the user who sent the email for proper notifications
  • REST API (Dolibarr): Send emails externally with DOLAPIKEY; optional attachments (file path or base64); link to third parties and objects; automatic Agenda event (POSTMARK_SENT); configurable default sender (user vs company)

Français

PostmarkApp transforme vos communications email dans Dolibarr en fournissant une livraison et un suivi d'emails de niveau entreprise. Contrairement au SMTP standard, Postmark garantit des taux de délivrabilité élevés et fournit des analyses détaillées sur chaque email envoyé.

Avantages principaux :

  • Traçabilité 100% des emails : Suivez chaque email de l'envoi à la livraison, l'ouverture et les clics
  • Livraison professionnelle : L'infrastructure Postmark garantit 99,9% de délivrabilité
  • Notifications en temps réel : Notifications webhook instantanées pour tous les événements email
  • Intégration complète : Tous les événements automatiquement enregistrés dans l'Agenda Dolibarr
  • Support Multi-Entités : Compatibilité complète avec le module MultiCompany de Dolibarr
  • Propriété utilisateur : Les événements appartiennent à l'utilisateur qui a envoyé l'email pour des notifications correctes
  • API REST (Dolibarr) : Envoi depuis l’extérieur avec DOLAPIKEY; pièces jointes (chemin serveur ou base64); liaison tiers et objet; événement agenda automatique (POSTMARK_SENT); expéditeur par défaut réglable : compte utilisateur ou société Dolibarr (mysoc)

Features

Core Features

  • Email Sending via Postmark API
 * Intercepts all Dolibarr email sending via hooks
 * Sends emails through Postmark's REST API
 * Supports HTML and plain text emails (auto-converts if needed)
 * Handles attachments, CC, BCC, Reply-To headers
 * Supports multiple message streams (transactional, marketing)
 * Intercepts sends via Dolibarr hooks (sendMail on contexts mail, sendmail, all) and substitution of dol_mail (postmarkapp_sendmail) so code paths using dol_mail can also route through Postmark when the replacement mailer option is enabled
  • REST API (native Dolibarr)
 * Endpoint POST /api/index.php/postmarkappapi/send-email (HTTPS)
 * Authentication: HTTP header DOLAPIKEY (user API key)
 * Required permission postmarkapp->api (admins implicitly allowed unless restricted by your Dolibarr configuration)
 * Body or query JSON: to, subject, message; optional cc/bcc, fk_soc, fk_element + element_type, user_id, attachments[] (file_path or base64)
 * from_mode (optional): user (From = API user email, fallback to company if missing) or company (From = Dolibarr main company « mysoc » email). If omitted, constant POSTMARKAPP_DEFAULT_FROM_MODE applies. No fallback to generic MAIN_MAIL_DEFAULT_FROM or noreply: HTTP 400 if no valid sender
 * Response fields include from_mode and from_source (user, company, company_fallback)
 * Localization of generated Agenda labels follows Content-Language then Accept-Language
 * Full reference: API.md in the module directory
  • Real-time Event Tracking
 * Sent: Email successfully sent via Postmark
 * Delivered: Email delivered to recipient's mail server
 * Opened: Recipient opened the email (first open only)
 * Clicked: Recipient clicked a link in the email
 * Bounced: Email delivery failed (hard/soft bounce)
 * Spam Complaint: Recipient marked email as spam
  • Dolibarr Integration
 * All events automatically created in Dolibarr's Agenda module
 * Events linked to original Dolibarr objects (invoices, proposals, orders, etc.)
 * Events linked to third parties and contacts
 * Parent-child relationships between events (Sent → Delivery → Open → Click)
 * User ownership: events belong to the user who sent the email
  • Automatic Triggers
 * Six automatic triggers registered in Dolibarr's Agenda
 * Automatically enabled on module activation
 * Configurable in Setup > Modules > Agenda > Automatic events
 * Can trigger custom workflows based on email events
  • Multi-Entity Support (MultiCompany)
 * Full compatibility with Dolibarr's MultiCompany module
 * Entity field in database for data isolation
 * Configurable sharing between entities
 * Automatic entity assignment based on email sender's entity
  • Comprehensive Event Management
 * Dedicated events list page with advanced filters
 * Filter by date, event type, recipient, subject, third party, contact, linked object, message ID
 * Search by object reference
 * Direct links to related Dolibarr objects
 * Link to ActionComm events
  • Webhook Management
 * Automatic webhook creation via Postmark API
 * Manual webhook configuration support
 * Built-in webhook testing tools
 * Webhook signature validation (optional)
  • Multi-language Support
 * Available in 7 languages: French, English, German, Spanish, Italian, Portuguese, Dutch
 * All interface elements translated
 * Event labels and descriptions translated
  • Administration pages
 * Main setup: Setup → Modules → PostmarkApp (admin/setup.php)
 * Tab About (admin/about.php): module metadata, README excerpt, contextual help on API sender rules and checking that rich-text help renders as HTML (not raw tags)
 * Tab Changelog (admin/changelog.php): rendered ChangeLog.md (version history)

Requirements

System Requirements

  • Dolibarr: Version 19.0 or higher
  • PHP: Version 7.1 or higher
  • PHP Extensions: cURL (required for API calls)
  • Postmark Account: Active account with at least one server
  • Server API Token: From Postmark dashboard
  • Agenda Module: Must be enabled (mandatory dependency)
  • REST API users: Grant permission postmarkapp->api and assign a Dolibarr API key for each integration account

Postmark Requirements

  • Verified Sender Signatures for the "From" email addresses
  • Server API Token (found in Postmark > Servers > API Tokens)
  • Webhook URL accessible from internet (for event tracking)

Installation

Step-by-Step Installation

  1. Download the module package module_postmarkapp-x.y.z.zip
  2. Extract to htdocs/custom/postmarkapp/ directory
  3. Go to Home > Setup > Modules/Applications
  4. Search for "PostmarkApp" in the module list
  5. Click Enable to activate the module
  6. The module will automatically:
 * Create the llx_postmarkapp_events table
 * Register automatic triggers in Agenda
 * Configure MultiCompany sharing (if MultiCompany module is enabled)
  1. Configure the module in Setup > Modules > PostmarkApp > Settings

Post-Installation

After installation, verify:

  • The llx_postmarkapp_events table exists in your database
  • The Agenda module is enabled
  • Automatic triggers are visible in Setup > Modules > Agenda > Automatic events
  • For REST integrations: Users → Permissions includes postmarkapp->api where needed and API keys assigned

Step 1: Server API Token

The Server API Token is the primary authentication method for Postmark.

  1. Log in to your Postmark account at https://postmarkapp.com
  2. Navigate to Servers and select your server
  3. Go to the API Tokens tab
  4. Copy the Server API Token (starts with a long alphanumeric string)
  5. Paste it in the PostmarkApp configuration page under "Server API Token"
  6. Click Validate to test the connection
  7. If successful, you'll see a green confirmation message

Security Note: The token is stored encrypted in Dolibarr's constants table.

Step 2: Options

  • Message Stream:
 * Select the Postmark message stream to use
 * Default: "outbound" (transactional emails)
 * Alternative: "broadcast" (marketing emails)
 * Streams are automatically loaded from your Postmark account
  • Track Opens:
 * Enable/disable open tracking
 * When enabled, Postmark tracks when emails are opened
 * Only the first open is tracked (PostFirstOpenOnly)
  • Track Clicks:
 * Enable/disable click tracking
 * Requires HTML emails - plain text emails cannot track clicks
 * When enabled, all links in emails are rewritten by Postmark for tracking
  • Replace Dolibarr Mailer:
 * Enable to route ALL Dolibarr emails through Postmark
 * When disabled, Dolibarr uses its native email system
 * Recommended: Keep enabled for consistent tracking
  • API default sender (From)
 * Constant POSTMARKAPP_DEFAULT_FROM_MODE: user (default From = authenticated API user email) or company (default From = main company « mysoc » email from Home → Setup → Company/Organization).
 * For company mode en production: the company email must be a verified Sender Signature in Postmark.
 * Constant POSTMARKAPP_SOCIETE_FROM_CONFIRMED + checkbox « Postmark confirmation » on the setup page: the administrator must explicitly confirm that the company From is authorized on Postmark.
 * Saving in company mode is refused if the mysoc email is missing or syntactically invalid.
 * Test email action uses the configured mode so verification matches production behaviour.
 * Per-request API override remains possible via from_mode (see REST API above).

Step 3: Webhook Configuration (Optional but Recommended)

Webhooks allow Postmark to notify Dolibarr in real-time when email events occur.

Automatic Setup:

  1. Ensure your Server API Token is validated
  2. Click Create Webhook Automatically
  3. The module will:
 * Generate the webhook URL (format: https://yourdomain.com/dolibarr/custom/postmarkapp/webhook.php)
 * Create the webhook in Postmark via API
 * Configure it to listen for: Delivery, Open (First Open Only), Click, Bounce, Spam Complaint
  1. You'll see a confirmation message with the webhook ID

Manual Setup:

  1. Copy the webhook URL displayed in the configuration page
  2. Log in to Postmark dashboard
  3. Go to Servers > Your Server > Webhooks
  4. Click Add Webhook
  5. Paste the URL
  6. Enable the following triggers:
 * Delivery
 * Open (select "First Open Only")
 * Click
 * Bounce
 * Spam Complaint
  1. Save the webhook

Testing Webhooks: The configuration page includes test buttons to simulate webhook events:

  • Test Delivery
  • Test Open
  • Test Click
  • Test Bounce

These send test payloads to your webhook endpoint for verification.

Step 4: Testing

  1. Click Test Connection to verify API connectivity
  2. Click Send Test Email to send a test email to your logged-in user's email address
  3. The test email includes:
 * HTML and plain text versions
 * A trackable link to test click tracking
 * Metadata for webhook linking
  1. Check your email inbox and verify delivery
  2. Use the webhook test buttons to verify event processing

MultiCompany Compatibility

PostmarkApp is fully compatible with Dolibarr's MultiCompany module.

How It Works

  • Each email event is stored with an entity field
  • By default, events are isolated per entity (entity = current entity)
  • Events can be shared between entities if MultiCompany sharing is enabled

Configuration

  1. Enable the MultiCompany module in Dolibarr
  2. Go to Setup > Modules > MultiCompany > Options
  3. Find the "PostmarkApp Events" sharing option
  4. Enable/disable sharing as needed

Sharing Behavior

  • Sharing Disabled: Each entity only sees its own email events
  • Sharing Enabled: Events can be shared between entities (entity IN (0, entity1, entity2, ...))
  • The webhook automatically uses the entity from the original "Sent" event

Entity Assignment

  • When an email is sent, the event is assigned to the current entity ($conf->entity)
  • Webhook events inherit the entity from the original "Sent" event
  • This ensures proper data isolation and sharing

Technical Architecture

Module Structure

postmarkapp/
├── core/
│   ├── modules/
│   │   └── modPostmarkApp.class.php    # Module descriptor, menus, hooks, constants
│   └── substitutions/
│       └── postmarkapp.lib.php         # dol_mail → postmarkapp_sendmail
├── class/
│   ├── actions_postmarkapp.class.php   # Hook handlers (sendMail, mail_begin/end)
│   └── api_postmarkapp.class.php      # Dolibarr REST API (send-email)
├── lib/
│   ├── postmarkapp.lib.php            # Admin tabs, sender helpers (mysoc validation)
│   └── class/
│       ├── postmarkappmail.class.php   # Postmark API wrapper
│       └── lysistech.class.php         # Optional remote last-version URL helper
├── admin/
│   ├── setup.php                       # Configuration
│   ├── about.php                       # About + embedded help
│   └── changelog.php                   # Rendered ChangeLog.md
├── events.php                           # Events list page
├── webhook.php                          # Webhook endpoint
├── API.md                               # Detailed REST documentation
├── ChangeLog.md
└── langs/
    └── [lang]/
        └── postmarkapp.lang             # Translations

Hooks System

The module uses Dolibarr's hook system to intercept email sending:

  • Hook contexts (registered in the module descriptor): mail, sendmail, all
  • Primary hook: sendMail
  • Hook File: class/actions_postmarkapp.class.php
  • Hook Method: sendMail($parameters, &$object, &$action, $hookmanager)
  • Additional handlers: mail_begin, mail_end where applicable for the same contexts

How It Works:

  1. Dolibarr prepares to send an email via CMailFile
  2. The hook intercepts the email before native sending
  3. Extracts email data (to, subject, body, attachments, etc.)
  4. Sends email via Postmark API using PostmarkAppMail class
  5. Logs the "Sent" event to database
  6. Returns 1 to prevent native Dolibarr email sending

dol_mail substitution

When substitution files are loaded, calls to Dolibarr dol_mail() can be diverted to Postmark via postmarkapp_sendmail() in core/substitutions/postmarkapp.lib.php (same prerequisites: module enabled, valid Server Token, Replace Mailer as required). Behaviour matches other intercepted sends (metadata trackid/objects when supplied in extra parameters).

API Integration

The module uses Postmark's REST API:

 * POST /email - Send email
 * GET /server - Test connection
 * GET /message-streams - List streams
 * GET /senders - List sender signatures
 * GET /webhooks - List webhooks
 * POST /webhooks - Create webhook

Database Schema

The module creates one custom table: llx_postmarkapp_events

Column Type Null Default Description
rowid INTEGER NO AUTO_INCREMENT Primary key
email_id VARCHAR(255) NO Postmark MessageID (unique identifier)
event_type VARCHAR(50) NO Event type (Sent, Delivery, Open, Click, Bounce, SpamComplaint)
recipient VARCHAR(255) YES NULL Email recipient address
subject VARCHAR(255) YES NULL Email subject line
fk_soc INTEGER YES NULL Linked third party ID (llx_societe.rowid)
fk_contact INTEGER YES NULL Linked contact ID (llx_socpeople.rowid)
fk_element INTEGER YES NULL Linked element ID (depends on element_type)
element_type VARCHAR(50) YES NULL Element type (propal, facture, commande, etc.)
fk_user INTEGER YES NULL User ID who sent the email (for event ownership)
fk_actioncomm INTEGER YES NULL Linked ActionComm ID (llx_actioncomm.rowid)
event_data TEXT YES NULL JSON data from webhook (full payload)
entity INTEGER NO 1 Entity ID (for MultiCompany)
date_creation DATETIME NO Event timestamp

Indexes:

  • idx_email_id on email_id
  • idx_event_type on event_type
  • idx_date_creation on date_creation
  • idx_fk_soc on fk_soc
  • idx_fk_contact on fk_contact
  • idx_fk_element on fk_element
  • idx_fk_user on fk_user
  • idx_entity on entity

Supported Object Types

The module can link email events to various Dolibarr objects:

Object Type Description Table
propal Customer Proposal llx_propal
commande Customer Order llx_commande
facture Customer Invoice llx_facture
expedition Shipment llx_expedition
contrat Contract llx_contrat
fichinter Intervention llx_fichinter
facture_fourn Supplier Invoice llx_facture_fourn
order_supplier Supplier Order llx_commande_fournisseur
supplier_proposal Supplier Proposal llx_supplier_proposal
project Project llx_projet
ticket Ticket llx_ticket
member Member llx_adherent
reception Reception llx_reception
expensereport Expense Report llx_expensereport

Automatic Triggers

The module registers 6 automatic triggers in Dolibarr's Agenda system:

Trigger Code Label Key Description Key Rang
POSTMARK_SENT PostmarkTriggerSent PostmarkTriggerSentDesc 50100
POSTMARK_DELIVERY PostmarkTriggerDelivery PostmarkTriggerDeliveryDesc 50101
POSTMARK_OPEN PostmarkTriggerOpen PostmarkTriggerOpenDesc 50102
POSTMARK_CLICK PostmarkTriggerClick PostmarkTriggerClickDesc 50103
POSTMARK_BOUNCE PostmarkTriggerBounce PostmarkTriggerBounceDesc 50104
POSTMARK_SPAMCOMPLAINT PostmarkTriggerSpam PostmarkTriggerSpamDesc 50105

These triggers are:

  • Automatically registered on module activation
  • Automatically enabled (constants MAIN_AGENDA_ACTIONAUTO_* set to 1)
  • Configurable in Setup > Modules > Agenda > Automatic events
  • Can trigger custom workflows based on email events

Permissions

The module defines three permissions:

  • postmarkapp_read: View email events (required for events list page; menu Tools → PostmarkApp events / events.php)
  • postmarkapp_setup: Configure the module (required for setup page)
  • postmarkapp_api: Call the Dolibarr REST endpoint postmarkappapi/send-email

Permissions are checked using: if ($user->hasRight('postmarkapp', 'read')) if ($user->hasRight('postmarkapp', 'setup')) if ($user->hasRight('postmarkapp', 'api'))

Remote version check (optional)

The module descriptor can expose LysisTech::getLastModuleVersionUrl() so Dolibarr may query a remote « last version » string. Restricted outbound HTTPS environments may log failures unrelated to runtime sending. Define DOLIBARR_LYSIS_SKIP_VERSION_CHECK in conf/conf.php to silence that check when needed (same pattern as other Lysis-published modules).

Menu

  • Events list appears under Tools (not a dedicated top-level main menu).

Important module constants

In addition to token and webhook settings, noteworthy keys include:

  • POSTMARKAPP_DEFAULT_FROM_MODE: user or company — default REST API sender mode
  • POSTMARKAPP_SOCIETE_FROM_CONFIRMED: admin confirmation flag for Postmark-aligned company sender
  • MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML: enforced by activation when HTML/click-tracking behaviour is desired (already documented above)

Webhook Processing

The webhook endpoint (webhook.php) processes incoming Postmark events:

  1. Receives POST request from Postmark with JSON payload
  2. Validates webhook signature (optional, if configured)
  3. Extracts event data (type, recipient, message ID, metadata)
  4. Searches for original "Sent" event by MessageID
  5. Retrieves linked objects (third party, contact, element) from original event
  6. Creates ActionComm event in Dolibarr's Agenda
  7. Sets event ownership to original sender's user ID
  8. Links event to original ActionComm (parent-child relationship)
  9. Stores detailed event data in llx_postmarkapp_events table
  10. Returns HTTP 200 to Postmark

SQL Queries and MultiCompany

All SQL queries use getEntity() function for MultiCompany compatibility:

SELECT * FROM llx_postmarkapp_events WHERE entity IN (getEntity('postmarkapp_events'))

This ensures:

  • Data isolation per entity (by default)
  • Data sharing when MultiCompany sharing is enabled
  • Proper entity assignment on insert

How It Works

Email Sending Flow

  1. User triggers email sending in Dolibarr (e.g., sending an invoice)
  2. Dolibarr prepares CMailFile object with email data
  3. PostmarkApp hook intercepts via sendMail hook
  4. Module extracts:
 * Recipient(s), subject, body (HTML/text), attachments
 * Linked objects (from trackid or metadata)
 * Current user ID (for event ownership)
  1. Email sent via Postmark API
  2. Postmark returns MessageID
  3. Module logs "Sent" event to database with:
 * MessageID, recipient, subject, linked objects, user ID, entity
  1. Returns 1 to prevent native Dolibarr email sending

Webhook Event Flow

  1. Postmark detects email event (delivery, open, click, bounce, spam)
  2. Postmark sends POST request to webhook URL with JSON payload
  3. Webhook endpoint receives and validates request
  4. Searches for original "Sent" event using MessageID
  5. Retrieves:
 * Linked objects (third party, contact, element)
 * User ID who sent the email
 * Entity ID
 * Original ActionComm ID
  1. Creates new ActionComm event:
 * Type: AC_EMAIL
 * Code: POSTMARK_[EVENT_TYPE]
 * Label: Translated event label
 * Owner: Original sender's user ID
 * Parent: Original ActionComm ID
 * Linked to: Third party, contact, element
  1. Stores event in llx_postmarkapp_events table
  2. Returns success to Postmark

Event Linking

Events are automatically linked to Dolibarr objects:

  • From trackid: Parses Dolibarr's trackid format (e.g., "pro1" = proposal ID 1)
  • From metadata: Extracts fk_soc, fk_contact, fk_element, element_type
  • From recipient email: Searches third parties and contacts by email address
  • From MessageID: Webhook events link to original "Sent" event via MessageID

Event Types

Event Type Description When It Occurs Dolibarr Code ActionComm Type
Sent Email sent via Postmark Immediately after API call POSTMARK_SENT AC_EMAIL
Delivery Email delivered When recipient's server accepts POSTMARK_DELIVERY AC_EMAIL
Open Email opened First time recipient opens email POSTMARK_OPEN AC_EMAIL
Click Link clicked When recipient clicks a tracked link POSTMARK_CLICK AC_EMAIL
Bounce Delivery failed Email rejected by recipient's server POSTMARK_BOUNCE AC_EMAIL
Spam Complaint Marked as spam Recipient reports email as spam POSTMARK_SPAMCOMPLAINT AC_EMAIL

Troubleshooting

Emails Not Sending

  1. Verify POSTMARKAPP_REPLACE_MAILER constant is set to 1
  2. Check Server API Token is valid (use "Test Connection" button)
  3. Verify "From" email address is a verified Sender Signature in Postmark
  4. Check Dolibarr logs (dolibarr.log) for error messages
  5. Ensure cURL extension is enabled in PHP
  6. Verify internet connectivity from server to Postmark API

Webhooks Not Received

  1. Verify webhook URL is accessible from internet (test with curl or browser)
  2. Check webhook is created in Postmark dashboard
  3. Verify webhook triggers are enabled (Delivery, Open, Click, Bounce, Spam)
  4. Test webhooks using built-in test buttons in configuration page
  5. Check server logs for incoming POST requests to webhook.php
  6. Verify webhook URL doesn't require authentication (webhook uses NOLOGIN)

Click Tracking Not Working

  • Click tracking requires emails to be sent in HTML format
  • Plain text emails cannot track clicks
  • Ensure MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML is enabled
  • Verify "Track Clicks" option is enabled in configuration
  • Check that links in emails are not already rewritten by another system

REST API errors (send-email)

  1. 401 / 403: Confirm header DOLAPIKEY, user login bound to that key has postmarkapp->api, module PostmarkApp enabled
  2. 400 (sender): No valid From — set the API user email, or configure a valid Company email matching a Postmark Sender Signature; in company mode check setup validation and confirmation checkbox
  3. Consult dolibarr.log and full examples in API.md

Events Not Appearing in Agenda

  1. Verify Agenda module is enabled
  2. Check automatic triggers are enabled in Setup > Modules > Agenda > Automatic events
  3. Verify user has permission to view ActionComm events
  4. Check llx_postmarkapp_events table has data
  5. Verify webhook is receiving and processing events (check logs)

MultiCompany Issues

  1. Verify MultiCompany module is enabled
  2. Check entity field exists in llx_postmarkapp_events table
  3. Verify sharing configuration in Setup > Modules > MultiCompany > Options
  4. Check SQL queries use getEntity('postmarkapp_events')
  5. Verify entity is correctly assigned on email send

Screenshots

Changelog

Current release (module descriptor: 1.5.27)

See also ChangeLog.md inside the package and the Changelog tab in administration.

Version 1.5.25

  • Documentation reminders: REST API sender configuration (user / company, confirmation), About page help (API response fields from_mode / from_source, HTTP 400 if no sender, HTML rendering of help)

Version 1.5.24

  • Module icons: addition of correct img/ files so Dolibarr img_object URLs no longer return 404

Version 1.5.23

  • Changelog tab in administration; About page aligned with Dolibarr module info layout

Version 1.5.22

  • About page displays ChangeLog.md correctly again alongside README

Version 1.5.10

  • Default REST sender constants POSTMARKAPP_DEFAULT_FROM_MODE and POSTMARKAPP_SOCIETE_FROM_CONFIRMED
  • Setup UI: sender mode selection, displayed mysoc email, link to company card, mandatory Postmark confirmation in company mode, save blocked if enterprise email invalid, test mail aligned with mode
  • REST send-email: optional from_mode, user_id, response metadata from_mode / from_source, structured errors instead of anonymous noreply fallback
  • Helpers postmarkapp_get_mysoc_sender(), postmarkapp_is_valid_sender_email()

Version 1.5.2 (2026-01-06)

  • Added MultiCompany compatibility
  • Added entity field to database
  • Implemented getEntity() in all SQL queries
  • Added MultiCompany sharing configuration
  • Added user ownership for events (fk_user field)
  • Enhanced object type support (supplier invoices, orders, projects, tickets, etc.)
  • Improved event linking (from trackid, metadata, recipient email)
  • Simplified event notes and labels
  • Removed duplicate "Sent" event (relies on Dolibarr's native system)
  • Added bilingual documentation
  • Added multi-language support (7 languages)
  • Added automatic trigger activation
  • Enhanced webhook processing with entity inheritance
  • Added comprehensive event filters
  • Added reference search for linked objects

Version 1.5.0 (2026-01-06)

  • Initial release
  • Postmark API integration
  • Webhook handling
  • Event tracking
  • Agenda integration
  • Object linking

Links

License

This module is distributed under the GNU General Public License v3 (GPLv3).

Professional Services / Services professionnels

English

Need help with setup? We can assist you with:

  • Installation and configuration of the PostmarkApp module
  • REST API integrations (DOLAPIKEY, from_mode, attachments)
  • Postmark account setup and sender signature verification
  • Webhook configuration and testing
  • Integration with your existing Dolibarr workflows
  • MultiCompany configuration and data migration
  • Custom development and feature requests
  • Training for your team

Contact us for a personalized quote: https://lysis.net

Français

Besoin d'aide pour le paramétrage ? Nous pouvons vous accompagner pour :

  • L'installation et la configuration du module PostmarkApp
  • Les intégrations API REST (DOLAPIKEY, from_mode, pièces jointes)
  • La création de votre compte Postmark et la vérification des signatures d'expéditeur
  • La configuration et les tests des webhooks
  • L'intégration avec vos processus Dolibarr existants
  • La configuration MultiCompany et la migration de données
  • Le développement sur mesure et les demandes de fonctionnalités
  • La formation de vos équipes

Contactez-nous pour un devis personnalisé : https://lysis.net

Author

Alex BORDARAUD
Website: https://lysis.net