Skip to main content

greentic_session/
mapping.rs

1use greentic_types::SessionKey;
2use sha2::{Digest, Sha256};
3
4/// Deterministic SessionKey from Telegram update fields.
5/// Inputs are strings/numbers the caller extracts from their payload.
6pub fn telegram_update_to_session_key(bot_id: &str, chat_id: &str, user_id: &str) -> SessionKey {
7    let s = format!("tg:{bot_id}:{chat_id}:{user_id}");
8    SessionKey(hex_sha(&s))
9}
10
11/// Deterministic SessionKey from a generic webhook (source + subject).
12pub fn webhook_to_session_key(source: &str, subject: &str, id_hint: &str) -> SessionKey {
13    let s = format!("wh:{source}:{subject}:{id_hint}");
14    SessionKey(hex_sha(&s))
15}
16
17fn hex_sha(input: &str) -> String {
18    let mut hasher = Sha256::new();
19    hasher.update(input.as_bytes());
20    hex::encode(hasher.finalize())
21}
22
23#[cfg(test)]
24mod tests {
25    use super::*;
26
27    #[test]
28    fn stable_hash() {
29        let key1 = telegram_update_to_session_key("bot", "chat", "user");
30        let key2 = telegram_update_to_session_key("bot", "chat", "user");
31        assert_eq!(key1, key2);
32        assert_ne!(key1, telegram_update_to_session_key("bot", "chat", "user2"));
33        let webhook = webhook_to_session_key("crm", "ticket", "42");
34        assert_eq!(webhook, webhook_to_session_key("crm", "ticket", "42"));
35    }
36}