use crate::Error;
pub const META_API_VERSION: &str = "v23.0";
pub struct WhatsAppConfig {
pub app_secret: String,
pub access_token: String,
pub phone_number_id: String,
pub verify_token: String,
pub is_owner: Box<dyn Fn(&str) -> bool + Send + Sync>,
}
impl WhatsAppConfig {
pub fn from_env(is_owner: Box<dyn Fn(&str) -> bool + Send + Sync>) -> Result<Self, Error> {
let app_secret = std::env::var("WHATSAPP_APP_SECRET")
.map_err(|_| Error::Config("WHATSAPP_APP_SECRET not set".into()))?;
let access_token = std::env::var("WHATSAPP_ACCESS_TOKEN")
.map_err(|_| Error::Config("WHATSAPP_ACCESS_TOKEN not set".into()))?;
let phone_number_id = std::env::var("WHATSAPP_PHONE_NUMBER_ID")
.map_err(|_| Error::Config("WHATSAPP_PHONE_NUMBER_ID not set".into()))?;
let verify_token = std::env::var("WHATSAPP_VERIFY_TOKEN")
.map_err(|_| Error::Config("WHATSAPP_VERIFY_TOKEN not set".into()))?;
Ok(Self {
app_secret,
access_token,
phone_number_id,
verify_token,
is_owner,
})
}
pub fn api_url(&self) -> String {
format!(
"https://graph.facebook.com/{META_API_VERSION}/{}/messages",
self.phone_number_id
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_env_fails_when_required_vars_missing() {
std::env::remove_var("WHATSAPP_APP_SECRET");
std::env::remove_var("WHATSAPP_ACCESS_TOKEN");
std::env::remove_var("WHATSAPP_PHONE_NUMBER_ID");
std::env::remove_var("WHATSAPP_VERIFY_TOKEN");
let result = WhatsAppConfig::from_env(Box::new(|_| false));
assert!(matches!(result, Err(Error::Config(_))));
}
#[test]
fn from_env_fails_when_one_var_missing() {
std::env::set_var("WHATSAPP_APP_SECRET", "secret");
std::env::set_var("WHATSAPP_ACCESS_TOKEN", "token");
std::env::set_var("WHATSAPP_PHONE_NUMBER_ID", "12345");
std::env::remove_var("WHATSAPP_VERIFY_TOKEN");
let result = WhatsAppConfig::from_env(Box::new(|_| false));
assert!(matches!(result, Err(Error::Config(_))));
std::env::remove_var("WHATSAPP_APP_SECRET");
std::env::remove_var("WHATSAPP_ACCESS_TOKEN");
std::env::remove_var("WHATSAPP_PHONE_NUMBER_ID");
}
#[test]
fn api_url_includes_phone_number_id_and_version() {
let config = WhatsAppConfig {
app_secret: "s".into(),
access_token: "t".into(),
phone_number_id: "99887766".into(),
verify_token: "v".into(),
is_owner: Box::new(|_| false),
};
assert_eq!(
config.api_url(),
"https://graph.facebook.com/v23.0/99887766/messages"
);
}
}