From 84ca784a0bf2464071b55e8ee89f507ae94bf0c7 Mon Sep 17 00:00:00 2001 From: aipeach <44671411+aipeach@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:06:54 +0800 Subject: [PATCH 1/2] add easyimages --- bot.py | 89 ++++++++++++++++++++++++++++++++++++++ config.yml.example | 3 ++ docker-compose.yml.example | 2 + docker-entrypoint.sh | 3 ++ 4 files changed, 97 insertions(+) diff --git a/bot.py b/bot.py index 92a0bd7..f9d3180 100644 --- a/bot.py +++ b/bot.py @@ -2,6 +2,7 @@ import os import yaml import logging +import requests from openai import OpenAI from crisp_api import Crisp @@ -80,6 +81,93 @@ async def onReply(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: ) return +# EasyImages Config +EASYIMAGES_API_URL = config.get('easyimages', {}).get('apiUrl', '') +EASYIMAGES_API_TOKEN = config.get('easyimages', {}).get('apiToken', '') + +async def handleImage(update: Update, context: ContextTypes.DEFAULT_TYPE): + msg = update.effective_message + + if msg.photo: + file_id = msg.photo[-1].file_id + elif msg.document and msg.document.mime_type.startswith('image/'): + file_id = msg.document.file_id + else: + await msg.reply_text("请发送图片文件。") + return + + try: + # 获取文件下载 URL + file = await context.bot.get_file(file_id) + file_url = file.file_path + + # 上传图片到 EasyImages + uploaded_url = upload_image_to_easyimages(file_url) + + # 生成 Markdown 格式的链接 + markdown_link = f"![Image]({uploaded_url})" + + # 查找对应的 Crisp 会话 ID + session_id = get_target_session_id(context, msg.message_thread_id) + if session_id: + # 将 Markdown 链接推送给客户 + send_markdown_to_client(session_id, markdown_link) + await msg.reply_text("图片已成功发送给客户!") + else: + await msg.reply_text("未找到对应的 Crisp 会话,无法发送给客户。") + + except Exception as e: + await msg.reply_text("图片上传失败,请稍后重试。") + logging.error(f"图片上传错误: {e}") + +def upload_image_to_easyimages(file_url): + try: + response = requests.get(file_url, stream=True) + response.raise_for_status() + + files = { + 'image': ('image.jpg', response.raw, 'image/jpeg'), + 'token': (None, EASYIMAGES_API_TOKEN) + } + res = requests.post(EASYIMAGES_API_URL, files=files) + res_data = res.json() + + if res_data.get("result") == "success": + return res_data["url"] + else: + raise Exception(f"Image upload failed: {res_data}") + except Exception as e: + logging.error(f"Error uploading image: {e}") + raise + +def get_target_session_id(context, thread_id): + for session_id, session_data in context.bot_data.items(): + if session_data.get('topicId') == thread_id: + return session_id + return None + +def send_markdown_to_client(session_id, markdown_link): + try: + # 将 Markdown 图片链接作为纯文本发送 + query = { + "type": "text", + "content": markdown_link, # 将图片链接当做普通文本 + "from": "operator", + "origin": "chat", + "user": { + "nickname": "人工客服", + "avatar": "https://bpic.51yuansu.com/pic3/cover/03/47/92/65e3b3b1eb909_800.jpg" + } + } + client.website.send_message_in_conversation( + config['crisp']['website'], + session_id, + query + ) + logging.info(f"图片链接已成功发送至 Crisp 会话 {session_id}") + except Exception as e: + logging.error(f"发送图片链接到 Crisp 失败: {e}") + raise async def onChange(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """Parses the CallbackQuery and updates the message text.""" @@ -104,6 +192,7 @@ def main(): if os.getenv('RUNNER_NAME') is not None: return app.add_handler(MessageHandler(filters.TEXT, onReply)) + app.add_handler(MessageHandler(filters.PHOTO | filters.Document.IMAGE, handleImage)) app.add_handler(CallbackQueryHandler(onChange)) app.job_queue.run_once(handler.exec,5,name='RTM') app.run_polling(drop_pending_updates=True) diff --git a/config.yml.example b/config.yml.example index 2e02562..06c326e 100644 --- a/config.yml.example +++ b/config.yml.example @@ -10,6 +10,9 @@ crisp: key: # 网站 ID website: +easyimages: + apiUrl: "http://127.0.0.1/api/index.php" + apiToken: "token" autoreply: # 自动关键词回复,你可以复制成多行,每个关键词用 `|` 隔开即可,在 `:` 后输入自动回复内容 "在吗|你好": "欢迎使用客服系统,请等待客服回复你~" diff --git a/docker-compose.yml.example b/docker-compose.yml.example index 1e9f945..f9c22c2 100644 --- a/docker-compose.yml.example +++ b/docker-compose.yml.example @@ -8,6 +8,8 @@ services: TZ: Asia/Shanghai BOT_TOKEN: 12345:abcdefghijklm BOT_GROUPID: -123456 + EasyImages_apiUrl: "http://127.0.0.1/api/index.php" + EasyImages_apiToken: "token" CRISP_ID: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa CRISP_KEY: aaaaaaaaaaaaaa11111111aaaaaaaaaaaaaaaaaa CRISP_WEBSITE: bbbbbbbb-bbbbb-bbbb-bbbb-bbbbbbbbbbbb diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 01976d1..ec5aef1 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -22,6 +22,9 @@ crisp: id: ${CRISP_ID} key: ${CRISP_KEY} website: ${CRISP_WEBSITE} +easyimages: + apiUrl: ${EasyImages_apiUrl} + apiToken: ${EasyImages_apiToken} autoreply: ${AUTOREPLY} openai: From 6aeec08d280a0a003efdb97a1baa0bb7ccbcf92d Mon Sep 17 00:00:00 2001 From: aipeach <44671411+aipeach@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:22:38 +0800 Subject: [PATCH 2/2] Update docker_build.yml --- .github/workflows/docker_build.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 307032f..a751f18 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -1,6 +1,7 @@ name: Docker Image Build on: + workflow_dispatch: push: branches: - "master" @@ -32,13 +33,13 @@ jobs: - run: docker buildx inspect --bootstrap - name: Build image and push(py3.9) - run: docker buildx build -t moefaq/crisp-telegram-bot:latest -t moefaq/crisp-telegram-bot:py3.9 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.9/Dockerfile . + run: docker buildx build -t ${{ secrets.FAQ_DOCKERHUB_USERNAME }}/crisp-telegram-bot:latest -t ${{ secrets.FAQ_DOCKERHUB_USERNAME }}/crisp-telegram-bot:py3.9 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.9/Dockerfile . - name: Build image and push(py3.10) - run: docker buildx build -t moefaq/crisp-telegram-bot:py3.10 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.10/Dockerfile . + run: docker buildx build -t ${{ secrets.FAQ_DOCKERHUB_USERNAME }}/crisp-telegram-bot:py3.10 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.10/Dockerfile . - name: Build image and push(py3.11) - run: docker buildx build -t moefaq/crisp-telegram-bot:py3.11 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.11/Dockerfile . + run: docker buildx build -t ${{ secrets.FAQ_DOCKERHUB_USERNAME }}/crisp-telegram-bot:py3.11 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.11/Dockerfile . - name: Build image and push(py3.12) - run: docker buildx build -t moefaq/crisp-telegram-bot:py3.12 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.12/Dockerfile . + run: docker buildx build -t ${{ secrets.FAQ_DOCKERHUB_USERNAME }}/crisp-telegram-bot:py3.12 --platform linux/amd64,linux/arm64 --progress plain --push -f dockerfiles/py3.12/Dockerfile .