🗞️Effingo
Effingo is a SaaS service to copy Naviga Doc articles to print articles, update the articles according to a configuration and connect the articles to a list.
API
The API consists of a lambda function which is called through a load balancer. There's also a S3 bucket for storing conversion rules configurations. The API is implemented using Twirp and therefore supports both protobuf and Rest calls.
Endpoints
GetConfiguration - Get specified transformation configuration.
AddConfiguration - Add transformation configuration.
RemoveConfiguration - Remove transformation configuration.
CopyListArticles - Copy articles and connect the copies to a list using transformation configuration and sets the publication date.
PrintArticle - Copy an article using transformation configuration and sets the publication date.
NavigaID permissions
AddConfiguration and RemoveConfiguration requires permission
"effingo:administration".CopyListArticles, PrintArticle and GetConfiguration requires permission
"effingo:user.
Transform Configuration
A transform configuration is used for specifying conditions and updates for example set properties, add and remove blocks.
Transformation fields use_channel and use_any_channel controls if mainchannel, channels or both should be checked to match channel_selection. The same property will be updated for the article copy.
When optional transformation field use_any_channel is set to true the channel selection is checked for either a matching mainchannel link or channel link.
For reference about the navigadoc document format see https://github.com/navigacontentlab/navigadoc.
There is one configuration for each unit. The configuration is stored per organisation and unit.
The configuration has a number of updates which is applied either per mainchannel or to all articles. The operations can be conditioned to match/not match a property or block, for example a specific category.
The action can be add or remove a block and/or property. For blocks the path should be specified to the articles content, meta or links section.
Configuration
use_channelChecks channel links instead of mainchannel for destination and channel selection when set.use_any_channelMatches channel_selection for both main channel and channel.sortingOptional list sorting specification.transformationsThe optional transformations to be performed on copied articles.
Transformations
nameOptional transformation description.channel_selectionTransformation is only applied to article copies with these mainchannels. If not set or emptychannel_selectionthe transformation will be applied to articles with any mainchannel.conditionsOptional conditions to filter articles by matching blocks or properties for which the transformation should be applied.updatesThe updates for setting properties, document status and removing and adding blocks.
Replacing a block can be accomplished with remove_block followed by aadd_block updates.
Conditions
matchMatch all blocks and properties that are listed in the defined path or all if no path is set.no_matchCheck that no listed block or property is set in the defined path or all if no path is set.
Possible path values in add_blocks and remove_blocks for limiting the match to a document section are
"Any"or0- find anywhere in the document Links, Content or Meta and the default value"Links"or1find in document Links"Content"or2find in document Content and"Meta"or3find in document Meta.
Match and NoMatch checks listed blocks, listed properties and optional document status. Static document properties that can be checked with properties name/value are
"status"
"provider"
"language"
"published" and
"unpublished".
Updates
The update can remove blocks, add blocks and set properties. Replacing a blocks is accomplished by remove and add block.
remove_blocksRemoves the specified blocks in a specified path if found.add_blocksAdds the specified blocks in a specified path.set_propertiesSet document properties. If a property value is empty the property will be removed. Static properties that can be updated are the same as listed above for match/no_match.document_statusSet the document status to the specified value.
Example: General transformation for source article main channel with conditions and updates
{
"use_channel": false,
"transformations": [
{
"name": "Transformation description",
"channel_selection": [
"source-channel-id"
],
"conditions": {
"document_status": "required-document-status",
"match": {
"properties": [
{
"name": "property-name",
"value": "match-property-value"
}
],
"blocks": [
{
"a-block-property": "match-block-property-value"
}
]
},
"no_match": {
"properties": [
{
"name": "property-name",
"value": "no-match-property-value"
}
],
"blocks": [
{
"a-block-property": "no-match-block-property-value"
}
]
},
"updates": {
"set_properties": {
"properties": [
{
"name": "property-name",
"value": "set-property-value"
}
],
"remove_blocks": {
"path": 0,
"blocks": [
{
"a-block-property": "match-value"
}
]
},
"add_blocks": {
"path": 1,
"blocks": [
{
"block-property-1": "set-value",
"block-property-2": "set-value"
}
]
}
}
}
}
}
]
}Sorting and grouping
The articles in the list can be sorted and grouped in descending or ascending order by adding the sorting clause.
Sorting
insert_sortsorts inserted articles by best effort but does not change the sorting for the existing articles in the list. When insert_sort is not set articles are added last in the list. Default is false.sort_propertyis optional and applies sorting before grouping when used.group_propertyis optional and applies grouping by a property or block. Must be specified whengroup_patternis used since thegroup_patternuses the value fromgroup_property.group_patternis used for grouping in a specified order and not for example alphabetically, see below for type of grouping withtype.
Sort and group property
propertyfor sorting or grouping by document property value or property parameter. Use value_field "parameters:name" to lookup parameter "name". Default for value_field is "value" which looks up the property value.blockUsed for looking up a document block value. The name of the block property is given in thevalue_field. To lookup a value from block data the data field should be prefixed by "data:" in the value_field.typeThe sort type for string or number.descendingSorts the elements descending if set to true. Not applicable for grouping whengroup_patternis being used.
To use a value for a block stored in data use prefix data: for the value_field.
To use a parameters value for properties use prefix parameters: for the value_field.
The value_field is case insensitive.
The sort_property type can be set to sort as string, integer or float.
SortStringor0is the defaultSortIntor1SortFloator2
The group_property type can be set to sort as string, integer or float. When group_pattern is used the type can be set to group by pattern in two different ways.
GroupDefinedor3which means the articles are grouped in the group pattern defined.GroupRollingor4takes the first article with the specified pattern, according to the sorted values value and then the next value and starts over if there are more articles.
Example: Sort and group by pattern
Sort articles descending according to the number property priority and group according to the pattern.
{
"sorting": {
"insert_sort": true,
"sort_property": {
"property": {
"name": "priority"
"value": "value"
},
"type": 1
"descending": true
},
"group_property": {
"block": {
"type": "x-im/articletype"
},
"value_field": "title"
},
"group_pattern": "A,B,C"
"descending": false
}
}Transform Configuration Examples
Example: Remove and add blocks
{
"use_channel": false,
"transformations": [
{
"name": "Remove and add blocks",
"channel_selection": [
"source-channel-id"
],
"conditions": {
"match": {
"path": 1,
"blocks": [
{
"uuid": "4c03eca0-326b-11ed-af7a-bbd62d8bfb54",
"type": "x-im/category",
"title": "Sport/Football",
"rel": "subject"
}
]
}
},
"updates": {
"remove_blocks": {
"path": 1,
"blocks": [
{
"uuid": "4c03eca0-326b-11ed-af7a-bbd62d8bfb54",
"type": "x-im/category",
"title": "Sport/Football",
"rel": "subject"
}
]
},
"add_blocks": {
"path": 1,
"blocks": [
{
"uuid": "81262a06-3045-11ed-9301-db925349924b",
"type": "x-im/section",
"title": "News/sport",
"rel": "subject"
}
]
}
}
}
]
}Example: Remove x-im/teaser block
{
"use_channel": false,
"transformations": [
{
"name": "Remove x-im/teaser block",
"channel_selection": [
"source-channel-id"
],
"conditions": {
"match": {
"path": 1,
"blocks": [
{
"type": "x-im/teaser"
}
]
}
},
"updates": {
"remove_blocks": {
"path": 1,
"blocks": [
{
"type": "x-im/teaser"
}
]
}
}
}
]
}Example: Change property
{
"use_channel": false,
"transformations": [
{
"name": "Change property",
"channel_selection": [
"source-channel-id"
],
"conditions": {
"document_status": "required-status",
"match": {
"properties": [
{
"name": "imext:haspublishedversion",
"value": "true"
}
]
}
},
"updates": {
"set_properties": {
"properties": [
{
"name": "imext:haspublishedversion",
"value": "false"
}
]
}
}
}
]
}Example: Set document status
{
"transformations": [
{
"name": "Set document status",
"channel_selection": [
"source-channel-id"
],
"conditions": {
"document_status": "match-document-status"
},
"updates": {
"document_status": "new-document-status"
}
}
]
}Deployment
To deploy the effingo service in a specific region you can do the following.
Install infomaker/core/deploy-manager with brew.
Checkout this project and go to the project folder.
Set the aws profile and region for example. The region should be eu-west-1 since that's where deploy-manager is running.
export AWS_REGION=eu-west-1
export AWS_PROFILE=[im-saasdev|im-saasstage|im-saasprod]Ensure that the ssm parameters exists in region and environment:
deploy-manager ssm ensure --region [your wanted region] {--service effingo}Create bindings note the branch value must match the profile used (im-saasdev|im-saasstage|im-saasprod) Get the bindings for the environment.
deploy-manager bindings get {--service effingo}If bindings can't be found the should be created, otherwise just add the wanted region:
deploy-manager bindings create --branch [dev|release] --region [your wanted region] {--service effingo}or
deploy-manager bindings update --add-region [your wanted region] {--service effingo}List bindings:
deploy-manager bindings listEnsure pipelines using:
deploy-manager pipelines ensure --template ci/pipeline.yml {--service effingo}You should see that the new region is being created for example:
eu-west-1 CREATE_IN_PROGRESS
eu-west-1 CREATE_COMPLETEDeploy the latest version:
deploy-manager deploy --branch [dev|release] --version [latest version] --region [your wanted region] {--service effingo}Last updated