Skip to content

Commit 9ebcfd8

Browse files
authored
[feat] Add an imap watcher for emails. (#4536)
[feat] Add an imap watcher for emails.
1 parent 7a7dafa commit 9ebcfd8

File tree

22 files changed

+532
-1
lines changed

22 files changed

+532
-1
lines changed
154 KB
Loading
66.7 KB
Loading

docs/guides/images/enable-2fa.png

105 KB
Loading

docs/guides/images/enable-imap.png

197 KB
Loading
600 KB
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../.eslintrc",
3+
"parserOptions": {
4+
"project": "tsconfig.json"
5+
},
6+
"rules": {
7+
"@typescript-eslint/no-unsafe-argument": "off",
8+
"@typescript-eslint/no-explicit-any": "off",
9+
"@typescript-eslint/strictNullChecks": "off",
10+
"@typescript-eslint/no-unsafe-member-access": "off",
11+
"@typescript-eslint/no-unsafe-assignment": "off"
12+
}
13+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
.idea/
2+
# Logs
3+
logs
4+
*.log
5+
npm-debug.log*
6+
yarn-debug.log*
7+
yarn-error.log*
8+
lerna-debug.log*
9+
.pnpm-debug.log*
10+
11+
# Diagnostic reports (https://nodejs.org/api/report.html)
12+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
13+
14+
# Runtime data
15+
pids
16+
*.pid
17+
*.seed
18+
*.pid.lock
19+
20+
# Directory for instrumented libs generated by jscoverage/JSCover
21+
lib-cov
22+
23+
# Coverage directory used by tools like istanbul
24+
coverage
25+
*.lcov
26+
27+
# nyc test coverage
28+
.nyc_output
29+
30+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
31+
.grunt
32+
33+
# Bower dependency directory (https://bower.io/)
34+
bower_components
35+
36+
# node-waf configuration
37+
.lock-wscript
38+
39+
# Compiled binary addons (https://nodejs.org/api/addons.html)
40+
build/Release
41+
42+
# Dependency directories
43+
node_modules/
44+
jspm_packages/
45+
46+
# Snowpack dependency directory (https://snowpack.dev/)
47+
web_modules/
48+
49+
# TypeScript cache
50+
*.tsbuildinfo
51+
52+
# Optional npm cache directory
53+
.npm
54+
55+
# Optional eslint cache
56+
.eslintcache
57+
58+
# Optional stylelint cache
59+
.stylelintcache
60+
61+
# Microbundle cache
62+
.rpt2_cache/
63+
.rts2_cache_cjs/
64+
.rts2_cache_es/
65+
.rts2_cache_umd/
66+
67+
# Optional REPL history
68+
.node_repl_history
69+
70+
# Output of 'npm pack'
71+
*.tgz
72+
73+
# Yarn Integrity file
74+
.yarn-integrity
75+
76+
# dotenv environment variable files
77+
.env
78+
.env.development.local
79+
.env.test.local
80+
.env.production.local
81+
.env.local
82+
83+
# parcel-bundler cache (https://parceljs.org/)
84+
.cache
85+
.parcel-cache
86+
87+
# Next.js build output
88+
.next
89+
out
90+
91+
# Nuxt.js build / generate output
92+
.nuxt
93+
dist
94+
95+
# Gatsby files
96+
.cache/
97+
# Comment in the public line in if your project uses Gatsby and not Next.js
98+
# https://nextjs.org/blog/next-9-1#public-directory-support
99+
# public
100+
101+
# vuepress build output
102+
.vuepress/dist
103+
104+
# vuepress v2.x temp and cache directory
105+
.temp
106+
.cache
107+
108+
# Docusaurus cache and generated files
109+
.docusaurus
110+
111+
# Serverless directories
112+
.serverless/
113+
114+
# FuseBox cache
115+
.fusebox/
116+
117+
# DynamoDB Local files
118+
.dynamodb/
119+
120+
# TernJS port file
121+
.tern-port
122+
123+
# Stores VSCode versions used for testing VSCode extensions
124+
.vscode-test
125+
126+
# yarn v2
127+
.yarn/cache
128+
.yarn/unplugged
129+
.yarn/build-state.yml
130+
.yarn/install-state.gz
131+
.pnp.*
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
FROM node:22.12 as builder
2+
3+
WORKDIR /app
4+
5+
RUN apt-get update && apt-get install -y g++ make python3
6+
7+
COPY package.json .
8+
COPY yarn.lock .
9+
COPY tsconfig.json .
10+
COPY .prettierrc .
11+
COPY .eslintrc .
12+
13+
COPY /packages/imap-mail-watcher/src ./packages/imap-mail-watcher/src
14+
COPY /packages/imap-mail-watcher/package.json ./packages/imap-mail-watcher/package.json
15+
COPY /packages/imap-mail-watcher/tsconfig.json ./packages/imap-mail-watcher/tsconfig.json
16+
COPY /packages/utils/package.json ./packages/utils/package.json
17+
18+
RUN yarn install --pure-lockfile
19+
20+
ADD /packages/utils ./packages/utils
21+
22+
RUN yarn workspace @omnivore/utils build
23+
RUN yarn workspace @omnivore/imap-mail-watcher build
24+
25+
FROM node:22.12 as runner
26+
27+
WORKDIR /app
28+
29+
ENV NODE_ENV production
30+
31+
COPY --from=builder /app/packages/imap-mail-watcher/dist /app/packages/imap-mail-watcher/dist
32+
COPY --from=builder /app/packages/imap-mail-watcher/package.json /app/packages/imap-mail-watcher/package.json
33+
COPY --from=builder /app/packages/imap-mail-watcher/node_modules /app/packages/imap-mail-watcher/node_modules
34+
COPY --from=builder /app/packages/utils/ /app/packages/utils/
35+
36+
37+
COPY --from=builder /app/node_modules /app/node_modules
38+
COPY --from=builder /app/package.json /app/package.json
39+
40+
CMD ["yarn", "workspace", "@omnivore/imap-mail-watcher", "start"]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "@omnivore/imap-mail-watcher",
3+
"version": "0.0.1",
4+
"scripts": {
5+
"build": "tsc",
6+
"dev": "ts-node-dev --files src/index.ts",
7+
"start": "node dist/watcher.js",
8+
"lint": "eslint src --ext ts,js,tsx,jsx",
9+
"lint:fix": "eslint src --fix --ext ts,js,tsx,jsx",
10+
"test:typecheck": "tsc --noEmit"
11+
},
12+
"dependencies": {
13+
"@omnivore/utils": "1.0.0",
14+
"axios": "^1.7.7",
15+
"imapflow": "^1.0.181",
16+
"mailparser": "^3.7.1"
17+
},
18+
"devDependencies": {
19+
"@types/imapflow": "^1.0.19",
20+
"@types/axios": "^0.14.4",
21+
"@types/express": "^5.0.0",
22+
"rxjs": "^7.8.1",
23+
"@types/html-to-text": "^9.0.2",
24+
"@types/jsdom": "^21.1.3",
25+
"@types/mailparser": "^3.4.5",
26+
"@types/node": "^22.10.7",
27+
"@types/pg": "^8.10.5",
28+
"@types/pg-format": "^1.0.3",
29+
"@types/urlsafe-base64": "^1.0.28",
30+
"@types/uuid": "^9.0.1",
31+
"@types/voca": "^1.4.3",
32+
"ts-node": "^10.9.1",
33+
"tslib": "^2.6.2",
34+
"typescript": "^5.7.3"
35+
},
36+
"volta": {
37+
"extends": "../../package.json"
38+
}
39+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
interface WatcherEnv {
2+
imap: {
3+
host: string
4+
port: number
5+
auth: {
6+
user: string
7+
password: string
8+
}
9+
}
10+
omnivoreEmail: string
11+
apiKey: string
12+
apiEndpoint: string,
13+
waitTime: number
14+
}
15+
16+
const envParser =
17+
(env: { [key: string]: string | undefined }) =>
18+
(varName: string, throwOnUndefined = false): string | undefined => {
19+
const value = env[varName]
20+
if (typeof value === 'string' && value) {
21+
return value
22+
}
23+
24+
if (throwOnUndefined) {
25+
throw new Error(
26+
`Missing ${varName} with a non-empty value in process environment`
27+
)
28+
}
29+
30+
return
31+
}
32+
33+
export function getEnv(): WatcherEnv {
34+
const parse = envParser(process.env)
35+
const imap = {
36+
auth: {
37+
user: parse('IMAP_USER')!,
38+
password: parse('IMAP_PASSWORD')!,
39+
},
40+
host: parse('IMAP_HOST')!,
41+
port: Number(parse('IMAP_PORT')!),
42+
}
43+
44+
return {
45+
apiKey: parse('WATCHER_API_KEY')!,
46+
apiEndpoint: parse('WATCHER_API_ENDPOINT')!,
47+
omnivoreEmail: parse('OMNIVORE_EMAIL')!,
48+
waitTime: Number(parse('WAIT_TIME')),
49+
imap,
50+
}
51+
}
52+
53+
export const env = getEnv()

0 commit comments

Comments
 (0)