everything but marking emails as read

fyi: untested in webserver, and newely incoming emails
This commit is contained in:
Saahil 2024-09-27 15:27:49 +00:00 committed by GitHub
parent 7849690f59
commit de78a73ad6
4 changed files with 203 additions and 24 deletions

View file

@ -2,12 +2,14 @@ require 'coffeescript/register'
mailparser = require 'mailparser'
simpleParser = mailparser.simpleParser
dotenv = require 'dotenv'
clipboardy = require 'clipboardy-cjs'
# coffee seems to not find dotenv automatically.
dotenv.config({ path: __dirname + '/.env' })
emails = require './emails'
express = require 'express'
Imap = require 'imap'
app = express()
current_codes = []
imap = new Imap({
user: process.env.IMAP_USER,
password: process.env.IMAP_PASSWORD,
@ -18,6 +20,42 @@ imap = new Imap({
authTimeout: 100000,
connTimeout: 100000,
})
manageCode = (codeOrUrl) ->
if !codeOrUrl
return
if typeof codeOrUrl is not 'string'
console.log "Code is not a string"
return
if !codeOrUrl.startsWith
console.log "Code is not a string"
return
if codeOrUrl.length < 3
console.log "Code too short"
return
if codeOrUrl.length > 10 && !codeOrUrl.startsWith('http')
console.log "Code too long"
return
console.log "Copied #{codeOrUrl} to clipboard"
current_codes.push codeOrUrl
if process.env.USE_CLIPBOARD == 'y'
if codeOrUrl.startsWith('http')
require('open')(codeOrUrl)
else
try
clipboardy.default.writeSync(codeOrUrl)
catch e
console.error e
if process.env.NTFY_TOPIC_NAME != null
fetch (process.env.NTFY_HOST || "https://ntfy.sh") + '/' + process.env.NTFY_TOPIC_NAME, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Click': codeOrUrl if codeOrUrl.startsWith('http')
},
body: if codeOrUrl.startsWith("http") then "Click on me to open your verification url." else "Your verification code is " + codeOrUrl,
}
openInbox = (cb) ->
imap.openBox 'INBOX', true, cb || ((err, box) -> if err then throw err)
@ -28,12 +66,6 @@ imap.on 'ready', () ->
console.log 'Connected'
openInbox (err, box) ->
if err then throw err
# imap.search ['UNSEEN'], (err, results) ->
# if err then throw err
# if results.length > 0
# console.log "New email"
# else
# console.log "No new email"
setInterval openInbox, 1000
imap.on 'error', (err) ->
@ -42,33 +74,54 @@ imap.on 'mail', (numNewMsgs) ->
console.log "New mail: #{numNewMsgs}"
imap.search ['UNSEEN', ['FROM', '@hackclub.com']], (err, results) ->
if err then throw err
console.log results
if results.length > 0
console.log "New email"
f = imap.fetch(results, { bodies: '', markSeen: true })
f.on 'message', (stream) ->
stream.on 'body', (stream) ->
f.on 'message', (mstream) ->
mstream.on 'body', (stream) ->
simpleParser stream, (err, mail) ->
if err then throw err
# console.log mail
# for email in emails
# if mail.from.value[0].address is email.email
# console.log "Email from #{email.email}"
# console.log mail.from
parseSprig = (mail) ->
code = mail.text.split("Here's your Sprig login code: ")[1].split("\n")[0]
console.log code, 'code'
manageCode(code)
parseLogin = (mail) ->
code = mail.text.split('\n')[4]
console.log code, 'code'
manageCode(code)
parseTeam = (mail) ->
code = mail.text.split('\n')[4].split("It's here: ")[1]
console.log code, 'code'
manageCode(code)
if mail.from.value[0].address in emails.map((email) -> email.email)
email = emails.find((email) -> email.email is mail.from.value[0].address)
console.log "Email from #{email.email}"
# TODO: finish this =(
switch email.email
when 'team@hackclub.com' then parseTeam(mail)
when 'login@hackclub.com' then parseLogin(mail)
when 'sprig@hackclub.com' then parseSprig(mail)
# console.log mail.text
stream.once 'end', ->
mstream.on 'attributes', (attrs) ->
console.log 'Attributes:', attrs
uid = attrs.uid
imap.addFlags uid, ['\\Seen'], (err) ->
if err then throw err
f.on 'end', ->
console.log "Done fetching all messages"
imap.setFlags results, ['\\Seen'], (err) ->
if err then throw err
else
console.log "No new email"
app.get '/health', (req, res) ->
res.send 'OK'
app.get '/', (req, res) ->
mapFunc = (c) -> if c.startsWith('http') then "<a href='#{c}'>#{c}</a>" else c
res.send current_codes.map(mapFunc).join('<br>')
if process.env.USE_SERVER is 'y'
server = app.listen process.env.PORT || 3000, ->
@ -76,8 +129,3 @@ if process.env.USE_SERVER is 'y'
process.on 'exit', ->
console.log "Closing server"

View file

@ -19,7 +19,9 @@ keys = {
IMAP_PORT: 'IMAP port',
PORT: 'Port',
USE_CLIPBOARD: 'Use clipboard? (y/n)',
USE_SERVER: 'Use server? (y/n)'
USE_SERVER: 'Use server? (y/n)',
NTFY_HOST: 'Notification server host (ntfy.sh) otherwise',
NTFY_TOPIC_NAME: 'Notification server topic name (if none is provided ntfy is disabled)',
}
env = {}