| Crates.io | discourse-webhooks |
| lib.rs | discourse-webhooks |
| version | 0.2.0 |
| created_at | 2025-07-19 15:23:31.649857+00 |
| updated_at | 2025-07-19 22:10:56.317103+00 |
| description | Type-safe Rust library for handling Discourse webhook events |
| homepage | https://github.com/Jontes-Tech/discourse-webhooks |
| repository | https://github.com/Jontes-Tech/discourse-webhooks |
| max_upload_size | |
| id | 1760321 |
| size | 75,847 |
A type-safe Rust library for handling Discourse webhook events.
topic_created - When a new topic is createdtopic_edited - When a topic is editedtopic_destroyed - When a topic is deletedtopic_recovered - When a deleted topic is restoredpost_created - When a new post is createdpost_edited - When a post is editedpost_destroyed - When a post is deletedpost_recovered - When a deleted post is restoredping - Webhook ping/health check eventsuse discourse_webhooks::{parse_webhook_payload, WebhookEventPayload};
use serde_json::json;
let payload = json!({
"topic": {
"id": 123,
"title": "Hello World",
"created_at": "2023-01-01T00:00:00Z",
// ... other fields
}
});
let event = parse_webhook_payload("topic_created", payload)?;
match event {
WebhookEventPayload::TopicEvent(topic_event) => {
println!("New topic: {}", topic_event.topic.title);
}
WebhookEventPayload::PostEvent(post_event) => {
println!("New post: {}", post_event.post.raw);
}
WebhookEventPayload::Generic(value) => {
println!("Unknown event: {:?}", value);
}
}
use discourse_webhooks::verify_signature;
let secret = "your_webhook_secret";
let payload = r#"{"topic":{"id":123}}"#;
let signature = "sha256=abcdef1234567890...";
verify_signature(secret, payload, signature)?;
println!("Signature verified!");
use discourse_webhooks::{WebhookEventHandler, TopicWebhookEvent, PostWebhookEvent, DiscourseInstance};
struct MyHandler;
impl WebhookEventHandler for MyHandler {
type Error = String;
fn handle_topic_created(&mut self, event: &TopicWebhookEvent) -> Result<(), Self::Error> {
println!("Topic created: {}", event.topic.title);
// Your custom logic here
Ok(())
}
fn handle_post_created(&mut self, event: &PostWebhookEvent) -> Result<(), Self::Error> {
println!("Post created: {}", event.post.raw);
// Your custom logic here
Ok(())
}
}
// Process events
let mut handler = MyHandler;
let instance = DiscourseInstance::EthereumMagicians;
process_webhook_event(&mut handler, &instance, "topic_created", payload)?;
use discourse_webhooks::{
DiscourseInstance, verify_json_signature, process_webhook_event,
WebhookEventHandler, TopicWebhookEvent, PostWebhookEvent
};
struct ForumHandler {
// Your application state
}
impl WebhookEventHandler for ForumHandler {
type Error = String;
fn handle_topic_created(&mut self, event: &TopicWebhookEvent) -> Result<(), Self::Error> {
// Handle new topics
println!("New topic: {}", event.topic.title);
Ok(())
}
fn handle_post_created(&mut self, event: &PostWebhookEvent) -> Result<(), Self::Error> {
// Handle new posts
println!("New post in topic: {}", event.post.topic_title);
Ok(())
}
}
// In your webhook endpoint
fn handle_webhook(
instance_header: &str,
event_type: &str,
signature: &str,
payload: serde_json::Value
) -> Result<(), Box<dyn std::error::Error>> {
// Parse instance
let instance = DiscourseInstance::from_url(instance_header)?;
if !instance.is_valid() {
return Err("Invalid Discourse instance".into());
}
// Verify signature
let secret = "your_webhook_secret";
verify_json_signature(secret, &payload, signature)?;
// Process event
let mut handler = ForumHandler { /* ... */ };
process_webhook_event(&mut handler, &instance, event_type, payload)?;
Ok(())
}