Goal: Send a Newsletter that is based on a Mailing Template but also contains content that is dynamically gathered and rendered with CSEREST request to an external system whenever a customer Entry is created or modified.
Info |
---|
You can download the whole Kickstarter-based sample application from our GitLab repository: um-public/tutorial-dynamic-newsletter-contentsyncqueue |
Start a new Kickstarter project
Codeblock |
---|
|
umkickstarter -n de.pinuts.tutorial
cd umkickstarter
# Copy your partner license file to env/devel/cmsbs-conf/cmsbs.license |
Include dependency
Hinweis |
---|
Since UM 7.55 the SyncQueue plugin is already included and will be automatically installed by the installer. In this case you must not include the following dependency. See also https://pinutswiki.atlassian.net/wiki/spaces/UMDOC/pages/4475551745/Universal+Messenger+7.55.0+EN#SyncQueue. |
Edit build.gradle
and add the following dependency:
Codeblock |
---|
|
dependencies {
[...]
runtime('de.pinuts.cmsbs:SyncQueue:1.5.0')
} |
Now, setup and restart:
Codeblock |
---|
|
gradle setup run |
Implement and register CommitCallback
Create a new (M)JS file: cmsbs-conf/cse/plugins/de.pinuts.tutorial/shared/CommitCallback.mjs
:
Codeblock |
---|
|
/// <reference path="../../../.vscode.js"/>
class MyCommitCallback extends CommitCallback {
/**
* @param {Entry} e
*/
preCommit(e) {
if (e.get('entrytype') == 'customer') {
console.log('preCommit:', e);
}
}
/**
* @param {Entry} e
*/
postCommit(e) {
if (e.get('entrytype') == 'customer') {
console.log('postCommit:', e);
}
}
/**
* @param {Entry} e
*/
preRemove(e) {
if (e.get('entrytype') == 'customer') {
console.log('preRemove:', e);
}
}
}
CommitCallback.registerCallback(() => new MyCommitCallback()); |
Open http://localhost:8080/cmsbs, login as admin
/ admin
and create, edit and delete a Customer entry.
Take a look at the console / shell where you started the UM: For each transaction the according Entry should be logged.
Setup a SyncQueue instance
Create a new file cmsbs-conf/cse/plugins/de.pinuts.tutorial/shared/queue.mjs
:
Codeblock |
---|
|
/// <reference path="../../../.vscode.js"/>
import SyncQueue from "@de.pinuts.cmsbs.syncqueue/shared/SyncQueue.es6";
import HttpClientBuilder from "@de.pinuts.http/shared/HttpClientBuilder.es6";
const client = new HttpClientBuilder()
.build();
const fn = (payload) => {
console.error('SyncQueue:', payload);
const e = UM.getEntryByOid(payload.oid);
let ret;
if (e) {
client.post(`http://localhost:8080/tutorial/customer/${e.oid}`)
.setJsonData({
oid: e.oid,
firstname: e.get('firstname'),
lastname: e.get('lastname'),
email: e.get('email'),
})
.execute()
.catch(rsp => {
console.error('HTTP request failed:', rsp.status);
ret = `HTTP error: ${rsp.status}`; // string = recoverable error
})
.then(rsp => {
ret = true; // true = success
});
} else {
// Send DELETE request...
}
return ret;
}
export const queue = new SyncQueue(fn)
.setName('tutorial')
.setMaxRetries(5)
.setRunOnPush(true)
.register(); |
Queue Entry updates
Now that we have a SyncQueue set up and a handler function in place to propagate any Customer updates, we can update our CommitUpdate to actually use the Queue:
Codeblock |
---|
|
import { queue } from "./queue.mjs";
[...]
/**
* @param {Entry} e
*/
postCommit(e) {
if (e.get('entrytype') == 'customer') {
queue.push({ oid: e.oid });
}
}
/**
* @param {Entry} e
*/
preRemove(e) {
if (e.get('entrytype') == 'customer') {
queue.push({ oid: e.oid });
}
}
[...] |
Test run
Now, edit or create a Customer entry and go to Tools / SyncQueue Dashboard.
You will notice a waiting (or failed) request for each creation or update operation you did. The HTTP requests will all fail with a 404 because there actually is no endpoint to receive our POST requests.
To make this work, you could implement a REST endpoint as a mockup and change the URL accordingly.