You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: dingtalk_notify.rs
    path of file: ./repos/CYFS/src/component/cyfs-debug/src/bug_report
    
    the code of the file until where you have to start completion: use super::request::PanicReportRequest;
use crate::panic::BugReportHandler;
use crate::panic::CyfsPanicInfo;
use cyfs_base::*;

/*
const NOTIFY_MSG: &str = r#"{
    "msgtype": "text",
    "text": {
        "content": ${content},
    },
    "at": {
        "atMobiles": [],
        "isAtAll": true
    }
};"#;
*/

#[derive(Clone)]
pub struct DingtalkNotifier {
    // 基于钉钉机器人的报警功能
    dingtalk_url: String,
}

impl DingtalkNotifier {
    pub fn new(dingtalk_url: &str) -> Self {
        info!("new dingtalk bug reporter: {}", dingtalk_url);
        Self {
            dingtalk_url: dingtalk_url.to_owned(),
        }
    }

    pub async fn notify(&self, req: PanicReportRequest) -> BuckyResult<()> {
        let content = format!(
            "CYFS service panic report: \nproduct:{}\nservice:{}\nbin:{}\nchan
    
    pub async fn notify(&self, req: PanicReportRequest) -> BuckyResult<()> {
        let content = format!(
            "CYFS service panic report: \nproduct:{}\nservice:{}\nbin:{}\nchannel:{}\ntarget:{}\nversion:{}\nmsg:{}",
            req.product_name,
            req.service_name,
            req.exe_name,
            req.channel,
            req.target,
            req.version,
            req.info_to_string(),
        );

        let at_all = match get_channel() {
            CyfsChannel::Nightly => false,
            _ => true,
        };

        let msg = serde_json::json!({
            "msgtype": "text",
            "text": {
                "content": content,
            },
            "at": {
                "atMobiles": [],
                "isAtAll": at_all,
            }
        });

        let client = surf::client();
        let req = surf::post(&self.dingtalk_url).body(msg);

        let mut _res = client.send(req).await.map_err(|e| {
            let msg = format!("report to dingtalk error! {}", e);
            error!("{}", msg);
            BuckyError::from(msg)
        })?;

        info!("report to dingtalk success!");
        Ok(())
    }