| Crates.io | zello-client |
| lib.rs | zello-client |
| version | 0.2.11 |
| created_at | 2025-12-09 11:20:20.795861+00 |
| updated_at | 2025-12-09 15:12:12.860143+00 |
| description | A simple Zello client for experimenting with Rust and understanding the publishing process. |
| homepage | |
| repository | https://github.com/jcmurray/zello-client |
| max_upload_size | |
| id | 1975314 |
| size | 129,333 |
</-- SPDX-License-Identifier: MIT OR Apache-2.0 SPDX-FileCopyrightText: 2024 John C. Murray -->
A Rust client library for interacting with the Zello API, supporting WebSocket connections for real-time push-to-talk (PTT) communication.
Add this to your Cargo.toml:
[dependencies]
zello-client = "0.2.11"
tokio = { version = "1.48", features = ["full"] }
It works on Ubuntu and other Linux distributions with the following audio library dependencies:
pulseaudio-utils,libopus-dev, andlibasound2-dev packages.These are the steps to install these required dependencies on distributions that use apt:
sudo apt install pulseaudio-utils
sudo apt install libopus-dev pkg-config
sudo apt install libasound2-dev pkg-config
You need to set up the required credentials for running an application. Example applications are shown below.
Information must be provided to this command in the form of a .env file with the following variables:
ZELLO_USERNAME='your_username'
ZELLO_PASSWORD='your_password'
ZELLO_TOKEN='your Zello authentication token'
ZELLO_CHANNEL='name of a Zello channel'
The authentication token is required because this application is using a development API which requires this token.
This requirement may change in the future when this Zello API is made public.
Ensure you provide a .env file with your credentials.
You should add the following dependencies to your project's Cargo.toml:
[dependencies]
anyhow = "1.0.100"
tokio = "1.48.0"
zello-client = "0.2.11"
With the following code in your project's src/main.rs to run this simple example:
use anyhow::Result;
use zello_client::{
connect_to_zello, initialize_logging, load_credentials, utilities::load_dotenv,
};
#[tokio::main]
async fn main() -> Result<()> {
load_dotenv()?;
initialize_logging()?;
let credentials = load_credentials()?;
let mut client = connect_to_zello(&credentials).await?;
client.send_text_message("Hello from Zello!").await?;
client.close().await?;
Ok(())
}
You should add the following dependencies to your project's Cargo.toml:
[dependencies]
anyhow = "1.0.100"
clap = "4.5.53"
crossbeam-channel = "0.5.15"
tokio = "1.48.0"
zello-client = "0.2.11"
With the following code in your project's src/main.rs to run this simple example:
use anyhow::Result;
use clap::Parser;
use crossbeam_channel::bounded;
use std::sync::Arc;
use tokio::sync::Mutex;
use zello_client::{
PCM_CHANNEL_CAPACITY, connect_to_zello, create_decoder, initialize_logging, load_credentials,
setup_audio_output, utilities::load_dotenv,
};
#[derive(Parser, Debug)]
#[command(name = "zello-client")]
#[command(about = "This is a simple Zello client application that allows you\n\
to listen to audio messages from and to send text messages to other\n\
users on the Zello platform.")]
#[command(
long_about = "This is a simple Zello client application that allows you\n\
to listen to audio messages from and to send text messages to other\n\
users on the Zello platform.
Information must be provided to this command in the form of\n\
a '.env' file with the following variables:
ZELLO_USERNAME='your_username'
ZELLO_PASSWORD='your_password'
ZELLO_TOKEN='your Zello authentication token'
ZELLO_CHANNEL='name of a Zello channel'
The authentication token is required because this application\n\
is using a development API which requires this token.\n\
\n\
This requirement may change in the future when the API is made public."
)]
#[command(version = env!("CARGO_PKG_VERSION"))]
struct Args {
/// Message to send as text message
#[arg(short = 'm', long)]
message: Option<String>,
/// Destination callsign of message (requires --message)
#[arg(short = 'c', long, requires = "message")]
callsign: Option<String>,
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
load_dotenv()?;
initialize_logging()?;
let credentials = load_credentials()?;
let decoder = create_decoder()?;
let (pcm_tx, pcm_rx) = bounded::<Vec<i16>>(PCM_CHANNEL_CAPACITY);
let pcm_rx = Arc::new(Mutex::new(pcm_rx));
let _stream = setup_audio_output(pcm_rx)?;
let mut client = connect_to_zello(&credentials).await?;
match (args.message, args.callsign) {
(Some(msg), Some(callsign)) => {
client
.send_text_message_to_callsign(&msg, &callsign)
.await?;
}
(Some(msg), None) => {
client.send_text_message(&msg).await?;
}
(None, _) => {
client.run_message_loop(decoder, &pcm_tx).await?;
}
}
client.close().await?;
Ok(())
}