Appmixer CLI
Appmixer command-line tool.
Use the Appmixer CLI tool to interact with the Appmixer engine remotely from the command line. It can be used to list flows, start/stop flows but more importantly, to develop and publish custom components.
npm install -g appmixer
Display the command options with the
-h
option:$ appmixer -h
Usage: appmixer [options] [command]
Appmixer command line interface.
Options:
-v, --version output the version number
-h, --help output usage information
Commands:
download|d Download component.
flow|f Flow commands.
init|i Initialize component.
login|l Login into Appmixer API.
logout|o Logout from Appmixer API.
pack|p Pack component into archive.
publish|pu Publish component.
remove|rm Remove component.
test|t Test component, authentication module, ...
url|u <url> Set Appmixer API url.
help [cmd] display help for [cmd]
Go to https://docs.appmixer.com/appmixer/ to find more information.
Each command has its own help information:
$ appmixer flow -h
Usage: appmixer flow <command>
Flow commands.
Options:
-h, --help output usage information
Commands:
start|s <flowId> Start flow.
stop|t <flowId> Stop flow.
remove|r <flowId> Remove flow.
ls|l [flowId] Ls flow.
help [cmd] display help for [cmd]
First set the Appmixer API URL. This is the URL of your hosted Appmixer engine instance or your own custom URL where the self-managed engine is located. If you have a trial package or local installation, you can use http://localhost:2200.
$ appmixer url https://api.appmixer.com
Login to your Appmixer account and enter your password:
The best way to start implementing your own custom components is to use the generator tool to generate a sample component. This gives you the basic skeleton of your component/service that you can later tweak. Use the
appmixer init example
command to generate a sample component:$ appmixer init example
Usage: appmixer init example <type> [path]
Options:
--vendor [vendor] Your vendor name.
--verbosity Verbosity level of the generated output log. Number in [0 - 2] range. Defaults to 1.
-h, --help output usage information
Examples:
$ appmixer init example no-auth
Environment Variables:
AM_GENERATOR_COMPONENT_PATH Components base directory. [path] argument overrides this variable if used.
As you can see, we have to give this command a
type
of example we want to generate. We will start with the most simple service type that does not use any authentication (OAuth1, OAuth2, API keys). In other words, the component will not ask the user to connect any account in the Inspector panel when using the component in a flow.$ appmixer init example no-auth
Created directory structure ./appmixer/myservice/mymodule/MyComponent
Creating component appmixer.myservice.mymodule.MyComponent
Created component manifest file ./appmixer/myservice/mymodule/MyComponent/component.json.
Created component package file ./appmixer/myservice/mymodule/MyComponent/package.json.
Created component behaviour file ./appmixer/myservice/mymodule/MyComponent/MyComponent.js.
Created service manifest file ./appmixer/myservice/service.json.
Created quota module file ./appmixer/myservice/quota.js.
Example successfully generated.
my-components
└── appmixer
└── myservice
├── mymodule
│ └── MyComponent
│ ├── MyComponent.js
│ ├── component.json
│ └── package.json
├── quota.js
└── service.json
You can now use appmixer pack appmixer/myservice && appmixer publish commands to upload it.
The command prints all the generated files and the directory structure. Note that we have just generated a working component with the
myservice.mymodule.MyComponent
type.Now we're ready to pack our service (i.e. create a zip archive with all the generated files) using the
appmixer pack appmixer/myservice
command:$ appmixer pack appmixer/myservice
Packing component directory: /Users/daviddurman/Projects/appmixer/my-components/appmixer/myservice
Files found in /Users/daviddurman/Projects/appmixer/my-components/appmixer/myservice
- mymodule
- quota.js
- service.json
You are in a directory with service.json file.
I'm going to create directory structure based on name in your service.json file.
3866 total bytes
appmixer.myservice.zip
You can pack the entire service or just the module or even individual components by providing the path to the
appmixer pack
command.The
pack
command generated the appmixer.myservice.zip
file in the current directory. Before you publish a component. Your user account has to have property
vendor
set to a string. The value depends on what vendor
is used in component(s) you're about to publish. More about that in here. In the examples in this section we use appmixer
as a vendor
, but you should use your own. If your company is called acme
then the vendor
property should be set to acme
as well. You can use Backoffice for that as shown in the next picture.
Using Backoffice to set vendor property.
The last step is to publish our component for our users to use. This is done using the
appmixer publish
command:$ appmixer publish appmixer.myservice.zip
Publishing archive: /Users/daviddurman/Projects/appmixer/my-components/appmixer.myservice.zip
Published.
Our component is now published and ready to be used:

