Skip to content
Linn Systems edited this page Sep 4, 2018 · 19 revisions

Linnworks.net Macros - A brief guide

General

This document is intended for macro developers. Please note that there is a shift in the way that macros are treated in Linnworks.net. Macros are added to a developer’s account and are installed on a user’s account as an application. Without the desktop environment, new macros are run via our servers and as such, there will be a cost associated with the runtime they use. In the current state of the closed beta, this is not in place. With the system being in closed beta, there is a continuous process of updates and refinements. Updates on macros can be found

Billing

Developers will be billed for macro run time. This is not currently implemented, but will be inplace in the near future. As it will be developer accounts that will be charged for macro run time,it is suggested that developers consider an application payment plan when the application iscreated.

Triggers

Currently, macros can be fired by the rules engine on orders, as an action or via a schedule or via the API as part of of a wider part of customisation.

Participation

In order to take part in the closed beta, you will need to request access either via the Ticket system under the API support category or directly from Nik (​nik@linnsystems.com​). Please note that, currently (03/01/18) all customers who want to use the application need to be added to the beta by a member of Linn Systems

Installation

Code must be pasted into the developer portal (​https://developer.linnworks.com/​), which also provides compilation, basic syntax highlighting and debug information in the case of compile errors. An example is provided later in this document.

Macro Format

The new macro framework uses .net Core 1.0. Each macro uses a standard format and has access to the standard Linnworks.net API built in, so there is no need for authorization steps. A standard visual studio solution is available that has several projects that will allow developers to test macros without running them on Linnworks servers, by providing application credentials and a valid token. The solution is available ​here​.

Each macro must contain an Execute method, as per the LinnworksMacro.cs file in the LinnMacroCustomer example project. The execute method can have any parameters passed to it, including complex types and may also have any return object.

Namespaces

The references given in the example solution are the only available namespaces. Please note that this is not extensible by developers. Unknown namespaces will be ignored and result in compile errors.

Limitations

Macros do not currently have access to communicate externally. At this time, this includes all System.Net and System.Web namespaces.

Releases

  • File transfers via FTP/FTPS/SFTP
  • Send emails
  • Passing parameters to a macro
  • Macro logger

Resource Use

Macros can be measured in both run time and memory usage. Run times can be defined in the edit macro screen between 30 seconds and 5 minutes (specified in seconds). At the defined timeout period, the runtime is ended, regardless of whether the execution is finished. Plan Type,which equates to memory usage, has the same kind of restrictions and resolution. The plan type allocations are:

Plan Type Memory (in Mb)
Small 256
Medium 512
Large 1024

Usage Warning

It is possible for a macro to kick off a rules engine evaluation.​ This will then potentially trigger another execution of the macro. If you are writing code that requests a re-evaluation of the rules engine, please make sure that safeguards are in place in your macros to avoid an infinite loop of macro triggering rules engine, which triggers the same macro. There are no safety nets in place. Causing an infinite loop will only be stopped if the developer account runs out of funds to allow subsequent runs. There is no specific recommended method, as this is an edge case of API use. One solution may be to set an order extended property on the order to flag that the macro has been run.

Examples

Rules Engine Triggered - Developer Actions

The following code is designed to be run as an action of a rules engine execution. Rules engine execution will automatically pass a parameter called OrderIds that is an array of Guids. This script adds a note to the order and locks it to alert staff members that it needs particular attention. For instance, the order is over a certain value and doesn’t have a tracked shipping service. The logic to identify the orders would be carried out in the rules engine, but the use of a macro allows notes to be added to orders, which is not available through the rules engine. In the following example, there is no need for a return type.

using LinnworksAPI;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinnworksMacro
{    
    public class LinnworksMacro : LinnworksMacroHelpers.LinnworksMacroBase    
    {        
        public void Execute(Guid[] OrderIds) 
        {            
            Api.Orders.LockOrder(OrderIds.ToList(), true);
            foreach (var o in OrderIds)            
            {
                Api.ProcessedOrders.AddOrderNote(o, "Order is high value without tracked shipping!", true);
            }
        }
    }
}

Logging into the developer portal and clicking on the Macros menu item and adding a new macro gives the following screen:

Name: Name must between a length of 1 and 30 characters, and only allows numbers, letters and underscores

Execution Type​: See ​Triggers

Plan Type​: See ​Resource Use

Description​: This is shown to the customer, so please make it as descriptive as possible if your macro will be widely available. Once created, double clicking the entry in the macro screen will bring up the edit dialog. Here there is a tab to paste in your macro code. The entire namespace and using statements need to be pasted into the editor.

Clicking compile and save will show debug information at the bottom of the screen in the case that the macro could not compile. In order for a customer to run a macro, they must install an application. It is recommended that an application type of System Integration is used. The following is an example manifest for the macro previously described.

{    
    "LinnworksPermissions": [],
    "Modules": [
        { 
           "RequiredPermissionId": null,
            "moduleName": "MyExampleMacro",
            "formattedName": "Example .net Rules Engine Macro",
            "icon": "fa fa-usd",
            "path": "",
            "type": "MacroModule",
            "group": [],
            "parameters": [
                {
                    "name": "MacroName",
                    "value": "ExampleMacro"
                }
            ],
            "files": null
        }
    ]
}

In order for the manifest to work correctly, there must be a module with a type of ​MacroModule​. In the parameters, there must be an entry with where the name is ​MacroName​, and a value which matches the name of the macro as entered in the macros screen. In our example, this is called ​ExampleMacro​. This manifest can then be saved and installed. It is possible, as with other application types, to have multiple modules in an application manifest. Please note that once an application with a macro in the manifest has been installed, the plan type, execution length and code cannot be changed. There is no versioning on macros, as there is with application manifests.

Rules Engine Triggered - Customer Actions

Once a customer has installed the application, either via installation URL or the application store, if the app is public, it needs to be “configured” by the customer. Once added to the macros beta, customers will have access to the macro configuration functionality, which is stored under the Apps menu:

Opening this screen will show all currently configured macros. Despite there currently being nouser configuration of rules engine macros, this may not always be the case. For this reason, click Add New Configuration. A new window will appear that shows all unconfigured scheduled and rules engine macros. Select the rules engine macro and click Create Configuration.

The configuration must be named, which can be done after Create Configuration is clicked. It is important to note that when assigning this as a rules engine execution action, the configuration name is used. This is in order to support parameters being passed to the code in the future. Ensure that the configuration is enabled in the macro configuration screen and refresh Linnworks. You can then set this configuration as a rules engine execution action:

The normal Linnworks workflow of saving the rule and enabling it still apply.

Scheduled Macros - Customer Actions

Similar to rules engine macros described above, macros can be scheduled by a customer to occur as and when they wish.

Macros designed to be used as scheduled macros have no required parameters. Again, they will accept custom parameters in the future. Similarly, they should be considered void methods, as nothing can be done with any returned values.

Scheduled macros are entered into the developer portal in exactly the same way as rules engine macros, as described above, with the exception of their type. The manifest has no special requirements.

Once installed by a customer, they will have to configure the macro in the same way as previously described. The interface will detect that it is a scheduled macro and instead of supplying just the configuration name, a schedule will have to be established by clicking New Schedule:

The scheduling process is similar to how schedules are designed in Linnworks.net > Data Import / Export and so should be familiar.

Once saved and enabled, the job will be scheduled to run at the time(s) given in the configuration.

API Macros

One use case for API macros could be native application that compiles stats on Linnworks data and then displays these to the user in a dashboard format. The application calls the macro run on the initialize and uses the return object to build the dashboard.

This type of macro can be run via the Linnworks.net api. The type of the macro needs to be set to API and the manifest is identical to the other examples in this thread.

To run a macro you need to send a POST request to the Macro/Run endpoint. The endpoint takes a FormDataCollection ​as the only parameter. The collection must contain an entry for macroName ​and applicationName​. For instance, if you also wished to pass a string called folderName, the collection might look like: applicatioName=MyApplication&macroName=MyAPIMacro&folderName=SendToday.

The maximum request length is 100kb.

The request is also case insensitive, so including properties named Example and example will pick one of these properties.

The return type from the macro will be passed back to the calling method as an object to be deserialized or cast as appropriate.

Using the SDK

SDK vs Developer Portal

The SDK is designed to aid a developer in creating macros before they added to the developer portal. The edit macro screen in the developer portal is not intended for use as a development environment. There are no plans to include any further features in this editor. Features such as intellisense (autocomplete) are available through .net capable IDEs such as visual studio (or VS Code), JetBrain’s Rider or Eclipse with a plugin like aCute. Whilst debugging capability may vary across these IDEs, this guide was produced using Visual Studio 2017.

The developer portal is also not capable of running the code and debugging. The SDK has been designed to give you a mocked environment to run macros.

SDK Projects

The SDK contains multiple projects:

  • LinnworksMacro: ​Where your macro code should be written
  • LinnMacroCustomer:​ Allows you to mock the macro framework and execute the macro code.
  • LinnworksAPI: For reference only. ​Modifying the API will not propagate to the live macro framework and compilation may fail when adding your macro code to the developer portal.
  • LinnworksMacroHelpers: For reference only.​ Similar to the API, this cannot be modified. In time helper methods will be added to this project when the need arises. These methods will be available in the live environment.

The SDK is designed to mimic the live environment. When you have created a macro, you only need to add the code from the LinnworksMacro.LinnworksMacro.cs file into the portal as described previously.

LinnworksMacro

This project contains a single file, named LinnworksMacro.cs. By default, it contains a sample macro that takes a StockItemId guid and returns a StockItemInv class. This particular example is designed to be used as an API macro, hence it has a return class.

To be consistent, this documentation will use the rules engine example code from above

LinnMacroCustomer

This is a console application that sets up an API context which allows the macro’s execute method to use the Linnworks API. The project has a single Program.cs file.

To use the API in any form a session is needed and hence in the file, you are prompted to give an application Id, application secret and application token.

It is recommended to create a test application in the developer portal for testing macros with, installing it on your own developer Linnworks.net account. The application type can be a system integration with the default manifest.

After adding these properties, the program uses authorize by application to get a session, passing elements of this session to the API context. It then calls macro.Execute. In the example below, the default project has been altered to match the input and output parameters of the macro.

Debugging

Please note that all API calls are live and will modify the Linnworks database straight away, rather than requiring any kind of save step such as the order object would have needed in an old Desktop order script. It is highly recommended that test orders are available when debugging new macro code. Similarly for API calls that modify a user’s Linnworks system, such as deleting system currency conversions, linnworks locations or printing documents, are also live and so appropriate test data and scenarios should be set up to debug.

Setting a breakpoint (VS Shortcut F9) at the top of your Execute method will allow you to step through the code and inspect the objects as they are set. Running the LinnmacroCustomer project will execute the code up to the first breakpoint.

Please be aware that using commands such as writing to the console or local file system will have no effect in the production environment and so appropriate use of breakpoints and either object explorer or the Immediate Window (or IDE equivalent) would be more appropriate.

The modified code below shows an example of inspecting an order:

Alternatively using the Immediate Window:

Please note that this kind of debugging is only available when the code execution is paused at a breakpoint.

Clone this wiki locally