This commit is contained in:
Frederico @ VilaRosa02 2025-08-27 08:49:21 +00:00
commit f07e7a77a8
6 changed files with 208 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
data/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "make-llm-files"]
path = make-llm-files
url = https://git.fredericofalcao.com/git/make-llm-files

1
make-llm-files Submodule

@ -0,0 +1 @@
Subproject commit 5a24d4946d3c53105b191bd9c43c5754bc71d0f1

72
src/Makefile Normal file
View File

@ -0,0 +1,72 @@
include ../.env
export
.SECONDARY:
SHELL=/bin/bash -x
ROOT_DIR=/mnt/servers/aws.fredericofalcao.com/api.fredericofalcao.com/data/emails
#SRC_EML_FILES=$(notdir $(shell find "$(ROOT_DIR)" -type f -name "*.eml" | head -n 2))
LATEST_FILE:=$(shell find "$(ROOT_DIR)" -name "*.eml" -printf '%T@ %p\n' | sort -n | tail -1)
LATEST_FILE_MODIFIED_TIME=$(shell echo "$(LATEST_FILE)" | cut -d' ' -f1)
LATEST_FILE_FILE_PATH=$(shell echo "$(LATEST_FILE)" | cut -d' ' -f2-)
SRC_EML_FILES=../data/$(notdir $(LATEST_FILE_FILE_PATH))
SRC_TXT_FILES=$(subst .eml,.email.txt,$(SRC_EML_FILES))
SRC_SCORE_FILES=$(subst .email.txt,.score.txt,$(SRC_TXT_FILES))
SRC_FILES=$(subst .score.txt,.notification.txt,$(SRC_SCORE_FILES))
all: $(SRC_FILES)
# 6. Run the MAIL-ROUTE script to either notify the user of a new message, or ignore
%.notification.txt: %.score.txt %.header.txt %.summary.txt
TELEGRAM_BOT_TOKEN=$(TELEGRAM_BOT_TOKEN) TELEGRAM_CHAT_ID=$(TELEGRAM_CHAT_ID) ./mail-route $^ > $@
%.header.txt: %.eml
echo > $@
cat $< | grep -i -e '^From:' | grep -o -E -e '@[a-zA-Z0-9_.-]+' | tr -d '@' | tr -d '\n' >> $@
printf " -> " >> $@
cat $< | grep -i -e '^To:' | grep -o -E -e '[a-zA-Z0-9_.-]+@' | tr -d '@' | tr -d '\n' >> $@
printf "\n" >> $@
# 4. Generate a summary of the email
%.summary.txt: %.email.txt
cd ../make-llm-files && make clean
echo "You are a machine executive assistant tasked with parsing emails. User will send the content of a received email, and you (agent) must send a one phrase (max 12 words) sentence as an executive summary of the email." > ../make-llm-files/01_root.sys
cp ../data/$< ../make-llm-files/user_message.txt
echo '{}' > ../make-llm-files/settings.json
cd ../make-llm-files && make
mv ../make-llm-files/agent_message.txt $@
# 3. Convert a text-only email to a score (something a script/email-router can react to)
%.score.txt: %.email.txt
cd ../make-llm-files && make clean
echo "You are a machine executive assistant tasked with parsing emails urgency/importance. User will send the content of a received email, and you (agent) must REPLY ONLY with a single score [0.00-1.00] where you assess how important/urgent the email is." > ../make-llm-files/01_root.sys
cp ../data/$< ../make-llm-files/user_message.txt
echo '{"temperature": 0.8,"max_output_tokens":4}' > ../make-llm-files/settings.json
cd ../make-llm-files && make
mv ../make-llm-files/agent_message.txt $@
# 2. Convert an eml to text-only (something that an llm can parse)
%.email.txt: %.eml
./extract_text_from_eml.sh $< > $@
# 1. Copy the email file (eml) locallly
%.eml:
cp $(shell find $(ROOT_DIR) -name "$(notdir $@)") ../data/
telegram_notification.log: email_message.eml
curl -s -X POST "https://api.telegram.org/bot$(TELEGRAM_BOT_TOKEN)/sendDocument" \
-F chat_id="$(TELEGRAM_CHAT_ID)" \
-F caption="Here is your file 📎" \
-F document="@$<" > $@
clean:
rm *.sys *.txt *.log *.eml

