Quickstart · about five minutes
Your first realtime message.
Install the SDK, connect, join a channel, send, receive. Run the same program twice, or in two languages, and watch them talk.
Get an API key
Sign in with Google in the developer portal. Your first key is shown once: copy it somewhere safe.
For a browser tab, use a temporary key from the dashboard (Keys → Temporary keys) instead: it expires in minutes, so it is safe to paste into page code while you try things. In your app, your server mints it (see below).
Install
<script src="https://hmdevonline.com/messaging-platform/sdk/generated-web-agent-js/js/web-agent.libs.js"></script> <script src="https://hmdevonline.com/messaging-platform/sdk/generated-web-agent-js/js/web-agent.js"></script>
Two script tags; no build step. The npm package is not published yet. In Node, require() agents/web-agent-js from the SDK repository.
pip install "git+https://github.com/HaithamMubarak/messaging-platform-sdk.git@develop#subdirectory=agents/python-agent"
Python 3.10+. Installs hmdev-messaging-agent from the public repository; PyPI publishing is planned.
git clone https://github.com/HaithamMubarak/messaging-platform-sdk.git cd messaging-platform-sdk ./gradlew :agents:examples:java-agent-chat:build
Java 17. Built from source for now; depend on it with implementation project(':agents:java-agent'), as agents/examples/java-agent-chat does. Maven Central publishing is planned.
git clone https://github.com/HaithamMubarak/messaging-platform-sdk.git cmake -S messaging-platform-sdk/agents/cpp-agent -B build cmake --build build && cmake --install build --prefix ./sdk # your CMakeLists.txt find_package(messaging-cpp-agent CONFIG REQUIRED) target_link_libraries(my_app PRIVATE hmdev::messaging-cpp-agent)
Needs curl, OpenSSL and nlohmann_json. The C++ client is experimental: HTTP polling only, and no payload encryption yet, so on a password-protected channel it can join but cannot read the other SDKs' messages.
Connect
Create a connection with the platform's API address and your key.
const agent = new AgentConnection();
from hmdev.messaging.agent.core.agent_connection import AgentConnection agent = AgentConnection.with_api_key( "https://hmdevonline.com/messaging-platform/api/v1/messaging-service", os.environ["MESSAGING_PLATFORM_API_KEY"])
AgentConnection agent = new AgentConnection( "https://hmdevonline.com/messaging-platform/api/v1/messaging-service", System.getenv("MESSAGING_PLATFORM_API_KEY"));
MessagingChannelApi api("https://hmdevonline.com/messaging-platform/api/v1/messaging-service", apiKey);
Join a channel
A channel is created the first time anyone joins it. Everyone with its name and password is in the same room; the password also encrypts the messages.
agent.connect({
api: 'https://hmdevonline.com/messaging-platform/api/v1/messaging-service',
apiKey: 'paste-a-temporary-key',
channelName: 'quickstart-room',
channelPassword: 'channel-password',
agentName: 'browser-user',
autoReceive: true, // without this, a polling connection receives nothing
});
agent.connect("quickstart-room", "channel-password", "python-agent")
agent.connect(ConnectConfig.of("quickstart-room", "channel-password", "java-agent"));
ConnectResponse r = api.connect("quickstart-room", "channel-password", "cpp-agent");
Send a message
agent.addEventListener('connect', e => { if (e.response.status === 'success') agent.sendMessage({ content: 'Hello from the browser!' }); });
agent.send_message("Hello from Python!")
agent.sendMessage("Hello from Java!");
api.send(EventType::CHAT_TEXT, "Hello from C++!", "*", r.sessionId, false);
Receive
Every client on the channel gets every message, in order.
agent.addEventListener('message', e => { e.response.data.filter(m => m.type === 'chat-text') .forEach(m => console.log(m.from, 'says', m.content)); });
class Printer(AgentConnectionEventHandler): def on_message_events(self, events): for e in events: if e.get("type") == "chat-text": print(e.get("from"), "says", e.get("content"), flush=True) agent.receive_async(Printer())
agent.receiveAsync(events -> events.stream()
.filter(e -> e.getType() == EventMessage.EventType.CHAT_TEXT)
.forEach(e -> System.out.println(e.getFrom() + " says " + e.getContent())));
ReceiveConfig config; config.globalOffset = r.globalOffset; config.localOffset = r.localOffset; while (running) { EventMessageResult result = api.receive(r.sessionId, config); for (const auto& msg : result.messages) std::cout << msg.from << ": " << msg.content << std::endl; config.globalOffset = result.globalOffset; config.localOffset = result.localOffset; std::this_thread::sleep_for(std::chrono::milliseconds(500)); }
Run it twice, or once in two languages. Each client prints the other's greeting. These exact programs were run together against the live platform before this page was published; the full files are in agents/examples/quickstart.
Before you ship a web app
Keep your API key on your server
Your server signs in the visitor, asks the platform for a short-lived key, and hands only that to the browser.
// server.mjs: runs on your server, never in a browser bundle app.post('/api/messaging-access', requireSignedInUser, async (req, res) => { const r = await fetch('https://hmdevonline.com/messaging-platform/api/v1/messaging-service/channels/api-access', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.MESSAGING_PLATFORM_API_KEY }, body: JSON.stringify({ ttlSeconds: 30, singleUse: true }), }); const { data } = await r.json(); res.set('Cache-Control', 'no-store').json({ temporaryKey: data.temporaryKey }); });
The browser then passes temporaryKey as apiKey to agent.connect. The full pattern, with error handling, is in the web agent guide.
Next: the rest of the channel
Who is here
getActiveAgents and the agent-connect / agent-disconnect events.
Channel storage
storagePut / storageGet: state every client can read and late joiners catch up on.
Peer-to-peer
new WebRtcHelper(agent): data channels and media, signaled over the same channel.
Web agent guide
Every method, event and option of the JavaScript SDK.
Read the guide →