use serenity::http::Http;
use serenity::model::channel::Channel;
use serenity::model::id::ChannelId;
use crate::config::Config;
const RESTRICTED: &str = "đ `/cowork` is restricted to the bot owner.";
const NOT_IN_SERVER: &str =
"âšī¸ `/cowork` opens a server channel. Run it in the channel you want open.";
pub(crate) fn is_cowork_command(text: &str) -> bool {
text.trim()
.strip_prefix("/cowork")
.is_some_and(|rest| rest.is_empty() || rest.starts_with(char::is_whitespace))
}
pub(crate) fn write_channel_open(channel_id: &str, name: Option<&str>) -> Result<(), String> {
let section = format!("channels.discord.channels.{channel_id}");
Config::write_key(§ion, "open", "true").map_err(|e| e.to_string())?;
Config::write_key(§ion, "respond_to", "all").map_err(|e| e.to_string())?;
if let Some(name) = name {
Config::write_key_string(§ion, "name", name).map_err(|e| e.to_string())?;
}
Ok(())
}
pub(crate) fn cowork_discord_channel(
text: &str,
is_owner: bool,
in_server: bool,
channel_id: &str,
channel_name: Option<&str>,
write: impl FnOnce(&str, Option<&str>) -> Result<(), String>,
) -> Option<String> {
if !is_cowork_command(text) {
return None;
}
if !is_owner {
return Some(RESTRICTED.to_string());
}
if !in_server {
return Some(NOT_IN_SERVER.to_string());
}
match write(channel_id, channel_name) {
Ok(()) => Some(format!(
"â
This channel is open: any member can talk to me here, threads and forum posts included. Recorded as `[channels.discord.channels.{channel_id}]` (open = true). Members are not registered: access comes from `open`."
)),
Err(e) => Some(format!("â Could not open this channel: {e}")),
}
}
pub(crate) async fn channel_name(http: &Http, channel: ChannelId) -> Option<String> {
match channel.to_channel(http).await {
Ok(Channel::Guild(gc)) => Some(gc.name),
Ok(_) => None,
Err(e) => {
tracing::warn!("Discord: could not read the name of channel {channel}: {e}");
None
}
}
}