rdzobot 0.1.0

Modular, but monolithic Matrix bot
Documentation
// SPDX-License-Identifier: AGPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 Wojtek Porczyk <woju@hackerspace.pl>

use matrix_sdk::attachment::AttachmentConfig;

use crate::prelude::*;
use crate::utils;

struct Parcel {
    room: String,
    event_orig: String,
    event_qr: String,
    id: String,
    code: String,
    r#ref: String,
    ete_d: String,
}

pub const RE_PARCEL_ORLEN: &str = "\
    ORLEN Paczka (?<id>[^ ]+) czeka przez (?<ete_d>[0-9]+) dni w automacie paczkowym (?<ref>.*?). Kod odbioru: (?<code>[0-9]+)";

pub async fn on_regex_orlen(
    re: regex::Regex,
    body: String,
    event: OriginalSyncRoomMessageEvent,
    _client: Client,
    room: Room,
    bot: Rdzobot,
) -> anyhow::Result<()> {
    for captures in re.captures_iter(&body) {
        let image = utils::create_qrcode_png(&captures["code"])?;
        let response = room
            .send_attachment(
                "qrcode.png",
                &mime::IMAGE_PNG,
                image,
                AttachmentConfig::new().caption(Some(format!(
                    "orlen, {}, {}, kod odbioru: {}",
                    &captures["id"], &captures["ref"], &captures["code"],
                ))),
            )
            .await?;

        let parcel = Parcel {
            room: room.room_id().to_string(),
            event_orig: event.event_id.to_string(),
            event_qr: response.event_id.to_string(),
            id: captures["id"].to_string(),
            code: captures["code"].to_string(),
            r#ref: captures["ref"].to_string(),
            ete_d: captures["ete_d"].to_string(),
        };

        let bot = bot.clone();
        let _ = tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
            bot.sqlite()
                .prepare(
                    "INSERT INTO parcels (
                        room, event_orig, event_qr, operator, id, code, ref, time_end
                    ) VALUES (
                        :room, :event_orig, :event_qr, 'orlen', :id, :code, :ref, datetime('now', format('+%d days', :ete_d))
                    );",
                )?
                .execute(rusqlite::named_params! {
                    ":room": parcel.room,
                    ":event_orig": parcel.event_orig,
                    ":event_qr": parcel.event_qr,
                    ":id": parcel.id,
                    ":code": parcel.code,
                    ":ref": parcel.r#ref,
                    ":ete_d": parcel.ete_d,
                })?;
            Ok(())
        })
        .await?;
    }

    Ok(())
}