🗞️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.

  • 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_channel Checks channel links instead of mainchannel for destination and channel selection when set.

  • use_any_channel Matches channel_selection for both main channel and channel.

  • sorting Optional list sorting specification.

  • transformations The optional transformations to be performed on copied articles.

Transformations

  • name Optional transformation description.

  • channel_selection Transformation is only applied to article copies with these mainchannels. If not set or empty channel_selection the transformation will be applied to articles with any mainchannel.

  • conditions Optional conditions to filter articles by matching blocks or properties for which the transformation should be applied.

  • updates The 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

  • match Match all blocks and properties that are listed in the defined path or all if no path is set.

  • no_match Check 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" or 0 - find anywhere in the document Links, Content or Meta and the default value

  • "Links" or 1 find in document Links

  • "Content" or 2 find in document Content and

  • "Meta" or 3 find 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_blocks Removes the specified blocks in a specified path if found.

  • add_blocks Adds the specified blocks in a specified path.

  • set_properties Set 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_status Set 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_sort sorts 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_property is optional and applies sorting before grouping when used.

  • group_property is optional and applies grouping by a property or block. Must be specified when group_pattern is used since the group_pattern uses the value from group_property.

  • group_pattern is used for grouping in a specified order and not for example alphabetically, see below for type of grouping with type.

Sort and group property

  • property for 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.

  • block Used for looking up a document block value. The name of the block property is given in the value_field. To lookup a value from block data the data field should be prefixed by "data:" in the value_field.

  • type The sort type for string or number.

  • descending Sorts the elements descending if set to true. Not applicable for grouping when group_pattern is 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.

  • SortString or 0 is the default

  • SortInt or 1

  • SortFloat or 2

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.

  • GroupDefined or 3 which means the articles are grouped in the group pattern defined.

  • GroupRolling or 4 takes 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 list
  • Ensure 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_COMPLETE
  • Deploy the latest version:

deploy-manager deploy --branch [dev|release] --version [latest version] --region [your wanted region] {--service effingo}

Last updated