DyAxy / Crisp-Telegram-Bot

基于 Telegram Topic 的 Crisp 插件,以分栏显示聊天,再也不用担心回错人了。
MIT License
60 stars 25 forks source link

关于图片回复功能 #2

Closed aipeach closed 2 months ago

aipeach commented 5 months ago

Crisp其实非会员也有办法发送图片的,那就是利用图床在聊天框发送图片的Markdown格式代码,例如在聊天框发送![googlelogo](https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png),这样就能显示图片了。

dadaoerv commented 3 months ago

crisp不让注册啊。。。。

aipeach commented 2 months ago

一个cloudflare-worker脚本,需要搭配EasyImages2.0使用,给bot发送图片、贴纸、以文件发送图片,都能回复markdownImageUrl telegram-cloud-photo-size-5-6172232024761417559-y

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
  })

  async function handleRequest(request) {
    // Telegram Bot TOKEN
    const TELEGRAM_BOT_TOKEN = '114514:ABCDEFG'
    // EasyImage API调用地址
    const EASYIMAGES_API_URL = 'https://png.cm/api/index.php'
    // EasyImage API Token
    const EASYIMAGES_API_TOKEN = 'a55fcf15f638f0b971d5b5bd916c78ed'
    // 指定允许使用机器人的 Telegram 用户 ID
    const ALLOWED_USER_IDS = ['123456789', '987654321'] // 替换为实际的 Telegram 用户 ID

    try {
      const telegramUpdate = await request.json()
      const chatId = telegramUpdate.message.chat.id
      const fromId = telegramUpdate.message.from.id.toString()

      // 仅允许指定用户使用机器人
      if (!ALLOWED_USER_IDS.includes(fromId)) {
        return new Response('Unauthorized', { status: 403 })
      }

      if (telegramUpdate.message) {
        const handlers = {
          photo: handlePhoto,
          document: handleDocument,
          sticker: handleSticker
        }

        for (const type in handlers) {
          if (telegramUpdate.message[type]) {
            await handlers[type](telegramUpdate.message, TELEGRAM_BOT_TOKEN, EASYIMAGES_API_URL, EASYIMAGES_API_TOKEN, chatId)
            break
          }
        }
      }

      return new Response('OK', { status: 200 })
    } catch (error) {
      console.error('Error handling request:', error)
      return new Response('Internal Server Error', { status: 500 })
    }
  }

  async function handlePhoto(message, botToken, apiUrl, apiToken, chatId) {
    const fileId = message.photo.pop().file_id
    await handleImage(fileId, botToken, apiUrl, apiToken, chatId)
  }

  async function handleDocument(message, botToken, apiUrl, apiToken, chatId) {
    if (message.document.mime_type.startsWith('image/')) {
      const fileId = message.document.file_id
      await handleImage(fileId, botToken, apiUrl, apiToken, chatId)
    }
  }

  async function handleSticker(message, botToken, apiUrl, apiToken, chatId) {
    const fileId = message.sticker.file_id
    await handleImage(fileId, botToken, apiUrl, apiToken, chatId)
  }

  async function handleImage(fileId, botToken, apiUrl, apiToken, chatId) {
    try {
      const fileUrl = await getFileUrl(botToken, fileId)
      const imageUrl = await uploadImageToEasyImages(fileUrl, apiUrl, apiToken)
      const markdownImageUrl = `![Image](${imageUrl})`
      const replyText = `返回图片链接为\n\n\`\`\`Markdown\n${markdownImageUrl}\n\`\`\``
      await sendMessage(botToken, chatId, replyText)
    } catch (error) {
      console.error('Error handling image:', error)
      await sendMessage(botToken, chatId, '上传图片失败')
    }
  }

  async function getFileUrl(botToken, fileId) {
    const response = await fetch(`https://api.telegram.org/bot${botToken}/getFile?file_id=${fileId}`)
    const result = await response.json()
    const filePath = result.result.file_path
    return `https://api.telegram.org/file/bot${botToken}/${filePath}`
  }

  async function uploadImageToEasyImages(fileUrl, apiUrl, apiToken) {
    const imageResponse = await fetch(fileUrl)
    const imageData = await imageResponse.arrayBuffer()
    const imageBlob = new Blob([imageData], { type: 'image/jpeg' })

    const formData = new FormData()
    formData.append('image', imageBlob, 'image.jpg')
    formData.append('token', apiToken)

    const response = await fetch(apiUrl, {
      method: 'POST',
      body: formData
    })

    const result = await response.json()
    if (result.result === "success") {
      return result.url
    } else {
      throw new Error('Image upload failed')
    }
  }

  async function sendMessage(botToken, chatId, text) {
    await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        chat_id: chatId,
        text: text,
        parse_mode: 'Markdown'
      })
    })
  }