48
src/extract_text_from_eml.sh Executable file
View File

@ -0,0 +1,48 @@
#!/bin/bash
EMAIL_FILENAME=$1
# REQUIRES:
# sudo apt-get -y install w3m
find_text() {
# Non-multipart fallback (single-part message)
if [[ "$ATTACHMENTS" == "Did not find anything to unpack from standard input" ]]; then
grep -A999999 -i -e '^From:' $EMAIL_FILENAME
return
fi
# Check if there is a TEXT/PLAIN part
if [[ ! -z $(echo "$ATTACHMENTS" | grep "text/plain") ]]
then
# Check if it is empty
TEXT_PLAIN_FILE=$(echo "$ATTACHMENTS" | grep "text/plain" | awk '{print $1}')
if [[ ! -z "$(cat $T_DIR/$TEXT_PLAIN_FILE)" ]]
then
grep -i -e 'From:' $EMAIL_FILENAME
grep -i -e 'To:' $EMAIL_FILENAME
grep -i -e 'Subject:' $EMAIL_FILENAME
qprint -d $T_DIR/$TEXT_PLAIN_FILE
return
fi
fi
if [[ ! -z $(echo "$ATTACHMENTS" | grep "text/html") ]]
then
HTML_FILE=$(echo "$ATTACHMENTS" | grep "text/html" | awk '{print $1}')
# CONVERT HTML TO TEXT
qprint -d $T_DIR/$HTML_FILE | w3m -dump -I UTF-8 -O UTF-8 -T text/html -
return
fi
}
T_DIR=$(mktemp -d)
ATTACHMENTS=$(munpack -q -t -C $T_DIR < $EMAIL_FILENAME)
find_text
rm -rf $T_DIR;

82
src/mail-route Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/env php
<?php
/*
## FREDS EMAIL SPAM SYSTEM
# < 0.20 : delete / reject
# < 0.40 : never notify / archive
# < 0.60 : notify at end-of-week
# < 0.80 : notify at end-of-day
# < 1.00 : notify immediately
*/
$bin_name = array_shift($argv);
$score = floatval(trim(file_get_contents(array_shift($argv))));
$message = implode("\n",array_map(fn($o)=>trim(file_get_contents($o)),$argv));
$telegram_bot_token = getenv()["TELEGRAM_BOT_TOKEN"] ?? "";
$telegram_chat_id = getenv()["TELEGRAM_CHAT_ID"] ?? "";
function sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id) {
// Build URL
$url = "https://api.telegram.org/bot{$telegram_bot_token}/sendMessage";
// cURL request
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'chat_id' => $telegram_chat_id,
'text' => $message,
]),
]);
$response = curl_exec($ch);
if ($response === false) {
return "cURL error: " . curl_error($ch) . PHP_EOL;
} else {
return $response ;
}
curl_close($ch);
}
if ( $score < 0.2 ) {
// DELETE / REJECT
sendTelegramMessage("_message rejected_", $telegram_bot_token, $telegram_chat_id);
sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id);
} elseif ($score < 0.4) {
// NEVER NOTIFY
sendTelegramMessage("_message would be archived_", $telegram_bot_token, $telegram_chat_id);
sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id);
} elseif ($score < 0.6) {
// NOTIFY AT THE END-OF-WEEK
sendTelegramMessage("_message is low-priority_", $telegram_bot_token, $telegram_chat_id);
sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id);
} elseif ($score < 0.8) {
// NOTIFY AT THE END-OF-DAY
sendTelegramMessage("_message is medium-priority_", $telegram_bot_token, $telegram_chat_id);
sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id);
} else {
// NOTIFY THE USER IMMEDIATELY
sendTelegramMessage("_message is high-priority_", $telegram_bot_token, $telegram_chat_id);
sendTelegramMessage($message, $telegram_bot_token, $telegram_chat_id);
}