blob: 90ebe043b57490746411cfb57c62f0ce393a0a6a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#!/usr/bin/env sh
# {{ ansible_managed }}
#
# Replies for Fredrick whilst he's travelling for work, and forwards replies to
# DevOps to respond for him if necessary.
FREDRICK_TOKEN='{{ postfix_fredrick_generator_token }}'
FREDRICK_ENDPOINT="https://fredrick.python-discord.workers.dev/"
# Read email into variable
EMAIL=$(cat)
# Find the sender
SENDER=$(echo "$EMAIL" | maddr -h from -)
# Grab the display name of the sender
SENDER_DISPLAY_NAME=$(echo "$EMAIL" | maddr -h from -d -)
# Grab the target address
RECIPIENT=$(echo "$EMAIL" | maddr -a -h to -)
# Sender date as a unix timestamp
DATE_UNIX=$(echo "$EMAIL" | mhdr -h date -D -)
# Find message ID to use later to add to a reply chain
MESSAGE_ID=$(echo "$EMAIL" | mhdr -h message-id -)
MESSAGE_DATE=$(echo "$EMAIL" | mhdr -h date -)
# Extract the original Subject and prefix it with "Re: " if necessary
ORIGINAL_SUBJECT=$(echo "$EMAIL" | mhdr -h subject -)
LIST_ID=$(echo "$EMAIL" | mhdr -h list-id -)
if [ "$LIST_ID" != "" ]; then
# We don't reply to all mailing list posts.
SHOULD_REPLY=$(awk 'BEGIN { srand(); print rand() <= 0.25 }')
if [ "$SHOULD_REPLY" = "0" ]; then
echo "fredrick: don't feel like replying to mailing list post (\"$ORIGINAL_SUBJECT\")."
exit 0
fi
fi
# Construct the reply subject
REPLY_SUBJECT="Re: $ORIGINAL_SUBJECT"
# Decode the text/plain component of the message body
#
# We strip off a line on some emails about being unable to find a filter
BODY=$(echo "$EMAIL" | mshow - -N -h "" -A text/plain | grep -v "^no filter or default handler$")
# Convert to a multiline JSON value that we can ship to the Fred API
JSON_BODY=$(echo -n "$BODY" | jq -R -s . | sed 's/\\n/\\\\n/g')
# We build the request to send off to the Fredrick generator
FINAL_JSON=$(jq -r -c -n \
--arg from "$SENDER" \
--arg subject "$ORIGINAL_SUBJECT" \
--arg sent_at_unix "$DATE_UNIX" \
--arg sent_at_unparsed "$MESSAGE_DATE" \
--argjson body "$JSON_BODY" \
'{sent_at_unix: $sent_at_unix, sent_at_unparsed: $sent_at_unparsed,
from: $from, subject: $subject, body: $body}')
FRED_RESPONSE=$(curl -X POST "$FREDRICK_ENDPOINT" \
-H "Authorization: $FREDRICK_TOKEN" \
-H "Content-Type: application/json" \
-d "$FINAL_JSON" -s)
# Fredrick likes to try add a Subject: line on sometimes
FILTERED=$(echo "$FRED_RESPONSE" | grep -v "^Subject:")
# Path where scheduled replies are stored
REPLIES_PATH=/var/tmp/fredrick-vacation-replies
if [ ! -d "$REPLIES_PATH" ]; then
# -p is to prevent race conditions from concurrent script runs
mkdir -p "$REPLIES_PATH"
fi
REPLY_PATH=$(mktemp --tmpdir="$REPLIES_PATH" --suffix=.eml)
(
echo "Subject: $REPLY_SUBJECT"
echo "From: Fredrick <[email protected]>"
echo "To: $SENDER"
echo "Bcc: [email protected]"
echo "In-Reply-To: $MESSAGE_ID"
echo "References: $MESSAGE_ID"
echo
echo "$FILTERED"
echo
# Quote the original message
echo "On $MESSAGE_DATE, $SENDER_DISPLAY_NAME wrote:"
echo "$BODY" | awk -F '\n' '{ print "> " $1 }'
) > "$REPLY_PATH"
ATSCRIPT=$(mktemp --suffix=fredrick-atscript.sh)
cat > "$ATSCRIPT" <<EOF
/usr/sbin/sendmail -t < "$REPLY_PATH"
rm "$REPLY_PATH"
EOF
# Use the z queue for maximum niceness
case $RECIPIENT in
"fredrick+ritalin@"*)
at -q z -f "$ATSCRIPT" now + 1 min
;;
*)
reply_delay=$(awk 'BEGIN { srand(); print (rand() * 100) + 20 }')
at -q z -f "$ATSCRIPT" now + "$reply_delay" min
;;
esac
rm "$ATSCRIPT"
|