aboutsummaryrefslogtreecommitdiffhomepage
path: root/bin/mail/deliver.sh
blob: ea21ac7d609b4c1ee467edcaf4a43719c3947efd (plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#! /bin/bash

# Deliver incoming mail to proper mailbox
# TODO image/audio mail part
date=$(date +%s)
mail_date="$(date --rfc-email -d @${date})"

# shell opt/trap {{{
shopt -s nocasematch extglob

# update index for dovecot
trap 'doveadm force-resync ${mailbox:-/}' EXIT

# temp file for decodemail (GNU Mailutils)
tmp_mailbox=$(mktemp -d); mkdir -p ${tmp_mailbox}/{tmp,new,cur}
cat >${tmp_mailbox}/cur/mail
trap 'rm -rf ${tmp_mailbox}' EXIT
# }}}
# log each delivery {{{
log=~/Maildir/cur/deliver.log.${date}
exec 2>>$log
trap 'doveadm force-resync /' EXIT

logfile=$(grep -rlE 'From:\s+<?MDA' ~/Maildir/cur | head -1)
if [ -z "$logfile" ]; then
  <<-HEADER cat >&2
	From: MDA <pham@topo.tw>
	Date: ${mail_date}
	Message-ID: <deliver.log>
	Content-Type: text/plain; charset=UTF-8
	Subject: Delivery Log

	HEADER
else
  mv $logfile $log 2>/dev/null
  sed -i "1,/^$/ s/^Date: .*/Date: ${mail_date}/" $log
fi
# }}}
# vars about message {{{
MAIL="$(decodemail ${tmp_mailbox})"
# TODO process multi-line header field
header="$(<<<"$MAIL" sed '/^$/ q; /^[[:blank:]]/ d;')"
body="$(<<<"$MAIL" sed -n '/^$/,$ p' | sed '1d')"

# vars about output
date=$(date --iso=seconds)
maildir=${HOME}/Maildir
mailbox=
# }}}
# FUNCTION: Set set_stdout {{{
set_stdout() {
  filename=${Subject// /_}
  path=${maildir}/${mailbox}${mailbox:+/}new/${date//:/}.${filename//[^[:alnum:]_]/}
  mkdir -p $(dirname $path)

  exec 1>$path
}
# }}}
# FUNCTION: print mail {{{
print_mail() {
  if [ "$private" = true ]; then
    <<-MAIL cat
		From: me <pham@topo.tw>
		Date: ${mail_date}
		Message-ID: ${Message_ID}
		Content-Type: text/plain; charset=UTF-8
		Self: true
		Subject: ${heading}

		$(sed 1d <<<"$body")
	MAIL
  else
    echo "$MAIL"
  fi
}
# }}}
# FUNCTION: save as private message {{{
private_message() {
  heading="$(head -1 <<<"${body}")"

  if [[ "${heading}" =~ ^"." ]]; then
    mailbox=act
    heading=${heading#.}
  else
    mailbox=box
  fi

  private=true
}
# }}}

# save each header field into vars {{{
# TODO Use GNU MailUtils to save header
while read line; do
  [[ "${line}" =~ ^" "|^"	" ]] && ${field}+=" ${line##*( )}" && continue

  IFS=': ' read field value <<<"${line}"
  field="${field^^}"
  field="${field//-/_}"
  declare ${field}="${value}"
done <<<"$header"
# }}}
# decide mailbox by vars {{{
if [[ "$SENDER" = pham@topo.tw && -n $CHAT_VERSION ]]; then
  private_message
elif [[ "${TO}" =~ '+'|'=' ]]; then
  mailbox=${TO#*[+=]}       # remove chars before symbol of mailbox
  mailbox=${mailbox%@*}     # remove suffix for mail address
elif [[ "${FROM}${RETURN_PATH}" =~ notifications@github.com|noreply@github.com ]]; then
  mailbox=DEV/github
elif [[ "${FROM}" =~ jgbsmart.com ]]; then
  mailbox=rent
elif [[ "${SUBJECT}" =~ 帳單|轉帳|對帳|付款|發票|消費|繳費|收據|費用|Invoice|Billing ]]; then
  mailbox=pay
elif [[ "${TO}" =~ dmarc@topo.tw ]]; then
  mailbox=DEV/dmarc
elif [[ "${LIST_ID}" =~ ^'Open Street Map Taiwan' ]]; then
  mailbox=FOSS/osm
elif [[ "${TO}" =~ talk-ja@openstreetmap.org ]]; then
  mailbox=LIST/talk-ja
elif [[ "${LIST_ID}" =~ ^~rjarry/aerc-discuss ]]; then
  mailbox=LIST/aerc
elif [[ "${LIST_ID}" =~ mutt-users.mutt.org ]]; then
  mailbox=LIST/mutt
elif [[
        "${SUBJECT}" =~  電子報|快訊|newsletter ||
        "${FROM}${TO}" =~ substack|service@kucw.io \
  ]]; then
  mailbox=news
elif [[ "${SUBJECT}" =~ login|verify|sign-in|密碼|安全性警示|登入|存取 ]]; then
  mailbox=login
elif [[ "${TO}" = cloudflare@topo.tw ]]; then
  mailbox=SRV/cloudflare
elif [[
        "${SUBJECT}" =~ 未讀|更新|核對表|嘟文|unread|summary|introduc  ||
        "${FROM}" =~ no-reply@hackmd.io \
  ]]; then
  mailbox=update
elif [[
        "${SUBJECT}${FROM}" =~ 優惠|快訊|願望清單|期待|eDM ||
        -n "${LIST_ID}${LIST_UNSUBSCRIBE}" ||
        ${TO} =~ tienling.chou@topo.tw \
  ]]; then
  mailbox=MISC/promote
fi
# }}}

# deliver mail to mailbox
set_stdout && print_mail

# log to stderr
echo -e ${date} ${mailbox:-INBOX} '\t' "${heading:-${SUBJECT}}" >&2

# vim:fdm=marker fdl=0