TCP/IP Trigger listens for newline-delimited JSON requests from a client and requests exposed app actions. It is designed for local automation, trusted-LAN automation, and development validation. It binds to loopback by default and requires a token before it accepts any command.

For ControlMyNikon, the current exposed action ids are CameraShoot, CameraToggleConnection, and CameraAutoFocus. Other app actions are not available to TCP/IP Trigger unless a later version explicitly exposes them.

Before you start

  • Use TCP/IP Trigger only with clients you control.
  • Keep the bind address at 127.0.0.1 for scripts that run on the same computer.
  • Use a LAN IPv4 address only on a trusted private network.
  • Keep Actions disabled while testing connectivity and tokens.
  • Turn Actions enabled on only when the request path is proven.
  • Regenerate the token if it has been shared with a client you no longer trust.

TCP/IP Trigger uses plaintext JSON and a bearer token. Do not expose it through router port forwarding, public Wi-Fi, untrusted VPNs, or internet-facing firewall rules. Use HTML Trigger when you want a phone browser page with large action buttons instead of a script or custom TCP/IP client. UDP Trigger is not planned.

Page controls

  • Start begins listening on the configured loopback address and port.
  • Stop ends the listener and releases the port.
  • Bind address sets the local address to listen on.
  • Use 127.0.0.1 for same-computer scripts.
  • Use an IPv4 address assigned to this computer for trusted-LAN clients.
  • Wildcard addresses such as 0.0.0.0 are not supported.
  • Port sets the TCP port.
  • Actions enabled allows accepted action requests to run exposed actions.
  • Actions disabled lets you test commands without running actions.
  • Token shows the required request token.
  • Copy token places the token on the clipboard.
  • Regenerate token creates a new token and invalidates the old one.
  • The event history starts with the action ids currently exposed to TCP/IP Trigger, then shows listener state, accepted commands, rejected commands, and requested actions.

If TCP/IP Trigger is listening when the current profile is saved or the app closes, that profile starts the listener again next time. If the saved address is no longer assigned to this computer or the port is busy, startup continues with TCP/IP Trigger stopped and the event history explains the failure.

Command format

Clients send one JSON object per line. The listener returns one JSON response per line.

The basic action request shape is:

{"token":"your-token","command":"action","action":"CameraShoot"}

A successful response looks like:

{"ok":true,"message":"Action requested.","action":"CameraShoot","actions":null,"error":null}

A rejected response includes a stable error code:

{"ok":false,"error":"InvalidToken","message":"Token is invalid.","action":null,"actions":null}

The first commands are:

  • action requests an exposed action.
  • ping verifies that the listener and token are working.
  • actions returns the action ids currently exposed to TCP/IP Trigger.

Python test client

This script uses only the Python standard library. Start TCP/IP Trigger first, then paste the token from the page into TOKEN. Leave SEND_ACTION as False while Actions disabled is on. Set SEND_ACTION to True only after ping and actions work and Actions enabled is on. A copy of this script is saved in the source tree at Shared\Common\Triggers\pyscripts\tcpip_trigger_test_client.py. For Visual Studio, open Shared\Common\Triggers\pyscripts\TcpIpTriggerPythonClient.sln.

import json
import socket
HOST = "127.0.0.1"
PORT = 50505
TOKEN = "paste-token-from-page"
SEND_ACTION = False
ACTION_ID = "CameraShoot"
def send_command(command):
    line = json.dumps(command, separators=(",", ":")) + "\n"
    with socket.create_connection((HOST, PORT), timeout=5) as sock:
        sock.sendall(line.encode("utf-8"))
        response = sock.makefile("r", encoding="utf-8", newline="\n").readline()
    return json.loads(response)
print("ping:", send_command({
    "token": TOKEN,
    "command": "ping"
}))
print("actions:", send_command({
    "token": TOKEN,
    "command": "actions"
}))
if SEND_ACTION:
    print("action:", send_command({
        "token": TOKEN,
        "command": "action",
        "action": ACTION_ID
    }))

Safety

TCP/IP Trigger can request app actions without local keyboard, scanner, voice, or sound input. For that reason, it starts disabled, binds to loopback by default, and requires a token even on loopback.

Actions disabled blocks action dispatch but still lets you validate JSON, token handling, and basic command responses. Use it while building or testing a client.

LAN binding is trusted-LAN-only control. Anyone who can connect to the listener and knows the token can request exposed actions while Actions enabled is on. Keep the token private and regenerate it after sharing it with temporary scripts or clients.

Troubleshooting

If Start is disabled:

  • Check that the port is between 1 and 65535.
  • Confirm the token is not empty.
  • Stop any previous listener state before changing the port.

If Start fails:

  • Another process may already be using the port.
  • Choose another port and try again.
  • Check the event history for the failure message.

If a client cannot connect:

  • Confirm TCP/IP Trigger is started.
  • Confirm the client connects to the displayed bind address and port.
  • For same-computer scripts, use 127.0.0.1.
  • For another LAN device, use the computer's LAN IPv4 address and confirm Windows firewall or endpoint tools allow the inbound connection.
  • Confirm the bind address is assigned to this computer.

If a request is rejected:

  • Confirm the request is one JSON object on a single line.
  • Confirm the token exactly matches the token on the page.
  • Confirm command is action, ping, or actions.
  • Confirm the requested action is one of the action ids shown by the actions command, such as CameraShoot.
  • Turn Actions enabled on before expecting action requests to run.

For Python or PowerShell client development, watch the event history while testing. It logs client connect and disconnect events, accepted ping and actions commands, rejected JSON, missing or invalid tokens, unknown commands, unknown actions, disabled actions, and successful action dispatch. The token itself is not written to the event history.

Related setup

Use Hotkeys when keyboard input should request actions. Use Scanner when barcode input should fill fields or trigger actions. Use Voice Trigger when spoken phrases should request actions. Use Sound Trigger when audio level threshold crossings should request actions.