You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord邮件机器人ImportError:无法导入imap_host求助

问题:导入imap_host时出现ImportError错误

本人无编程经验,为社团Discord服务器开发一款会议时间管理的邮件机器人,基于GitHub仓库RichardHladik/MailBot fork修改。运行main.py时出现ImportError: cannot import name 'imap_host'错误,修改导入语句无效,附上报错信息、代码和配置文件,请求技术帮助。

报错信息

PS C:\Users\jp518\OneDrive\Documents\vscode> & C:/Users/jp518/AppData/Local/Programs/Python/Python36/python.exe c:/Users/jp518/OneDrive/Documents/vscode/main.py
Traceback (most recent call last):
  File "c:/Users/jp518/OneDrive/Documents/vscode/main.py", line 9, in <module>
    from config import (
ImportError: cannot import name 'imap_host'

main.py代码

# -*- coding: utf8 -*-
import os
import email
import email.policy
import discord
import asyncio
from aioimaplib import aioimaplib
from selectolax.parser import HTMLParser
from config import (
    imap_host,
    user,
    passwd,
    mail_channel_id,
    token,
)

intents = discord.Intents.default()
client = discord.Client(intents=intents)
imap_host = imap_host.split(":")


def get_text_selectolax(html):
    """
    parsing HTML from email and returning crucial parts as TEXT
    """
    tree = HTMLParser(html)
    if tree.body is None:
        return None
    for tag in tree.css("script"):
        tag.decompose()
    for tag in tree.css("style"):
        tag.decompose()
    text = tree.body.text(separator="\n")
    return text


def strip_ending(t, pattern):
    if t.endswith(pattern):
        t = t[: -len(pattern)]
    return t


def simple_format(msg):
    msg = msg.replace("\n>\n", "\n> \n")
    msg = strip_ending(msg, "\n>")
    return msg


async def chunkize(channel, msg):
    LIMIT = 2000
    for i in range(0, len(msg), LIMIT):
        await channel.send(msg[i : i + LIMIT])


async def idle_loop(host, port, user, password):
    """
    This will loop to get new emails and send them to "mail_channel_id"
    """
    imap_client = aioimaplib.IMAP4_SSL(host=host, port=port, timeout=30)
    await imap_client.wait_hello_from_server()
    await imap_client.login(user, password)
    await imap_client.select()
    await asyncio.sleep(5)

    while True:
        # only get emails which we haven't read
        mail_channel = client.get_channel(mail_channel_id)

        status, data = await imap_client.search("(UNSEEN)")
        data = [d.decode() for d in data]
        for i in data[0].split():
            print("Fetching msg {i}")
            typ, mail = await imap_client.fetch(str(i), "(RFC822)")
            mail_msg = email.message_from_bytes(mail[1], policy=email.policy.SMTP)
            mail_channel = client.get_channel(mail_channel_id)

            msg_header = (
                f"**From:** {mail_msg['from']}\n"
                f"**Subject:** {mail_msg['subject']}\n"
                f"**To:** {mail_msg['to']}\n"
                f"**Date:** {mail_msg['date']}"
            )

            msg_body = []
            for part in mail_msg.walk():
                if part.get_content_type() == "text/plain":
                    message = "\n".join(
                        part.get_payload(decode=True).decode().splitlines()
                    )

                    message = get_text_selectolax(message).strip("\n")
                    message = simple_format(message)
                    msg_body.append(message)

                if part.get_content_maintype() == "multipart":
                    continue

                if part.get("Content-Disposition") is None:
                    continue

            msg = msg_header + "\n\n" + "\n".join(msg_body)
            await chunkize(mail_channel, msg)

        idle = await imap_client.idle_start(timeout=60)
        print((await imap_client.wait_server_push()))
        imap_client.idle_done()
        await asyncio.wait_for(idle, 30)


@client.event
async def on_ready():
    print("We have logged in as {0.user}".format(client))


def on_error(event, *args, **kwargs):
    message, *_ = args
    print(message)
    os._exit(1)


async def main():
    async with client:
        client.loop.create_task(
            idle_loop(imap_host[0], int(imap_host[1]), user, passwd)
        )
        client.loop.set_exception_handler(on_error)
        await client.start(token)


asyncio.run(main())

config.py配置

imap_host = "imap.gmail.com:993"
user = "redacted@gmail.com"
passwd = "redacted"
mail_channel_id = redacted
token = "redacted"

解决方案

  • 检查文件位置:确保config.py和main.py在同一目录下,Python只会在当前运行目录和系统路径中查找模块,路径不对会导致无法导入。
  • 修复config.py语法错误:config.py里的mail_channel_id = redacted存在问题——如果redacted是数字(Discord频道ID是整数),直接写数字即可;如果是字符串形式,需要加引号。这行语法错误会导致整个config.py无法被Python正确加载,进而引发导入错误,这是最可能的原因。
  • 验证变量拼写:确认config.py里的变量名是imap_host,没有大小写错误或拼写失误。
  • 测试基础导入:写一个简单的测试脚本test.py,内容如下:
    from config import imap_host
    print(imap_host)
    
    运行该脚本,看是否能成功输出imap_host的值,逐步排查问题。

内容的提问来源于stack exchange,提问作者jason Prescott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:07:41