Custom component published

Notice the labels and icons of the service in the component panel on the left and of the component in the Inspector selector match our definitions from the
myservice/service.json
and myservice/mymodule/MyComponent/component.json
manifest files.To see all the available components uploaded to Appmixer, use the
appmixer component ls
command:$ appmixer component ls
appmixer.actimo.contacts.CreateContact
appmixer.actimo.contacts.DeleteContact
appmixer.actimo.contacts.GetContact
appmixer.actimo.contacts.GetContacts
appmixer.actimo.contacts.UpdateContact
appmixer.actimo.groups.GetGroups
appmixer.actimo.messages.SendMessage
appmixer.apify.crawlers.Crawl
appmixer.asana.projects.CreateProject
appmixer.asana.projects.NewProject
appmixer.asana.tasks.CreateStory
appmixer.asana.tasks.CreateSubtask
appmixer.asana.tasks.CreateTask
appmixer.asana.tasks.NewComment
...
If you decide your component is no longer needed, you can remove your component from the system with the
appmixer remove
command:appmixer remove appmixer.myservice.mymodule.MyComponent
The remove command lets you specify any portion of the fully qualified component type. For example, if you want to remove the entire service, you can do that with:
appmixer remove appmixer.myservice
It's important to note that removing a component that is used in any of the running flows will cause the flows to stop working. The flows will start generating errors that will be visible in the Insights section. The
remove
command does not automatically stop the flows. Always make sure the component is not used in any of the running flows before you remove it.
IMPORTANT: Removing a component cannot be undone!You can re-publish (
appmixer publish
) your component which effectively replaces the old component with the new one.Note that re-publishing a component will not replace the component in a running flow. Flows wanting the new version of the component have to be stopped and started again to load the new version of the component.
Also note that if you "dramatically" change your component, e.g. removing ports, flows using the component type might require re-configuration since the ports that were used to connect to other components will not exist. The same goes for other major changes: changing output parameters that are used in connected components, changing inspector config and properties, etc.
Writing/updating code of your component, re-publishing it and re-configuring/restarting your flow every time you need to test your component would be a long process. Therefore, the Appmixer CLI tool provides a command to test your component locally on your machine, before publishing it to Appmixer. The
appmixer test
command allows you to test your component by sending messages to it, configuring properties and testing authentication methods:$ appmixer test -h
Usage: appmixer test <command>
Dev tools for testing your files.
Options:
-h, --help output usage information
Commands:
dump|d <moduleName> Get stored authentication data from previous commands.
auth|a <authModuleFile> Authenticate service.
component|c <componentFile> Test component.
help [cmd] display help for [cmd]
We'll start by exploring the component testing tool:
$ appmixer test component -h
Usage: appmixer test component [options] [componentDir]
Options:
-f, --transform [transform] specify transformer
-i, --input [input] input test message object (default: [])
-m, --mime [mime] mime type, application/json by default
-p, --properties [properties] component properties (JSON format)
-s, --no-state do not show component's state
-t, --tickPeriod [tickPeriod] tick period (in ms), default is 10000 ms
-h, --help output usage information
Examples:
Following example will send input message { "to": "[email protected]" } to component's input port 'in'.
You always have to specify to which input port you want to send message.
$ appmixer test component [path-to-your-component-directory] -i '{ "in": { "to": "[email protected]" } }'
This is how to specify transformer function from transformer file.
$ appmixer test component [path-to-component] -i '{}' -f './transformers#channelsToSelectArray'
How to set properties and tick period:
$ appmixer t c [path-to-component] -p '{ "channelId: "123XYZ" }' -t 2000
You can send more than one message:
$ appmixer t c [path-to-component] -i '{ "in": { "to": "[email protected]" }}' -i '{ "in": { "to": "[email protected]" }}'
You can run appmixer command in your component's directory:
$ appmixer test c
Directory has to contain component.json file and component's source code file.
If you're developing component that needs authentication, use 'appmixer test auth' before.
If you're developing Oauth2 component you might need to refresh access token before calling this command.
Use 'appmixer test auth refresh' for such purposes.
Some of the feature (context.store, context.componentStaticCall, ... will work only if you are logged in into Appmixer.
If you want to test them in your component, call appmixer login first.
For more information, checkout our documentation at:
https://docs.appmixer.com/appmixer/component-definition/authentication
https://docs.appmixer.com/appmixer/appmixer-trial/custom-component-helloappmixer
Let's say we want to send a message to our component and see how it reacts, i.e. what is the output of our component. We know our component has an input port called
in
and requires the sourceData
property as part of the incoming messages (see the component.json
file of your MyComponent, especially the inPorts
section). We can use the test
command for this:$ appmixer test component appmixer/myservice/mymodule/MyComponent -i '{ "in": { "sourceData": "foo" } }'
Testing /Users/daviddurman/Projects/appmixer/my-components/appmixer/myservice/mymodule/MyComponent
Validating properties.
Test server is listening on 2300
Starting component.
Calling receive method with input message:
in:
-
properties:
correlationId: null
gridInstanceId: null
contentType: application/json
contentEncoding: utf8
sender: null
destination: null
correlationInPort: null
componentHeaders:
signal: false
content:
sourceData: foo
scope:
{"name":"component","hostname":"MacBook-Pro.local","pid":26397,"level":30,"msg":"{\"properties\":{\"correlationId\":\"8f2ce09e-3f6d-48dd-81bd-e80189f70bb4\",\"gridInstanceId\":null,\"contentType\":\"application/json\",\"contentEncoding\":\"utf8\",\"sender\":{\"componentId\":\"70eb49e9-88df-4d0e-9549-d4e4f0f755c0\",\"type\":\"appmixer.myservice.mymodule.MyComponent\",\"outputPort\":\"out\"},\"destination\":null,\"correlationInPort\":null,\"componentHeaders\":{},\"signal\":false},\"content\":{\"sourceData\":\"foo\"},\"scope\":{\"_walkthrough\":[{\"targetId\":\"70eb49e9-88df-4d0e-9549-d4e4f0f755c0\",\"links\":[]}]}} { componentId: '70eb49e9-88df-4d0e-9549-d4e4f0f755c0',\n flowId: 'c5d05118-13b5-4ec8-a8fe-2e6ef51fdd52',\n userId: '5da735715abc4a671dfb592f',\n componentType: 'appmixer.myservice.mymodule.MyComponent',\n type: 'data',\n portType: 'out',\n port: 'out',\n inputMessages: { in: [ [Object] ] },\n annotatedMsg: { sourceData: 'foo' } }","time":"2019-10-16T15:21:22.169Z","v":0}
Component sent a message to its output port: out
{ sourceData: 'foo' }
Component's receive method finished in: 45 ms.
Return value from receive method:
undefined
Component's state at the end:
State is empty, component did not store anything into state.
Stopping component.
Destroying component.
The command prints out a lot of useful information, for example the output of the component (see "Component sent a message to its output port: out"). Since our component just forwards the same data that it received, we see the same object we sent to it: { sourceData: 'foo' }.
Now suppose we have a bug in our code in MyComponent.js, a syntax error:
module.exports = {
receive(context) {
myBadError
context.sendJson(context.messages.in.content, 'out');
}
}
Now re-running the test gives us:
$ appmixer test component appmixer/myservice/mymodule/MyComponent -i '{ "in": { "sourceData": "foo" } }'
Testing /Users/daviddurman/Projects/appmixer/my-components/appmixer/myservice/mymodule/MyComponent
Validating properties.
Test server is listening on 2300
Starting component.
Calling receive method with input message:
in:
-
properties:
correlationId: null
gridInstanceId: null
contentType: application/json
contentEncoding: utf8
sender: null
destination: null
correlationInPort: null
componentHeaders:
signal: false
content:
sourceData: foo
scope:
[ERROR]: myBadError is not defined
When your component is published, you can always download it back to your local file system. To download the source code of your component, use the
appmixer download
command:$ appmixer download -h
Usage: appmixer download selector
Options:
-o, --out [dir] Where you want save it.
-h, --help output usage information
Examples:
Download all files for SendEmail component:
$ appmixer download vendor.google.gmail.SendEmail
Download only package.json file for SendEmail component:
$ appmixer download vendor.google.gmail.SendEmail/package.json
Download main SendEmail.js file only:
$ appmixer download vendor.google.gmail.SendEmail/SendEmail.js
Download all gmail components:
$ appmixer download vendor.google.gmail
Download auth.js file for gmail:
$ appmixer download vendor.google.gmail/auth.js
Download quota.js file for gmail:
$ appmixer download vendor.google.gmail/quota.js
In our case, the download command would look like:
$ appmixer download appmixer.myservice
$ ls
appmixer.zip
$ unzip appmixer.zip
$ tree appmixer/
appmixer
└── myservice
├── mymodule
│ └── MyComponent
│ ├── MyComponent.compiled.js
│ ├── MyComponent.js
│ ├── component.json
│ ├── package-lock.json
│ ├── package.json
│ └── sourcemap-register.js
└── service.json
3 directories, 7 files
You can list all your flows using the
appmixer flow ls
command:$ appmixer flow ls
[Get Current Weather] : [a5769b32-8835-44ad-82e1-ece2874ea3e3] : [stopped]
[Uptime Monitor] : [5b5fd3a0-0ef2-4fc5-9a60-164f5e44c660] : [stopped]
[Daily Rainy Day Alert] : [ec1103e5-c66c-41c4-9223-029d2b328f5c] : [stopped]
If you want to see see just one flow and its stage (running/stopped), you can pass the ID of the flow in the
flow ls
command:$ appmixer flow ls a5769b32-8835-44ad-82e1-ece2874ea3e3
Flow: a5769b32-8835-44ad-82e1-ece2874ea3e3
Stage: stopped
To see the flow descriptor of a flow (i.e. JSON object that represents the entire configuration of the components in the flow and their connections), add the
--descriptor
or -d
flag:$ appmixer flow ls a5769b32-8835-44ad-82e1-ece2874ea3e3 --descriptor
{
"5ba2740c-929b-4599-b09e-fc8f8d5dac82": {
"type": "appmixer.utils.controls.OnStart",
"label": "OnStart",
"source": {},
"config": {},
"x": 88,
"y": 110
},
"0f366972-08fe-4cd4-80c0-227cfb6db54b": {
"type": "appmixer.utils.weather.GetCurrentWeather",
"label": "GetCurrentWeather",
"source": {
"location": {
"5ba2740c-929b-4599-b09e-fc8f8d5dac82": [
"out"
]
}
},
"config": {
"transform": {
"location": {
"5ba2740c-929b-4599-b09e-fc8f8d5dac82": {
"out": {
"type": "json2new",
"lambda": {
"city": "Prague",
"units": "metric"
}
}
}
}
}
},
"x": 286,
"y": 110
},
"ab6a22f8-916d-4aab-a5e3-2abedc03917c": {
"type": "appmixer.utils.email.SendEmail",
"label": "SendEmail",
"source": {
"in": {
"0f366972-08fe-4cd4-80c0-227cfb6db54b": [
"weather"
]
}
},
"config": {
"transform": {
"in": {
"0f366972-08fe-4cd4-80c0-227cfb6db54b": {
"weather": {
"type": "json2new",
"lambda": {
"from_email": "[email protected]",
"subject": "Appmixer: Current Weather",
"text": "Temperature: {{{$.0f366972-08fe-4cd4-80c0-227cfb6db54b.weather.main.temp}}} dgC\nPressure: {{{$.0f366972-08fe-4cd4-80c0-227cfb6db54b.weather.main.pressure}}} hPa\nHumidity: {{{$.0f366972-08fe-4cd4-80c0-227cfb6db54b.weather.main.humidity}}}%\nCloudiness: {{{$.0f366972-08fe-4cd4-80c0-227cfb6db54b.weather.clouds.all}}}%",
"to": ""
}
}
}
}
}
},
"x": 484,
"y": 110
}
}
You can start and stop flows using the
appmixer flow start
and appmixer flow stop
commands:$ appmixer flow start a5769b32-8835-44ad-82e1-ece2874ea3e3
Flow a5769b32-8835-44ad-82e1-ece2874ea3e3 successfully started.
$ appmixer flow stop a5769b32-8835-44ad-82e1-ece2874ea3e3
Flow a5769b32-8835-44ad-82e1-ece2874ea3e3 successfully stopped.
To remove flows, use the
appmixer flow remove
command:$ appmixer flow remove 2058a1ee-9c19-4e94-bd7a-0da7f9bed973
Flow 2058a1ee-9c19-4e94-bd7a-0da7f9bed973 successfully removed.
Note that the removed flow will be automatically stopped if it was running. Also note that this action cannot be undone.
You need admin privileges to run these commands. You should not modify Modifiers if there are any running flows using them. Such operation would break the flows.
The next command will download modifiers from Appmixer and save into modifiers.json file.
$ appmixer modifiers get
The next command will publish modifiers into Appmixer.
$ appmixer modifiers publish file-with-your-modifiers.json
The next command will delete existing modifiers from Appmixer. The next time Appmixer starts, it will load the default set of Modifiers.
$ appmixer modifiers delete
Last modified 2yr ago