Rust client for Librus Synergia - the Polish school diary system.
Add to your Cargo.toml:
[dependencies]
librus-rs = "2.0"
tokio = { version = "1", features = ["full"] }use librus_rs::Client;
#[tokio::main]
async fn main() -> Result<(), librus_rs::Error> {
// From environment variables (LIBRUS_USERNAME, LIBRUS_PASSWORD)
let mut client = Client::from_env().await?;
// Fetch grades
let grades = client.grades().await?;
for grade in grades.grades {
println!("{}: {}", grade.date, grade.grade);
}
// Fetch messages
let unread = client.unread_counts().await?;
println!("Unread messages: {}", unread.inbox);
let messages = client.inbox_messages(1, 10).await?;
for msg in messages {
println!("{}: {}", msg.sender_name, msg.topic);
}
// Fetch school notices (announcements)
let notices = client.school_notices_latest(10).await?;
for notice in notices {
let content = Client::notice_content_to_text(¬ice.content);
let preview: String = content.chars().take(80).collect();
println!("{}: {}", notice.subject, preview);
}
Ok(())
}Three ways to create a client:
use librus_rs::Client;
// From environment variables
let client = Client::from_env().await?;
// With explicit credentials
let client = Client::new("username", "password").await?;
// Using the builder pattern
let client = Client::builder()
.username("username")
.password("password")
.build()
.await?;Base URL: https://synergia.librus.pl/gateway/api/2.0/
| Method | Description |
|---|---|
me() |
Get current user info |
grades() |
Get all grades |
grade_category(id) |
Get grade category by ID |
grade_comment(id) |
Get grade comment by ID |
lesson(id) |
Get lesson info by ID |
subject(id) |
Get subject info by ID |
attendances() |
Get all attendances |
attendance_types() |
Get attendance types |
homeworks() |
Get all homeworks |
school_notices() |
Get school notices (announcements) |
school_notices_page(page, limit) |
Get school notices with pagination |
school_notices_latest(limit) |
Get latest notices (client-side sort) |
user(id) |
Get user by ID |
current_user() |
Get current user details |
Notes:
- Pagination is supported by
SchoolNotices(viapage/limitquery params).
Base URL: https://wiadomosci.librus.pl/api/
| Method | Description |
|---|---|
unread_counts() |
Get unread message counts for all folders |
inbox_messages(page, limit) |
List received messages |
outbox_messages(page, limit) |
List sent messages |
message(id) |
Get full message details |
attachment(attachment_id, message_id) |
Download attachment as bytes |
decode_message_content(base64) |
Decode base64 message content to string |
notice_content_to_text(html) |
Convert API-provided notice HTML to text |
There is no official public documentation for the Synergia API. Community references:
- https://libraries.io/go/github.com%2Fgoferwplynie%2FlibrusApi (lists implemented endpoints; notes lack of official docs)
- https://ravensiris.github.io/librusapi/ (HTML-scraping docs; not official)
All methods return Result<T, librus_rs::Error>. Error variants:
pub enum Error {
Authentication, // Invalid credentials
MissingEnvVar(&'static str), // Environment variable not set
MissingCredentials(&'static str), // Builder credential missing
HttpClient(reqwest::Error), // HTTP client error
Request(reqwest::Error), // Request failed
ApiError { status, body }, // API returned error
Parse { source, body }, // JSON parsing failed
}pub use librus_rs::{
Client, // Main API client
Error, // Error type
// Grades
Grade, GradeCategory, GradeComment,
ResponseGrades, ResponseGradesCategories, ResponseGradesComments,
// Lessons & Attendance
Lesson, LessonSubject, Attendance, AttendanceType,
ResponseLesson, ResponseLessonSubject, ResponseAttendances, ResponseAttendancesType,
// User
Me, User, ResponseMe, ResponseUser,
// Homework
Homework, ResponseHomeworks,
// School notices (announcements)
SchoolNotice, ResponseSchoolNotices,
// Messages
InboxMessage, OutboxMessage, MessageDetail, Attachment, UnreadCounts,
};pub struct InboxMessage {
pub message_id: String,
pub sender_first_name: String,
pub sender_last_name: String,
pub sender_name: String,
pub topic: String,
pub content: String, // Base64 encoded
pub send_date: String,
pub read_date: Option<String>,
pub is_any_file_attached: bool,
pub tags: Vec<String>,
pub category: Option<String>,
}pub struct MessageDetail {
pub message_id: String,
pub sender_id: Option<String>,
pub sender_first_name: String,
pub sender_last_name: String,
pub sender_name: String,
pub sender_group: Option<String>,
pub topic: String,
pub message: String, // Base64 encoded
pub send_date: String,
pub read_date: Option<String>,
pub attachments: Vec<Attachment>,
pub receivers_count: Option<u32>,
pub no_reply: Option<u8>,
pub archive: Option<u8>,
}For Nix users:
nix develop
cargo build
cargo testMIT