mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-05 15:38:34 +08:00
feat: telegram bot (#238)
This commit is contained in:
@@ -17,6 +17,7 @@ import MailsUnknow from './admin/MailsUnknow.vue';
|
|||||||
import About from './common/About.vue';
|
import About from './common/About.vue';
|
||||||
import Maintenance from './admin/Maintenance.vue';
|
import Maintenance from './admin/Maintenance.vue';
|
||||||
import Appearance from './common/Appearance.vue';
|
import Appearance from './common/Appearance.vue';
|
||||||
|
import Telegram from './admin/Telegram.vue';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
localeCache, adminAuth, showAdminAuth, adminTab, loading, globalTabplacement
|
localeCache, adminAuth, showAdminAuth, adminTab, loading, globalTabplacement
|
||||||
@@ -46,6 +47,7 @@ const { t } = useI18n({
|
|||||||
unknow: 'Mails with unknow receiver',
|
unknow: 'Mails with unknow receiver',
|
||||||
senderAccess: 'Sender Access Control',
|
senderAccess: 'Sender Access Control',
|
||||||
sendBox: 'Send Box',
|
sendBox: 'Send Box',
|
||||||
|
telegram: 'Telegram Bot',
|
||||||
statistics: 'Statistics',
|
statistics: 'Statistics',
|
||||||
maintenance: 'Maintenance',
|
maintenance: 'Maintenance',
|
||||||
appearance: 'Appearance',
|
appearance: 'Appearance',
|
||||||
@@ -64,6 +66,7 @@ const { t } = useI18n({
|
|||||||
unknow: '无收件人邮件',
|
unknow: '无收件人邮件',
|
||||||
senderAccess: '发件权限控制',
|
senderAccess: '发件权限控制',
|
||||||
sendBox: '发件箱',
|
sendBox: '发件箱',
|
||||||
|
telegram: '电报机器人',
|
||||||
statistics: '统计',
|
statistics: '统计',
|
||||||
maintenance: '维护',
|
maintenance: '维护',
|
||||||
appearance: '外观',
|
appearance: '外观',
|
||||||
@@ -121,6 +124,9 @@ onMounted(async () => {
|
|||||||
<n-tab-pane name="sendBox" :tab="t('sendBox')">
|
<n-tab-pane name="sendBox" :tab="t('sendBox')">
|
||||||
<SendBox />
|
<SendBox />
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
<n-tab-pane name="telegram" :tab="t('telegram')">
|
||||||
|
<Telegram />
|
||||||
|
</n-tab-pane>
|
||||||
<n-tab-pane name="statistics" :tab="t('statistics')">
|
<n-tab-pane name="statistics" :tab="t('statistics')">
|
||||||
<Statistics />
|
<Statistics />
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
import { useGlobalState } from '../../store'
|
||||||
|
import { api } from '../../api'
|
||||||
|
|
||||||
|
const { localeCache } = useGlobalState()
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const { t } = useI18n({
|
||||||
|
locale: localeCache.value || 'zh',
|
||||||
|
messages: {
|
||||||
|
en: {
|
||||||
|
init: 'Init',
|
||||||
|
successTip: 'Success',
|
||||||
|
status: 'Check Status',
|
||||||
|
},
|
||||||
|
zh: {
|
||||||
|
init: '初始化',
|
||||||
|
successTip: '成功',
|
||||||
|
status: '查看状态',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const status = ref({
|
||||||
|
fetched: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const res = await api.fetch(`/admin/telegram/status`)
|
||||||
|
Object.assign(status.value, res)
|
||||||
|
status.value.fetched = true
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message || "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
try {
|
||||||
|
await api.fetch(`/admin/telegram/init`, {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
message.success(t('successTip'))
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message || "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="center">
|
||||||
|
<n-card style="max-width: 800px; overflow: auto;">
|
||||||
|
<n-button @click="save" type="primary" block>
|
||||||
|
{{ t('init') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button @click="fetchData" secondary block>
|
||||||
|
{{ t('status') }}
|
||||||
|
</n-button>
|
||||||
|
<pre v-if="status.fetched">{{ JSON.stringify(status, null, 2) }}</pre>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
text-align: left;
|
||||||
|
place-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.n-button {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,22 +5,19 @@ import { GithubAlt, Discord, Telegram } from '@vicons/fa'
|
|||||||
<template>
|
<template>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<n-card>
|
<n-card>
|
||||||
<n-button tag="a" target="_blank" href="https://github.com/dreamhunter2333/cloudflare_temp_email" secondary
|
<n-button tag="a" target="_blank" href="https://github.com/dreamhunter2333/cloudflare_temp_email">
|
||||||
block strong>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="GithubAlt" />
|
<n-icon :component="GithubAlt" />
|
||||||
</template>
|
</template>
|
||||||
Github
|
Github
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button tag="a" target="_blank" href="https://discord.gg/dQEwTWhA6Q" secondary
|
<n-button tag="a" target="_blank" href="https://discord.gg/dQEwTWhA6Q">
|
||||||
block strong>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="Discord" />
|
<n-icon :component="Discord" />
|
||||||
</template>
|
</template>
|
||||||
Discord
|
Discord
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button tag="a" target="_blank" href="https://t.me/cloudflare_temp_email" secondary
|
<n-button tag="a" target="_blank" href="https://t.me/cloudflare_temp_email">
|
||||||
block strong>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="Telegram" />
|
<n-icon :component="Telegram" />
|
||||||
</template>
|
</template>
|
||||||
@@ -38,10 +35,10 @@ import { GithubAlt, Discord, Telegram } from '@vicons/fa'
|
|||||||
|
|
||||||
.n-card {
|
.n-card {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
text-align: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.n-button {
|
.n-button {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ ENABLE_AUTO_REPLY = false
|
|||||||
# dkim config
|
# dkim config
|
||||||
# DKIM_SELECTOR = "mailchannels" # Refer to the DKIM section mailchannels._domainkey for mailchannels
|
# DKIM_SELECTOR = "mailchannels" # Refer to the DKIM section mailchannels._domainkey for mailchannels
|
||||||
# DKIM_PRIVATE_KEY = "" # Refer to the contents of priv_key.txt in the DKIM section
|
# DKIM_PRIVATE_KEY = "" # Refer to the contents of priv_key.txt in the DKIM section
|
||||||
|
# telegram bot
|
||||||
|
# TG_MAX_ACCOUNTS = 5
|
||||||
|
|
||||||
[[d1_databases]]
|
[[d1_databases]]
|
||||||
binding = "DB"
|
binding = "DB"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ cp wrangler.toml.template wrangler.toml
|
|||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> 如果你要启用注册用户功能,并需要发送邮件验证,则需要创建 `KV` 缓存, 不需要可跳过此步骤
|
> 如果你要启用注册用户功能,并需要发送邮件验证,则需要创建 `KV` 缓存, 不需要可跳过此步骤
|
||||||
|
> 如果需要 Telegram Bot,需要创建 `KV` 缓存,不需要可跳过此步骤
|
||||||
|
|
||||||
通过命令行创建 KV 缓存,或者在 Cloudflare 控制台创建,然后复制对应配置到 `wrangler.toml` 文件中
|
通过命令行创建 KV 缓存,或者在 Cloudflare 控制台创建,然后复制对应配置到 `wrangler.toml` 文件中
|
||||||
|
|
||||||
@@ -62,6 +63,8 @@ ENABLE_AUTO_REPLY = false
|
|||||||
# dkim config
|
# dkim config
|
||||||
# DKIM_SELECTOR = "mailchannels" # 参考 DKIM 部分 mailchannels._domainkey 的 mailchannels
|
# DKIM_SELECTOR = "mailchannels" # 参考 DKIM 部分 mailchannels._domainkey 的 mailchannels
|
||||||
# DKIM_PRIVATE_KEY = "" # 参考 DKIM 部分 priv_key.txt 的内容
|
# DKIM_PRIVATE_KEY = "" # 参考 DKIM 部分 priv_key.txt 的内容
|
||||||
|
# telegram bot 最多绑定邮箱数量
|
||||||
|
# TG_MAX_ACCOUNTS = 5
|
||||||
|
|
||||||
# D1 数据库的名称和 ID 可以在 cloudflare 控制台查看
|
# D1 数据库的名称和 ID 可以在 cloudflare 控制台查看
|
||||||
[[d1_databases]]
|
[[d1_databases]]
|
||||||
@@ -83,6 +86,17 @@ database_id = "xxx" # D1 数据库 ID
|
|||||||
# simple = { limit = 10, period = 60 }
|
# simple = { limit = 10, period = 60 }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Telegram Bot 配置
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 如果不需要 Telegram Bot, 可跳过此步骤
|
||||||
|
|
||||||
|
请先创建一个 Telegram Bot,然后获取 `token`,然后执行下面的命令,将 `token` 添加到 secrets 中
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm wrangler secret put TELEGRAM_BOT_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
## 部署
|
## 部署
|
||||||
|
|
||||||
第一次部署会提示创建项目, `production` 分支请填写 `production`
|
第一次部署会提示创建项目, `production` 分支请填写 `production`
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ docker-compose up -d
|
|||||||
|
|
||||||
修改 docker-compose.yaml 中的环境变量, 注意选择合适的 `tag`
|
修改 docker-compose.yaml 中的环境变量, 注意选择合适的 `tag`
|
||||||
|
|
||||||
|
`proxy_url` 为 `worker` 的 URL 地址
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
smtp_proxy_server:
|
smtp_proxy_server:
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
```python
|
```python
|
||||||
limit = 10
|
limit = 10
|
||||||
offset = 0
|
offset = 0
|
||||||
res = requests.post(
|
res = requests.get(
|
||||||
f"http://localhost:8787/api/mails?limit={limit}&offset={offset}`;",
|
f"http://localhost:8787/api/mails?limit={limit}&offset={offset}`;",
|
||||||
json=send_body, headers={
|
headers={
|
||||||
"Authorization": f"Bearer {你的JWT密码}",
|
"Authorization": f"Bearer {你的JWT密码}",
|
||||||
# "x-custom-auth": "<你的网站密码>", # 如果启用了自定义密码
|
# "x-custom-auth": "<你的网站密码>", # 如果启用了自定义密码
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
|
|||||||
@@ -45,3 +45,10 @@
|
|||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
9. Telegram Bot 配置
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> 如果不需要 Telegram Bot, 可跳过此步骤
|
||||||
|
|
||||||
|
请先创建一个 Telegram Bot,然后获取 `token`,然后执行下面的命令,将 `token` 添加到 `Variables` 中, Name: `TELEGRAM_BOT_TOKEN`
|
||||||
|
|||||||
@@ -131,3 +131,4 @@ dist
|
|||||||
|
|
||||||
.wrangler
|
.wrangler
|
||||||
wrangler.toml
|
wrangler.toml
|
||||||
|
.dev.vars
|
||||||
|
|||||||
+12
-4
@@ -5,15 +5,23 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "wrangler dev",
|
"dev": "wrangler dev",
|
||||||
"deploy": "wrangler deploy",
|
"deploy": "wrangler deploy --minify",
|
||||||
"start": "wrangler dev",
|
"start": "wrangler dev",
|
||||||
"build": "wrangler deploy src/worker.js --dry-run --outdir dist --minify"
|
"build": "wrangler deploy src/worker.js --dry-run --outdir dist --minify"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"wrangler": "^3.53.1"
|
"@cloudflare/workers-types": "^4.20240512.0",
|
||||||
|
"wrangler": "^3.55.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hono": "^4.3.0",
|
"hono": "^4.3.6",
|
||||||
"mimetext": "^3.0.24"
|
"mimetext": "^3.0.24",
|
||||||
|
"postal-mime": "^2.2.5",
|
||||||
|
"telegraf": "4.16.3"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"patchedDependencies": {
|
||||||
|
"telegraf@4.16.3": "patches/telegraf@4.16.3.patch"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
diff --git a/lib/core/network/client.js b/lib/core/network/client.js
|
||||||
|
index 25fbbbb47c7f88e83ae26f629e5ae1a0c141725c..209d4a6bf05352f44eeb082eb327581d698de5ce 100644
|
||||||
|
--- a/lib/core/network/client.js
|
||||||
|
+++ b/lib/core/network/client.js
|
||||||
|
@@ -1,18 +1,18 @@
|
||||||
|
"use strict";
|
||||||
|
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function (o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
- desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
+ desc = { enumerable: true, get: function () { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
-}) : (function(o, m, k, k2) {
|
||||||
|
+}) : (function (o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function (o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
-}) : function(o, v) {
|
||||||
|
+}) : function (o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
@@ -29,8 +29,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
/* eslint @typescript-eslint/restrict-template-expressions: [ "error", { "allowNumber": true, "allowBoolean": true } ] */
|
||||||
|
const crypto = __importStar(require("crypto"));
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
-const promises_1 = require("fs/promises");
|
||||||
|
-const https = __importStar(require("https"));
|
||||||
|
+// const promises_1 = require("fs/promises");
|
||||||
|
+// const https = __importStar(require("https"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
||||||
|
const check_1 = require("../helpers/check");
|
||||||
|
@@ -61,10 +61,10 @@ const DEFAULT_OPTIONS = {
|
||||||
|
apiRoot: 'https://api.telegram.org',
|
||||||
|
apiMode: 'bot',
|
||||||
|
webhookReply: true,
|
||||||
|
- agent: new https.Agent({
|
||||||
|
- keepAlive: true,
|
||||||
|
- keepAliveMsecs: 10000,
|
||||||
|
- }),
|
||||||
|
+ // agent: new https.Agent({
|
||||||
|
+ // keepAlive: true,
|
||||||
|
+ // keepAliveMsecs: 10000,
|
||||||
|
+ // }),
|
||||||
|
attachmentAgent: undefined,
|
||||||
|
testEnv: false,
|
||||||
|
};
|
||||||
|
@@ -112,9 +112,9 @@ async function buildFormDataConfig(payload, agent) {
|
||||||
|
}
|
||||||
|
const boundary = crypto.randomBytes(32).toString('hex');
|
||||||
|
const formData = new multipart_stream_1.default(boundary);
|
||||||
|
- await Promise.all(Object.keys(payload).map((key) =>
|
||||||
|
- // @ts-expect-error payload[key] can obviously index payload, but TS doesn't trust us
|
||||||
|
- attachFormValue(formData, key, payload[key], agent)));
|
||||||
|
+ await Promise.all(Object.keys(payload).map((key) =>
|
||||||
|
+ // @ts-expect-error payload[key] can obviously index payload, but TS doesn't trust us
|
||||||
|
+ attachFormValue(formData, key, payload[key], agent)));
|
||||||
|
return {
|
||||||
|
method: 'POST',
|
||||||
|
compress: true,
|
||||||
|
@@ -205,14 +205,15 @@ async function attachFormMedia(form, media, id, agent) {
|
||||||
|
if ('source' in media && media.source) {
|
||||||
|
let mediaSource = media.source;
|
||||||
|
if (typeof media.source === 'string') {
|
||||||
|
- const source = await (0, promises_1.realpath)(media.source);
|
||||||
|
- if ((await (0, promises_1.stat)(source)).isFile()) {
|
||||||
|
- fileName = (_c = media.filename) !== null && _c !== void 0 ? _c : path.basename(media.source);
|
||||||
|
- mediaSource = await fs.createReadStream(media.source);
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- throw new TypeError(`Unable to upload '${media.source}', not a file`);
|
||||||
|
- }
|
||||||
|
+ throw new TypeError(`Unable to upload '${media.source}', not a file`);
|
||||||
|
+ // const source = await (0, promises_1.realpath)(media.source);
|
||||||
|
+ // if ((await (0, promises_1.stat)(source)).isFile()) {
|
||||||
|
+ // fileName = (_c = media.filename) !== null && _c !== void 0 ? _c : path.basename(media.source);
|
||||||
|
+ // mediaSource = await fs.createReadStream(media.source);
|
||||||
|
+ // }
|
||||||
|
+ // else {
|
||||||
|
+ // throw new TypeError(`Unable to upload '${media.source}', not a file`);
|
||||||
|
+ // }
|
||||||
|
}
|
||||||
|
if (isStream(mediaSource) || Buffer.isBuffer(mediaSource)) {
|
||||||
|
form.addPart({
|
||||||
|
diff --git a/lib/core/network/polling.js b/lib/core/network/polling.js
|
||||||
|
index 42f20a5090304c56d0970da56eeaaacaa518ca92..0ae889c32d46e33440c62ad6d27a290c0fe3dda2 100644
|
||||||
|
--- a/lib/core/network/polling.js
|
||||||
|
+++ b/lib/core/network/polling.js
|
||||||
|
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Polling = void 0;
|
||||||
|
const abort_controller_1 = __importDefault(require("abort-controller"));
|
||||||
|
const debug_1 = __importDefault(require("debug"));
|
||||||
|
-const util_1 = require("util");
|
||||||
|
+// const util_1 = require("util");
|
||||||
|
const error_1 = require("./error");
|
||||||
|
const debug = (0, debug_1.default)('telegraf:polling');
|
||||||
|
-const wait = (0, util_1.promisify)(setTimeout);
|
||||||
|
+// const wait = (0, util_1.promisify)(setTimeout);
|
||||||
|
function always(x) {
|
||||||
|
return () => x;
|
||||||
|
}
|
||||||
|
@@ -47,7 +47,8 @@ class Polling {
|
||||||
|
(err instanceof error_1.TelegramError && err.code >= 500)) {
|
||||||
|
const retryAfter = (_b = (_a = err.parameters) === null || _a === void 0 ? void 0 : _a.retry_after) !== null && _b !== void 0 ? _b : 5;
|
||||||
|
debug('Failed to fetch updates, retrying after %ds.', retryAfter, err);
|
||||||
|
- await wait(retryAfter * 1000);
|
||||||
|
+ // await wait(retryAfter * 1000);
|
||||||
|
+ await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (err instanceof error_1.TelegramError &&
|
||||||
|
diff --git a/lib/telegraf.js b/lib/telegraf.js
|
||||||
|
index 23d021c3d5f98493bd714a2114ec8fa853560e5c..90094d18316138b7e12eab42f722e69ccc9b6c1f 100644
|
||||||
|
--- a/lib/telegraf.js
|
||||||
|
+++ b/lib/telegraf.js
|
||||||
|
@@ -28,8 +28,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Telegraf = void 0;
|
||||||
|
const crypto = __importStar(require("crypto"));
|
||||||
|
-const http = __importStar(require("http"));
|
||||||
|
-const https = __importStar(require("https"));
|
||||||
|
+// const http = __importStar(require("http"));
|
||||||
|
+// const https = __importStar(require("https"));
|
||||||
|
const composer_1 = require("./composer");
|
||||||
|
const compact_1 = require("./core/helpers/compact");
|
||||||
|
const context_1 = __importDefault(require("./context"));
|
||||||
|
@@ -157,13 +157,13 @@ class Telegraf extends composer_1.Composer {
|
||||||
|
const callback = typeof cb === 'function'
|
||||||
|
? (req, res) => webhookCb(req, res, () => cb(req, res))
|
||||||
|
: webhookCb;
|
||||||
|
- this.webhookServer =
|
||||||
|
- tlsOptions != null
|
||||||
|
- ? https.createServer(tlsOptions, callback)
|
||||||
|
- : http.createServer(callback);
|
||||||
|
- this.webhookServer.listen(port, host, () => {
|
||||||
|
- debug('Webhook listening on port: %s', port);
|
||||||
|
- });
|
||||||
|
+ // this.webhookServer =
|
||||||
|
+ // tlsOptions != null
|
||||||
|
+ // ? https.createServer(tlsOptions, callback)
|
||||||
|
+ // : http.createServer(callback);
|
||||||
|
+ // this.webhookServer.listen(port, host, () => {
|
||||||
|
+ // debug('Webhook listening on port: %s', port);
|
||||||
|
+ // });
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
secretPathComponent() {
|
||||||
|
@@ -176,7 +176,7 @@ class Telegraf extends composer_1.Composer {
|
||||||
|
/**
|
||||||
|
* @see https://github.com/telegraf/telegraf/discussions/1344#discussioncomment-335700
|
||||||
|
*/
|
||||||
|
- async launch(config = {},
|
||||||
|
+ async launch(config = {},
|
||||||
|
/** @experimental */
|
||||||
|
onLaunch) {
|
||||||
|
var _a, _b;
|
||||||
Generated
+163
-26
@@ -4,20 +4,34 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
patchedDependencies:
|
||||||
|
telegraf@4.16.3:
|
||||||
|
hash: pnqp5pf7vetkijrc5uah4r5w6m
|
||||||
|
path: patches/telegraf@4.16.3.patch
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
hono:
|
hono:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.6
|
||||||
version: 4.3.0
|
version: 4.3.6
|
||||||
mimetext:
|
mimetext:
|
||||||
specifier: ^3.0.24
|
specifier: ^3.0.24
|
||||||
version: 3.0.24
|
version: 3.0.24
|
||||||
|
postal-mime:
|
||||||
|
specifier: ^2.2.5
|
||||||
|
version: 2.2.5
|
||||||
|
telegraf:
|
||||||
|
specifier: 4.16.3
|
||||||
|
version: 4.16.3(patch_hash=pnqp5pf7vetkijrc5uah4r5w6m)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@cloudflare/workers-types':
|
||||||
|
specifier: ^4.20240512.0
|
||||||
|
version: 4.20240512.0
|
||||||
wrangler:
|
wrangler:
|
||||||
specifier: ^3.53.1
|
specifier: ^3.55.0
|
||||||
version: 3.53.1
|
version: 3.55.0(@cloudflare/workers-types@4.20240512.0)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -63,6 +77,9 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
|
'@cloudflare/workers-types@4.20240512.0':
|
||||||
|
resolution: {integrity: sha512-o2yTEWg+YK/I1t/Me+dA0oarO0aCbjibp6wSeaw52DSE9tDyKJ7S+Qdyw/XsMrKn4t8kF6f/YOba+9O4MJfW9w==}
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -223,11 +240,18 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.9':
|
'@jridgewell/trace-mapping@0.3.9':
|
||||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||||
|
|
||||||
|
'@telegraf/types@7.1.0':
|
||||||
|
resolution: {integrity: sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw==}
|
||||||
|
|
||||||
'@types/node-forge@1.3.11':
|
'@types/node-forge@1.3.11':
|
||||||
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
||||||
|
|
||||||
'@types/node@20.12.8':
|
'@types/node@20.12.12':
|
||||||
resolution: {integrity: sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==}
|
resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==}
|
||||||
|
|
||||||
|
abort-controller@3.0.0:
|
||||||
|
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||||
|
engines: {node: '>=6.5'}
|
||||||
|
|
||||||
acorn-walk@8.3.2:
|
acorn-walk@8.3.2:
|
||||||
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
|
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
|
||||||
@@ -256,6 +280,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
buffer-alloc-unsafe@1.1.0:
|
||||||
|
resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==}
|
||||||
|
|
||||||
|
buffer-alloc@1.2.0:
|
||||||
|
resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==}
|
||||||
|
|
||||||
|
buffer-fill@1.0.0:
|
||||||
|
resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==}
|
||||||
|
|
||||||
capnp-ts@0.7.0:
|
capnp-ts@0.7.0:
|
||||||
resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==}
|
resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==}
|
||||||
|
|
||||||
@@ -267,8 +300,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
core-js-pure@3.37.0:
|
core-js-pure@3.37.1:
|
||||||
resolution: {integrity: sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ==}
|
resolution: {integrity: sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==}
|
||||||
|
|
||||||
data-uri-to-buffer@2.0.2:
|
data-uri-to-buffer@2.0.2:
|
||||||
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
|
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
|
||||||
@@ -294,6 +327,10 @@ packages:
|
|||||||
estree-walker@0.6.1:
|
estree-walker@0.6.1:
|
||||||
resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
|
resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
|
||||||
|
|
||||||
|
event-target-shim@5.0.1:
|
||||||
|
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
exit-hook@2.2.1:
|
exit-hook@2.2.1:
|
||||||
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
|
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -324,8 +361,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
hono@4.3.0:
|
hono@4.3.6:
|
||||||
resolution: {integrity: sha512-rf9142VLQNMVBj+BjVLISgDWDxnJGUIuX39dvqcdySwr2gTsPfsqW1twWDUjfwQNWm9hEn40MpDu9RFGUN+e8A==}
|
resolution: {integrity: sha512-2IqXwrxWF4tG2AR7b5tMYn+KEnWK8UvdC/NUSbOKWj/Kj11OJqel58FxyiXLK5CcKLiL8aGtTe4lkBKXyaHMBQ==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
@@ -369,11 +406,15 @@ packages:
|
|||||||
mimetext@3.0.24:
|
mimetext@3.0.24:
|
||||||
resolution: {integrity: sha512-UdG1KVfcxeEfo6el91lzFG2WLLTm8DxSK/rosxx5H2Pjla50+DSsjTgr9BRAfAkbQWaxvzcaTO+bHK5ZrdKdfA==}
|
resolution: {integrity: sha512-UdG1KVfcxeEfo6el91lzFG2WLLTm8DxSK/rosxx5H2Pjla50+DSsjTgr9BRAfAkbQWaxvzcaTO+bHK5ZrdKdfA==}
|
||||||
|
|
||||||
miniflare@3.20240419.0:
|
miniflare@3.20240419.1:
|
||||||
resolution: {integrity: sha512-fIev1PP4H+fQp5FtvzHqRY2v5s+jxh/a0xAhvM5fBNXvxWX7Zod1OatXfXwYbse3hqO3KeVMhb0osVtrW0NwJg==}
|
resolution: {integrity: sha512-Q9n0W07uUD/u0c/b03E4iogeXOAMjZnE3P7B5Yi8sPaZAx6TYWwjurGBja+Pg2yILN2iMaliEobfVyAKss33cA==}
|
||||||
engines: {node: '>=16.13'}
|
engines: {node: '>=16.13'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
mri@1.2.0:
|
||||||
|
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
ms@2.1.2:
|
ms@2.1.2:
|
||||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||||
|
|
||||||
@@ -386,6 +427,15 @@ packages:
|
|||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-forge@1.3.1:
|
node-forge@1.3.1:
|
||||||
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
|
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
|
||||||
engines: {node: '>= 6.13.0'}
|
engines: {node: '>= 6.13.0'}
|
||||||
@@ -394,6 +444,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
p-timeout@4.1.0:
|
||||||
|
resolution: {integrity: sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
path-parse@1.0.7:
|
path-parse@1.0.7:
|
||||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||||
|
|
||||||
@@ -404,6 +458,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
|
postal-mime@2.2.5:
|
||||||
|
resolution: {integrity: sha512-6eTJf+B47JMdDuLF/4MBiGpTinxl0W8bA9CzrSoiQrNVRqK8Vhe59VrS6sXh2lG/lgo0bxpZFcWOF4Dv1FaSfg==}
|
||||||
|
|
||||||
printable-characters@1.0.42:
|
printable-characters@1.0.42:
|
||||||
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
|
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
|
||||||
|
|
||||||
@@ -432,6 +489,13 @@ packages:
|
|||||||
rollup-pluginutils@2.8.2:
|
rollup-pluginutils@2.8.2:
|
||||||
resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
|
resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
|
||||||
|
|
||||||
|
safe-compare@1.1.4:
|
||||||
|
resolution: {integrity: sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ==}
|
||||||
|
|
||||||
|
sandwich-stream@2.0.2:
|
||||||
|
resolution: {integrity: sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==}
|
||||||
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
selfsigned@2.4.1:
|
selfsigned@2.4.1:
|
||||||
resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
|
resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -455,10 +519,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
telegraf@4.16.3:
|
||||||
|
resolution: {integrity: sha512-yjEu2NwkHlXu0OARWoNhJlIjX09dRktiMQFsM678BAH/PEPVwctzL67+tvXqLCRQQvm3SDtki2saGO9hLlz68w==}
|
||||||
|
engines: {node: ^12.20.0 || >=14.13.1}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
|
|
||||||
|
tr46@0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
|
||||||
tslib@2.6.2:
|
tslib@2.6.2:
|
||||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||||
|
|
||||||
@@ -469,13 +541,19 @@ packages:
|
|||||||
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
||||||
engines: {node: '>=14.0'}
|
engines: {node: '>=14.0'}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1:
|
||||||
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
workerd@1.20240419.0:
|
workerd@1.20240419.0:
|
||||||
resolution: {integrity: sha512-9yV98KpkQgG+bdEsKEW8i1AYZgxns6NVSfdOVEB2Ue1pTMtIEYfUyqUE+O2amisRrfaC3Pw4EvjtTmVaoetfeg==}
|
resolution: {integrity: sha512-9yV98KpkQgG+bdEsKEW8i1AYZgxns6NVSfdOVEB2Ue1pTMtIEYfUyqUE+O2amisRrfaC3Pw4EvjtTmVaoetfeg==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
wrangler@3.53.1:
|
wrangler@3.55.0:
|
||||||
resolution: {integrity: sha512-bdMRQdHYdvowIwOhEMFkARIZUh56aDw7HLUZ/2JreBjj760osXE4Fc4L1TCkfRRBWgB6/LKF5LA4OcvORMYmHg==}
|
resolution: {integrity: sha512-VhtCioKxOdVqkHa8jQ6C6bX3by2Ko0uM0DKzrA+6lBZvfDUlGDWSOPiG+1fOHBHj2JTVBntxWCztXP6L+Udr8w==}
|
||||||
engines: {node: '>=16.17.0'}
|
engines: {node: '>=16.17.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -502,14 +580,14 @@ packages:
|
|||||||
youch@3.3.3:
|
youch@3.3.3:
|
||||||
resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==}
|
resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==}
|
||||||
|
|
||||||
zod@3.23.6:
|
zod@3.23.8:
|
||||||
resolution: {integrity: sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA==}
|
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@babel/runtime-corejs3@7.24.5':
|
'@babel/runtime-corejs3@7.24.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
core-js-pure: 3.37.0
|
core-js-pure: 3.37.1
|
||||||
regenerator-runtime: 0.14.1
|
regenerator-runtime: 0.14.1
|
||||||
|
|
||||||
'@babel/runtime@7.24.5':
|
'@babel/runtime@7.24.5':
|
||||||
@@ -535,6 +613,8 @@ snapshots:
|
|||||||
'@cloudflare/workerd-windows-64@1.20240419.0':
|
'@cloudflare/workerd-windows-64@1.20240419.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@cloudflare/workers-types@4.20240512.0': {}
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/trace-mapping': 0.3.9
|
'@jridgewell/trace-mapping': 0.3.9
|
||||||
@@ -626,14 +706,20 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
|
|
||||||
|
'@telegraf/types@7.1.0': {}
|
||||||
|
|
||||||
'@types/node-forge@1.3.11':
|
'@types/node-forge@1.3.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.12.8
|
'@types/node': 20.12.12
|
||||||
|
|
||||||
'@types/node@20.12.8':
|
'@types/node@20.12.12':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
|
abort-controller@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
event-target-shim: 5.0.1
|
||||||
|
|
||||||
acorn-walk@8.3.2: {}
|
acorn-walk@8.3.2: {}
|
||||||
|
|
||||||
acorn@8.11.3: {}
|
acorn@8.11.3: {}
|
||||||
@@ -655,6 +741,15 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fill-range: 7.0.1
|
fill-range: 7.0.1
|
||||||
|
|
||||||
|
buffer-alloc-unsafe@1.1.0: {}
|
||||||
|
|
||||||
|
buffer-alloc@1.2.0:
|
||||||
|
dependencies:
|
||||||
|
buffer-alloc-unsafe: 1.1.0
|
||||||
|
buffer-fill: 1.0.0
|
||||||
|
|
||||||
|
buffer-fill@1.0.0: {}
|
||||||
|
|
||||||
capnp-ts@0.7.0:
|
capnp-ts@0.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
@@ -676,7 +771,7 @@ snapshots:
|
|||||||
|
|
||||||
cookie@0.5.0: {}
|
cookie@0.5.0: {}
|
||||||
|
|
||||||
core-js-pure@3.37.0: {}
|
core-js-pure@3.37.1: {}
|
||||||
|
|
||||||
data-uri-to-buffer@2.0.2: {}
|
data-uri-to-buffer@2.0.2: {}
|
||||||
|
|
||||||
@@ -713,6 +808,8 @@ snapshots:
|
|||||||
|
|
||||||
estree-walker@0.6.1: {}
|
estree-walker@0.6.1: {}
|
||||||
|
|
||||||
|
event-target-shim@5.0.1: {}
|
||||||
|
|
||||||
exit-hook@2.2.1: {}
|
exit-hook@2.2.1: {}
|
||||||
|
|
||||||
fill-range@7.0.1:
|
fill-range@7.0.1:
|
||||||
@@ -739,7 +836,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
hono@4.3.0: {}
|
hono@4.3.6: {}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -778,7 +875,7 @@ snapshots:
|
|||||||
js-base64: 3.7.7
|
js-base64: 3.7.7
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
|
|
||||||
miniflare@3.20240419.0:
|
miniflare@3.20240419.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@cspotcode/source-map-support': 0.8.1
|
'@cspotcode/source-map-support': 0.8.1
|
||||||
acorn: 8.11.3
|
acorn: 8.11.3
|
||||||
@@ -791,28 +888,38 @@ snapshots:
|
|||||||
workerd: 1.20240419.0
|
workerd: 1.20240419.0
|
||||||
ws: 8.17.0
|
ws: 8.17.0
|
||||||
youch: 3.3.3
|
youch: 3.3.3
|
||||||
zod: 3.23.6
|
zod: 3.23.8
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- supports-color
|
- supports-color
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
|
mri@1.2.0: {}
|
||||||
|
|
||||||
ms@2.1.2: {}
|
ms@2.1.2: {}
|
||||||
|
|
||||||
mustache@4.2.0: {}
|
mustache@4.2.0: {}
|
||||||
|
|
||||||
nanoid@3.3.7: {}
|
nanoid@3.3.7: {}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
node-forge@1.3.1: {}
|
node-forge@1.3.1: {}
|
||||||
|
|
||||||
normalize-path@3.0.0: {}
|
normalize-path@3.0.0: {}
|
||||||
|
|
||||||
|
p-timeout@4.1.0: {}
|
||||||
|
|
||||||
path-parse@1.0.7: {}
|
path-parse@1.0.7: {}
|
||||||
|
|
||||||
path-to-regexp@6.2.2: {}
|
path-to-regexp@6.2.2: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
|
|
||||||
|
postal-mime@2.2.5: {}
|
||||||
|
|
||||||
printable-characters@1.0.42: {}
|
printable-characters@1.0.42: {}
|
||||||
|
|
||||||
readdirp@3.6.0:
|
readdirp@3.6.0:
|
||||||
@@ -843,6 +950,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
estree-walker: 0.6.1
|
estree-walker: 0.6.1
|
||||||
|
|
||||||
|
safe-compare@1.1.4:
|
||||||
|
dependencies:
|
||||||
|
buffer-alloc: 1.2.0
|
||||||
|
|
||||||
|
sandwich-stream@2.0.2: {}
|
||||||
|
|
||||||
selfsigned@2.4.1:
|
selfsigned@2.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node-forge': 1.3.11
|
'@types/node-forge': 1.3.11
|
||||||
@@ -861,10 +974,26 @@ snapshots:
|
|||||||
|
|
||||||
supports-preserve-symlinks-flag@1.0.0: {}
|
supports-preserve-symlinks-flag@1.0.0: {}
|
||||||
|
|
||||||
|
telegraf@4.16.3(patch_hash=pnqp5pf7vetkijrc5uah4r5w6m):
|
||||||
|
dependencies:
|
||||||
|
'@telegraf/types': 7.1.0
|
||||||
|
abort-controller: 3.0.0
|
||||||
|
debug: 4.3.4
|
||||||
|
mri: 1.2.0
|
||||||
|
node-fetch: 2.7.0
|
||||||
|
p-timeout: 4.1.0
|
||||||
|
safe-compare: 1.1.4
|
||||||
|
sandwich-stream: 2.0.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
- supports-color
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
|
|
||||||
|
tr46@0.0.3: {}
|
||||||
|
|
||||||
tslib@2.6.2: {}
|
tslib@2.6.2: {}
|
||||||
|
|
||||||
undici-types@5.26.5: {}
|
undici-types@5.26.5: {}
|
||||||
@@ -873,6 +1002,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@fastify/busboy': 2.1.1
|
'@fastify/busboy': 2.1.1
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
tr46: 0.0.3
|
||||||
|
webidl-conversions: 3.0.1
|
||||||
|
|
||||||
workerd@1.20240419.0:
|
workerd@1.20240419.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@cloudflare/workerd-darwin-64': 1.20240419.0
|
'@cloudflare/workerd-darwin-64': 1.20240419.0
|
||||||
@@ -881,7 +1017,7 @@ snapshots:
|
|||||||
'@cloudflare/workerd-linux-arm64': 1.20240419.0
|
'@cloudflare/workerd-linux-arm64': 1.20240419.0
|
||||||
'@cloudflare/workerd-windows-64': 1.20240419.0
|
'@cloudflare/workerd-windows-64': 1.20240419.0
|
||||||
|
|
||||||
wrangler@3.53.1:
|
wrangler@3.55.0(@cloudflare/workers-types@4.20240512.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@cloudflare/kv-asset-handler': 0.3.2
|
'@cloudflare/kv-asset-handler': 0.3.2
|
||||||
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
|
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
|
||||||
@@ -889,7 +1025,7 @@ snapshots:
|
|||||||
blake3-wasm: 2.1.5
|
blake3-wasm: 2.1.5
|
||||||
chokidar: 3.6.0
|
chokidar: 3.6.0
|
||||||
esbuild: 0.17.19
|
esbuild: 0.17.19
|
||||||
miniflare: 3.20240419.0
|
miniflare: 3.20240419.1
|
||||||
nanoid: 3.3.7
|
nanoid: 3.3.7
|
||||||
path-to-regexp: 6.2.2
|
path-to-regexp: 6.2.2
|
||||||
resolve: 1.22.8
|
resolve: 1.22.8
|
||||||
@@ -898,6 +1034,7 @@ snapshots:
|
|||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
xxhash-wasm: 1.0.2
|
xxhash-wasm: 1.0.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@cloudflare/workers-types': 4.20240512.0
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
@@ -914,4 +1051,4 @@ snapshots:
|
|||||||
mustache: 4.2.0
|
mustache: 4.2.0
|
||||||
stacktracey: 2.1.8
|
stacktracey: 2.1.8
|
||||||
|
|
||||||
zod@3.23.6: {}
|
zod@3.23.8: {}
|
||||||
|
|||||||
@@ -36,7 +36,12 @@ api.post('/admin/new_address', async (c) => {
|
|||||||
if (!name) {
|
if (!name) {
|
||||||
return c.text("Please provide a name", 400)
|
return c.text("Please provide a name", 400)
|
||||||
}
|
}
|
||||||
return newAddress(c, name, domain, enablePrefix);
|
try {
|
||||||
|
const res = await newAddress(c, name, domain, enablePrefix);
|
||||||
|
return c.json(res);
|
||||||
|
} catch (e) {
|
||||||
|
return c.text(`Failed create address: ${e.message}`, 400)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
api.delete('/admin/delete_address/:id', async (c) => {
|
api.delete('/admin/delete_address/:id', async (c) => {
|
||||||
|
|||||||
+12
-15
@@ -7,14 +7,14 @@ export const newAddress = async (c, name, domain, enablePrefix) => {
|
|||||||
name = name.replace(/[^a-zA-Z0-9.]/g, '')
|
name = name.replace(/[^a-zA-Z0-9.]/g, '')
|
||||||
// check name length
|
// check name length
|
||||||
if (name.length < 0) {
|
if (name.length < 0) {
|
||||||
return c.text("Name too short", 400)
|
throw new Error("Name too short")
|
||||||
}
|
}
|
||||||
// create address
|
// create address
|
||||||
if (enablePrefix) {
|
if (enablePrefix) {
|
||||||
name = getStringValue(c.env.PREFIX) + name;
|
name = getStringValue(c.env.PREFIX) + name;
|
||||||
}
|
}
|
||||||
if (name.length >= 30) {
|
if (name.length >= 30) {
|
||||||
return c.text("Name too long (max 30)", 400)
|
throw new Error("Name too long (max 30)")
|
||||||
}
|
}
|
||||||
// check domain, generate random domain
|
// check domain, generate random domain
|
||||||
const domains = getDomains(c);
|
const domains = getDomains(c);
|
||||||
@@ -28,30 +28,27 @@ export const newAddress = async (c, name, domain, enablePrefix) => {
|
|||||||
`INSERT INTO address(name) VALUES(?)`
|
`INSERT INTO address(name) VALUES(?)`
|
||||||
).bind(name).run();
|
).bind(name).run();
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return c.text("Failed to create address", 500)
|
throw new Error("Failed to create address")
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message && e.message.includes("UNIQUE")) {
|
if (e.message && e.message.includes("UNIQUE")) {
|
||||||
return c.text("Address already exists, please retry a new address", 400)
|
throw new Error("Address already exists")
|
||||||
}
|
}
|
||||||
return c.text("Failed to create address", 500)
|
throw new Error("Failed to create address")
|
||||||
}
|
}
|
||||||
let address_id = 0;
|
let address_id = 0;
|
||||||
try {
|
address_id = await c.env.DB.prepare(
|
||||||
address_id = await c.env.DB.prepare(
|
`SELECT id FROM address where name = ?`
|
||||||
`SELECT id FROM address where name = ?`
|
).bind(name).first("id");
|
||||||
).bind(name).first("id");
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
// create jwt
|
// create jwt
|
||||||
const jwt = await Jwt.sign({
|
const jwt = await Jwt.sign({
|
||||||
address: name,
|
address: name,
|
||||||
address_id: address_id
|
address_id: address_id
|
||||||
}, c.env.JWT_SECRET, "HS256")
|
}, c.env.JWT_SECRET, "HS256")
|
||||||
return c.json({
|
return {
|
||||||
jwt: jwt
|
jwt: jwt,
|
||||||
})
|
address: name,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cleanup = async (c, cleanType, cleanDays) => {
|
export const cleanup = async (c, cleanType, cleanDays) => {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
export const CONSTANTS = {
|
export const CONSTANTS = {
|
||||||
VERSION: 'v0.4.2',
|
VERSION: 'v0.4.2',
|
||||||
|
|
||||||
|
// DB settings
|
||||||
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',
|
ADDRESS_BLOCK_LIST_KEY: 'address_block_list',
|
||||||
SEND_BLOCK_LIST_KEY: 'send_block_list',
|
SEND_BLOCK_LIST_KEY: 'send_block_list',
|
||||||
AUTO_CLEANUP_KEY: 'auto_cleanup',
|
AUTO_CLEANUP_KEY: 'auto_cleanup',
|
||||||
USER_SETTINGS_KEY: 'user_settings',
|
USER_SETTINGS_KEY: 'user_settings',
|
||||||
|
|
||||||
|
// KV
|
||||||
|
TG_KV_PREFIX: "temp-mail-telegram"
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createMimeMessage } from "mimetext";
|
import { createMimeMessage } from "mimetext";
|
||||||
import { getBooleanValue } from "./utils";
|
import { getBooleanValue } from "./utils";
|
||||||
|
import { sendMailToTelegram } from "./telegram_api";
|
||||||
|
|
||||||
async function email(message, env, ctx) {
|
async function email(message, env, ctx) {
|
||||||
if (env.BLACK_LIST && env.BLACK_LIST.split(",").some(word => message.from.includes(word))) {
|
if (env.BLACK_LIST && env.BLACK_LIST.split(",").some(word => message.from.includes(word))) {
|
||||||
@@ -20,6 +21,15 @@ async function email(message, env, ctx) {
|
|||||||
console.log(`Failed save message from ${message.from} to ${message.to}`);
|
console.log(`Failed save message from ${message.from} to ${message.to}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send email to telegram
|
||||||
|
try {
|
||||||
|
await sendMailToTelegram({
|
||||||
|
env: env,
|
||||||
|
}, message.to, rawEmail);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("send mail to telegram error", error);
|
||||||
|
}
|
||||||
|
|
||||||
// auto reply email
|
// auto reply email
|
||||||
if (getBooleanValue(env.ENABLE_AUTO_REPLY)) {
|
if (getBooleanValue(env.ENABLE_AUTO_REPLY)) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -106,7 +106,12 @@ api.post('/api/new_address', async (c) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
return newAddress(c, name, domain, true);
|
try {
|
||||||
|
const res = await newAddress(c, name, domain, true);
|
||||||
|
return c.json(res);
|
||||||
|
} catch (e) {
|
||||||
|
return c.text(`Failed create address: ${e.message}`, 400)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
api.delete('/api/delete_address', async (c) => {
|
api.delete('/api/delete_address', async (c) => {
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Hono, Context } from 'hono'
|
||||||
|
import { ServerResponse } from 'node:http'
|
||||||
|
import { Writable } from 'node:stream'
|
||||||
|
import { newTelegramBot, initTelegramBotCommands, sendMailToTelegram } from './telegram'
|
||||||
|
|
||||||
|
export const api = new Hono()
|
||||||
|
export { sendMailToTelegram }
|
||||||
|
|
||||||
|
api.post("/telegram/webhook", async (c: Context) => {
|
||||||
|
const token = c.env.TELEGRAM_BOT_TOKEN;
|
||||||
|
const bot = newTelegramBot(c, token);
|
||||||
|
let body = null;
|
||||||
|
const res = new Writable();
|
||||||
|
Object.assign(res, {
|
||||||
|
headersSent: false,
|
||||||
|
setHeader: (name: string, value: string) => c.header(name, value),
|
||||||
|
end: (data: any) => body = data,
|
||||||
|
});
|
||||||
|
const reqJson = await c.req.json();
|
||||||
|
await bot.handleUpdate(reqJson, res as ServerResponse);
|
||||||
|
return c.body(body);
|
||||||
|
});
|
||||||
|
|
||||||
|
api.post("/admin/telegram/init", async (c: Context) => {
|
||||||
|
if (!c.env.TELEGRAM_BOT_TOKEN || !c.env.KV) {
|
||||||
|
return c.text("TELEGRAM_BOT_TOKEN and KV are required", 400);
|
||||||
|
}
|
||||||
|
const domain = new URL(c.req.url).host;
|
||||||
|
const token = c.env.TELEGRAM_BOT_TOKEN;
|
||||||
|
const webhookUrl = `https://${domain}/telegram/webhook`;
|
||||||
|
console.log(`setting webhook to ${webhookUrl}`);
|
||||||
|
const bot = newTelegramBot(c, token);
|
||||||
|
await bot.telegram.setWebhook(webhookUrl)
|
||||||
|
await initTelegramBotCommands(bot);
|
||||||
|
return c.json({
|
||||||
|
message: "webhook set successfully",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
api.get("/admin/telegram/status", async (c: Context) => {
|
||||||
|
if (!c.env.TELEGRAM_BOT_TOKEN || !c.env.KV) {
|
||||||
|
return c.text("TELEGRAM_BOT_TOKEN and KV are required", 400);
|
||||||
|
}
|
||||||
|
const token = c.env.TELEGRAM_BOT_TOKEN;
|
||||||
|
const bot = newTelegramBot(c, token);
|
||||||
|
const info = await bot.telegram.getWebhookInfo()
|
||||||
|
const commands = await bot.telegram.getMyCommands()
|
||||||
|
return c.json({ info, commands });
|
||||||
|
});
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
|
||||||
|
import { Context } from "hono";
|
||||||
|
import { Jwt } from 'hono/utils/jwt'
|
||||||
|
import { Telegraf, Context as TgContext, Markup } from "telegraf";
|
||||||
|
import { callbackQuery } from "telegraf/filters";
|
||||||
|
import PostalMime from 'postal-mime';
|
||||||
|
|
||||||
|
import { CONSTANTS } from "../constants";
|
||||||
|
// @ts-ignore
|
||||||
|
import { getIntValue, getDomains, getStringValue } from '../utils';
|
||||||
|
// @ts-ignore
|
||||||
|
import { newAddress } from '../common'
|
||||||
|
|
||||||
|
const COMMANDS = [
|
||||||
|
{
|
||||||
|
command: "start",
|
||||||
|
description: "开始使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "new",
|
||||||
|
description: "新建邮箱地址, 如果要自定义邮箱地址, 请输入 /new <name>@<domain>, name [a-zA-Z0-9.] 有效"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "address",
|
||||||
|
description: "查看邮箱地址列表"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "bind",
|
||||||
|
description: "绑定邮箱地址, 请输入 /bind <邮箱地址凭证>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: "mails",
|
||||||
|
description: "查看邮件, 请输入 /mails <邮箱地址>, 不输入地址默认查看第一个地址"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export function newTelegramBot(c: Context, token: string): Telegraf {
|
||||||
|
const bot = new Telegraf(token);
|
||||||
|
bot.command("start", async (ctx: TgContext) => {
|
||||||
|
if (ctx.chat?.type !== "private") {
|
||||||
|
return await ctx.reply("请在私聊中使用");
|
||||||
|
}
|
||||||
|
const prefix = getStringValue(c.env.PREFIX)
|
||||||
|
const domains = getDomains(c);
|
||||||
|
return await ctx.reply(
|
||||||
|
"欢迎使用本机器人\n\n"
|
||||||
|
+ (prefix ? `当前已启用前缀: ${prefix}\n` : '')
|
||||||
|
+ "新建邮箱地址, 如果要自定义邮箱地址, "
|
||||||
|
+ "请输入 /new <name>@<domain>, name [a-zA-Z0-9.] 有效\n"
|
||||||
|
+ `当前可用域名: ${JSON.stringify(domains)}\n`
|
||||||
|
+ "请使用以下命令:\n"
|
||||||
|
+ COMMANDS.map(c => `/${c.command}: ${c.description}`).join("\n")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
bot.command("new", async (ctx: TgContext) => {
|
||||||
|
if (ctx.chat?.type !== "private") {
|
||||||
|
return await ctx.reply("请在私聊中使用");
|
||||||
|
}
|
||||||
|
const userId = ctx?.message?.from?.id;
|
||||||
|
if (!userId) {
|
||||||
|
return await ctx.reply("无法获取用户信息");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const address = ctx?.message?.text.slice("/new".length).trim();
|
||||||
|
if (!address) {
|
||||||
|
return await ctx.reply("请输入邮箱地址");
|
||||||
|
}
|
||||||
|
const [name, domain] = address.includes("@") ? address.split("@") : [address, null];
|
||||||
|
const jwtList = await c.env.KV.get(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, { type: 'json' }) || [];
|
||||||
|
if (jwtList.length >= getIntValue(c.env.TG_MAX_ADDRESS, 5)) {
|
||||||
|
return await ctx.reply("绑定地址数量已达上限");
|
||||||
|
}
|
||||||
|
const res = await newAddress(c, name, domain, true);
|
||||||
|
// for mail push to telegram
|
||||||
|
await c.env.KV.put(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, JSON.stringify([...jwtList, res.jwt]));
|
||||||
|
await c.env.KV.put(`${CONSTANTS.TG_KV_PREFIX}:${res.address}`, userId);
|
||||||
|
return await ctx.reply(`创建地址成功:\n`
|
||||||
|
+ `地址: ${res.address}\n`
|
||||||
|
+ `凭证: ${res.jwt}\n`
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return await ctx.reply(`创建地址失败: ${(e as Error).message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bot.command("bind", async (ctx: TgContext) => {
|
||||||
|
if (ctx.chat?.type !== "private") {
|
||||||
|
return await ctx.reply("请在私聊中使用");
|
||||||
|
}
|
||||||
|
const userId = ctx?.message?.from?.id;
|
||||||
|
if (!userId) {
|
||||||
|
return await ctx.reply("无法获取用户信息");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const jwt = ctx?.message?.text.slice("/bind".length).trim();
|
||||||
|
if (!jwt) {
|
||||||
|
return await ctx.reply("请输入凭证");
|
||||||
|
}
|
||||||
|
const { address } = await Jwt.verify(jwt, c.env.JWT_SECRET, "HS256");
|
||||||
|
if (!address) {
|
||||||
|
return await ctx.reply("凭证无效");
|
||||||
|
}
|
||||||
|
const jwtList = await c.env.KV.get(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, { type: 'json' }) || [];
|
||||||
|
if (jwtList.length >= getIntValue(c.env.TG_MAX_ADDRESS, 5)) {
|
||||||
|
return await ctx.reply("绑定地址数量已达上限");
|
||||||
|
}
|
||||||
|
await c.env.KV.put(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, JSON.stringify([...jwtList, jwt]));
|
||||||
|
// for mail push to telegram
|
||||||
|
await c.env.KV.put(`${CONSTANTS.TG_KV_PREFIX}:${address}`, userId);
|
||||||
|
return await ctx.reply(`绑定成功:\n`
|
||||||
|
+ `地址: ${address}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return await ctx.reply(`绑定失败: ${(e as Error).message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bot.command("address", async (ctx: TgContext) => {
|
||||||
|
if (ctx.chat?.type !== "private") {
|
||||||
|
return await ctx.reply("请在私聊中使用");
|
||||||
|
}
|
||||||
|
const userId = ctx?.message?.from?.id;
|
||||||
|
if (!userId) {
|
||||||
|
return await ctx.reply("无法获取用户信息");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const jwtList = await c.env.KV.get(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, { type: 'json' }) || [];
|
||||||
|
const addressList = [];
|
||||||
|
for (const jwt of jwtList) {
|
||||||
|
try {
|
||||||
|
const { address } = await Jwt.verify(jwt, c.env.JWT_SECRET, "HS256");
|
||||||
|
addressList.push(address);
|
||||||
|
} catch (e) {
|
||||||
|
addressList.push("此凭证无效");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await ctx.reply(`地址列表:\n\n`
|
||||||
|
+ addressList.map(a => `地址: ${a}`).join("\n")
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return await ctx.reply(`获取地址列表失败: ${(e as Error).message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const queryMail = async (ctx: TgContext, queryAddress: string, mailIndex: number, edit: boolean) => {
|
||||||
|
const userId = ctx?.message?.from?.id || ctx.callbackQuery?.message?.chat?.id;
|
||||||
|
if (!userId) {
|
||||||
|
return await ctx.reply("无法获取用户信息");
|
||||||
|
}
|
||||||
|
const jwtList = await c.env.KV.get(`${CONSTANTS.TG_KV_PREFIX}:${userId}`, { type: 'json' }) || [];
|
||||||
|
const addressList = [];
|
||||||
|
for (const jwt of jwtList) {
|
||||||
|
try {
|
||||||
|
const { address } = await Jwt.verify(jwt, c.env.JWT_SECRET, "HS256");
|
||||||
|
addressList.push(address);
|
||||||
|
} catch (e) {
|
||||||
|
addressList.push("此凭证无效");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!queryAddress && addressList.length > 0) {
|
||||||
|
queryAddress = addressList[0];
|
||||||
|
}
|
||||||
|
if (!addressList.includes(queryAddress)) {
|
||||||
|
return await ctx.reply(`未绑定此地址 ${queryAddress}`);
|
||||||
|
}
|
||||||
|
const raw = await c.env.DB.prepare(
|
||||||
|
`SELECT * FROM raw_mails where address = ? `
|
||||||
|
+ ` order by id desc limit 1 offset ?`
|
||||||
|
).bind(
|
||||||
|
queryAddress, mailIndex
|
||||||
|
).first("raw");
|
||||||
|
const { mail } = await parseMail(raw);
|
||||||
|
if (edit) {
|
||||||
|
return await ctx.editMessageText(mail || "无邮件",
|
||||||
|
{
|
||||||
|
...Markup.inlineKeyboard([
|
||||||
|
Markup.button.callback("上一条", `mail_${queryAddress}_${mailIndex - 1}`, mailIndex <= 0),
|
||||||
|
Markup.button.callback("下一条", `mail_${queryAddress}_${mailIndex + 1}`, !raw),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return await ctx.reply(mail || "无邮件",
|
||||||
|
{
|
||||||
|
...Markup.inlineKeyboard([
|
||||||
|
Markup.button.callback("上一条", `mail_${queryAddress}_${mailIndex - 1}`, mailIndex <= 0),
|
||||||
|
Markup.button.callback("下一条", `mail_${queryAddress}_${mailIndex + 1}`, !raw),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.command("mails", async ctx => {
|
||||||
|
try {
|
||||||
|
const queryAddress = ctx?.message?.text.slice("/mails".length).trim();
|
||||||
|
return await queryMail(ctx, queryAddress, 0, false);
|
||||||
|
} catch (e) {
|
||||||
|
return await ctx.reply(`获取邮件失败: ${(e as Error).message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bot.on(callbackQuery("data"), async ctx => {
|
||||||
|
// Use ctx.callbackQuery.data
|
||||||
|
try {
|
||||||
|
const data = ctx.callbackQuery.data;
|
||||||
|
if (data && data.startsWith("mail_") && data.split("_").length === 3) {
|
||||||
|
const [_, queryAddress, mailIndex] = data.split("_");
|
||||||
|
await queryMail(ctx, queryAddress, parseInt(mailIndex), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(`获取邮件失败: ${(e as Error).message}`, e);
|
||||||
|
return await ctx.answerCbQuery(`获取邮件失败: ${(e as Error).message}`);
|
||||||
|
}
|
||||||
|
await ctx.answerCbQuery();
|
||||||
|
});
|
||||||
|
|
||||||
|
return bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function initTelegramBotCommands(bot: Telegraf) {
|
||||||
|
bot.telegram.sendMessage
|
||||||
|
await bot.telegram.setMyCommands(COMMANDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseMail = async (raw_mail: string) => {
|
||||||
|
if (!raw_mail) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsedEmail = await PostalMime.parse(raw_mail);
|
||||||
|
return {
|
||||||
|
isHtml: false,
|
||||||
|
mail: `From: ${parsedEmail.from ? `${parsedEmail.from.name}[${parsedEmail.from.address}]` : "无发件人"}\n`
|
||||||
|
+ `To: ${parsedEmail.to?.map(t => `${t.name}[${t.address}]`).join(" ")}\n`
|
||||||
|
+ `Subject: ${parsedEmail.subject}\n`
|
||||||
|
+ `Date: ${parsedEmail.date}\n`
|
||||||
|
+ `Content:\n${parsedEmail.text?.substring(0, 100) || "解析失败"}`
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
isHtml: false,
|
||||||
|
mail: `解析邮件失败: ${(e as Error).message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function sendMailToTelegram(c: Context, address: string, raw_mail: string) {
|
||||||
|
if (!c.env.TELEGRAM_BOT_TOKEN || !c.env.KV) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const userId = await c.env.KV.get(`${CONSTANTS.TG_KV_PREFIX}:${address}`);
|
||||||
|
if (!userId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { mail } = await parseMail(raw_mail);
|
||||||
|
if (!mail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bot = newTelegramBot(c, c.env.TELEGRAM_BOT_TOKEN);
|
||||||
|
await bot.telegram.sendMessage(userId, mail);
|
||||||
|
}
|
||||||
+15
-1
@@ -47,10 +47,24 @@ export const getBooleanValue = (value) => {
|
|||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
return value === "true";
|
return value === "true";
|
||||||
}
|
}
|
||||||
console.error("Invalid boolean value", value);
|
console.error(`Failed to parse boolean value: ${value}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getIntValue = (value, defaultValue = 0) => {
|
||||||
|
if (typeof value === "number") {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (typeof value === "string") {
|
||||||
|
try {
|
||||||
|
return parseInt(value);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to parse int value: ${value}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
export const getDomains = (c) => {
|
export const getDomains = (c) => {
|
||||||
if (!c.env.DOMAINS) {
|
if (!c.env.DOMAINS) {
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { api as userApi } from './user_api';
|
|||||||
import { api as adminApi } from './admin_api';
|
import { api as adminApi } from './admin_api';
|
||||||
import { api as apiV1 } from './deprecated';
|
import { api as apiV1 } from './deprecated';
|
||||||
import { api as apiSendMail } from './mails_api/send_mail_api'
|
import { api as apiSendMail } from './mails_api/send_mail_api'
|
||||||
|
import { api as telegramApi } from './telegram_api'
|
||||||
|
|
||||||
import { email } from './email';
|
import { email } from './email';
|
||||||
import { scheduled } from './scheduled';
|
import { scheduled } from './scheduled';
|
||||||
@@ -107,6 +108,7 @@ app.route('/', userApi)
|
|||||||
app.route('/', adminApi)
|
app.route('/', adminApi)
|
||||||
app.route('/', apiV1)
|
app.route('/', apiV1)
|
||||||
app.route('/', apiSendMail)
|
app.route('/', apiSendMail)
|
||||||
|
app.route('/', telegramApi)
|
||||||
|
|
||||||
app.get('/', async c => c.text("OK"))
|
app.get('/', async c => c.text("OK"))
|
||||||
app.get('/health_check', async c => c.text("OK"))
|
app.get('/health_check', async c => c.text("OK"))
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"lib": [
|
||||||
|
"ESNext"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"@cloudflare/workers-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -38,6 +38,8 @@ ENABLE_AUTO_REPLY = false
|
|||||||
# dkim config
|
# dkim config
|
||||||
# DKIM_SELECTOR = ""
|
# DKIM_SELECTOR = ""
|
||||||
# DKIM_PRIVATE_KEY = ""
|
# DKIM_PRIVATE_KEY = ""
|
||||||
|
# telegram bot
|
||||||
|
# TG_MAX_ACCOUNTS = 5
|
||||||
|
|
||||||
[[d1_databases]]
|
[[d1_databases]]
|
||||||
binding = "DB"
|
binding = "DB"
|
||||||
|
|||||||
Reference in New Issue
Block a user