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

Python调用GitHub API提取Issue操作用户邮箱失败,求解决方案

解决GitHub API获取Issue用户邮箱返回null的问题

问题根源

GitHub API默认不会返回用户的公开邮箱,只有当用户在个人设置中开启了"公开我的电子邮件地址",且你的访问令牌拥有对应权限时,才能获取到邮箱信息。另外,PyGitHub的user.email属性仅返回用户的主要公开邮箱,若用户未设置公开,该字段直接返回None。

可行解决方法

1. 确保访问令牌拥有user:email权限

创建GitHub访问令牌时,必须在权限范围(scopes)中勾选user:email,否则无法请求用户的邮箱数据。

2. 使用get_emails()方法获取全量邮箱

PyGitHub的User对象提供了get_emails()方法,该方法会返回用户关联的所有邮箱(包括公开和私有,前提是令牌有权限)。你可以优先提取主邮箱,代码修改如下:

获取Issue创建者邮箱:

if issue.user:
    user = g.get_user(issue.user.login)
    emails = user.get_emails()
    if emails:
        # 优先取主邮箱,若无则取第一个邮箱
        opened_by_email = next((email['email'] for email in emails if email['primary']), emails[0]['email'])
    else:
        opened_by_email = None

获取Issue关闭者邮箱:

closer_mail = "not closed"
if issue.closed_by:
    closer_user = g.get_user(issue.closed_by.login)
    closer_emails = closer_user.get_emails()
    if closer_emails:
        closer_mail = next((email['email'] for email in closer_emails if email['primary']), closer_emails[0]['email'])
    else:
        closer_mail = None

3. 处理用户未公开邮箱的情况

即便权限配置正确,部分用户可能未公开任何邮箱,此时只能返回None或自定义提示(比如"邮箱未公开"),这属于用户隐私设置,无法强制获取。

修改后的完整代码

def extract_issues(repo_url, access_token):
    try:
        g = Github(access_token)

        # 提取仓库用户名和名称
        repo_url_parts = repo_url.strip('/').split('/')
        username, repo_name = repo_url_parts[-2:]

        repo = g.get_repo(f"{username}/{repo_name}")

        issues_data = []
        for issue in repo.get_issues(state='all'):
            issue_comments = issue.get_comments()

            opened_by = issue.user.login if issue.user else None
            opened_by_email = None
            if issue.user:
                user = g.get_user(issue.user.login)
                emails = user.get_emails()
                if emails:
                    opened_by_email = next((email['email'] for email in emails if email['primary']), emails[0]['email'])

            # 处理关闭者邮箱
            closed_by = issue.closed_by.login if issue.closed_by else None
            closer_mail = "not closed"
            if issue.closed_by:
                closer_user = g.get_user(issue.closed_by.login)
                closer_emails = closer_user.get_emails()
                if closer_emails:
                    closer_mail = next((email['email'] for email in closer_emails if email['primary']), closer_emails[0]['email'])
                else:
                    closer_mail = None

            issue_data = {
                'id': issue.number,
                'title': issue.title,
                'description': issue.body,
                'state': issue.state,
                'created_at': issue.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                'closed_at': issue.closed_at.strftime('%Y-%m-%d %H:%M:%S') if issue.closed_at else None,
                'closed_by': closed_by,
                'closer_mail': closer_mail,
                'opened_by': opened_by,
                'opener_mail': opened_by_email,
                'comments': [{'author': comment.user.login,
                              'comment_date': comment.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                              'comment_text': comment.body} for comment in issue_comments]
            }
            issues_data.append(issue_data)

        return issues_data
    except Exception as e:
        print(f"An error occurred: {str(e)}")
        return None

内容的提问来源于stack exchange,提问作者Tugce Ozgirgin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:56:18