近来看到很多站点的评论都可以在用户输入 QQ 邮箱时自动获取其 QQ 头像来替代默认的 Gravatar 头像,这样方便了很多没有时间自定义 Gravatar 头像的人,我觉得很有意义。逛 Typecho 官方社区机缘巧合下看到博客 侥のblog 给出了这样的代码,这篇博文自《Typecho评论调用QQ头像 - 宸轩云》 。现修改后收藏于此。


2020.3.19 修改了第一种方法的接口使调用的 QQ 头像地址不再暴露用户 QQ 号码,请诸位放心使用 QQ 快速评论。
使用新的无隐私接口(我自己给接口起的名 )需要服务器支持 curl 拓展,代码中使用了 curl 相关方法处理 API 接口的数据。

操作

修改 Typecho 目录下 /var/Typecho 文件夹下 common.php 文件,932 行,关于获取 Gravatar 头像的代码:

public static function gravatarUrl($mail, $size, $rating, $default, $isSecure = false)
    {
        if (defined('__TYPECHO_GRAVATAR_PREFIX__')) {
            $url = __TYPECHO_GRAVATAR_PREFIX__;
        } else {
            $url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
            $url .= '/avatar/';
        }

        if (!empty($mail)) {
            $url .= md5(strtolower(trim($mail)));
        }

        $url .= '?s=' . $size;
        $url .= '&r=' . $rating;
        $url .= '&d=' . $default;

        return $url;
    }

修改为:

public static function gravatarUrl($mail, $size, $rating, $default, $isSecure = false)
    {
            $reg = "/^\d{5,10}@[qQ][Qq]\.(com)$/";
            if (preg_match($reg, $mail)) {
                // $img    = explode("@", $mail);
                // $url = "//q2.qlogo.cn/headimg_dl?dst_uin={$img[0]}&spec=100";

                $object = explode("@", $mail)[0];
                $apiurl = "https://ptlogin2.qq.com/getface?appid=1006102&uin=" . $object . "&imgtype=3";
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $apiurl);
                curl_setopt($ch, CURLOPT_HEADER, 0);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_TIMEOUT, 10);
                $data = curl_exec($ch);
                curl_close($ch);
                $avatar = $data;
                $pattern2 = '/pt.setHeader\((.*)\)/is';
                preg_match($pattern2, $avatar, $result2);
                $url = json_decode($result2[1], true)["$object"];
            } else {
                if (defined('__TYPECHO_GRAVATAR_PREFIX__')) {
                    $url = __TYPECHO_GRAVATAR_PREFIX__;
                } else {
                    $url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
                    $url .= '/avatar/';
                }
                if (!empty($mail)) {
                    $url .= md5(strtolower(trim($mail)));
                }
                $url .= '?s=' . $size;
                $url .= '&r=' . $rating;
                $url .= '&d=' . $default;
            }
            return $url;
    }

效果

  • 输入 QQ 邮箱,调用 QQ 头像
  • 输入普通邮箱,调用 Gravatar 头像

修改后,原版获取头像地址会暴露 QQ 号码的问题解决,参考教程为《GravatarServer of typecho - 权那他》。将原来的接口 //q2.qlogo.cn/headimg_dl?dst_uin=QQ_NUMBER&spec=100 地址替换为 //ptlogin2.qq.com/getface?appid=1006102&uin="QQ_NUMBER"&imgtype=3

这个接口会将 QQ 号码加密处理后返回头像地址,改变 imgtype 参数为 1 2 3 4 分别可以获取 40×40 40×40 100×100 140×140 大小的头像信息。注意这里直接访问 API 地址获取的不是原来那种图片,而是包含图片地址的字符串。代码中使用 curl 请求 API 地址然后处理之后输出图片地址。

优先级总是优先调用 QQ 头像,请自行修改以实现需要的优先级。

后续

看到网友建议,直接修改 Typecho 源码并不是一个很好的方法,不过我认为无所谓,Typecho 下一次大版本更新估计也是下辈子的事了。这里还有其他几种方法简单写写,具体还请参考给出的相关教程。

  • 添加主题函数实现
  • 将评论区“邮箱”项定义为“QQ”,后台处理使提交数据为“ $QQ @qq.com”并获取QQ头像

法② 添加主题函数

本来还在在想找 Handsome 主题里现成的函数...哎...这么 Ctrl + CCtrl + V 两把梭就完事儿了。结果找了十年,也没发现这个函数究竟在哪。怪我太菜了,又没有视力。

好吧,现成的找不到的话那就自己梭呗,反正上面原理全都写出来了的。尝试在主题 function.php 结尾添加上面代码 咳咳,此处超出我的能力范围。搜索了一番之后找到了参考文章《Typecho 模板实现 QQ 邮箱识别,并生成头像地址 - 规则之树》。

思路是在 function.php 中添加函数。通过 isqq() 方法获取邮箱,判断是否为 QQ 邮箱,是则截取邮箱的 qq 号部分对接 qlogo API ,不是则 MD5 加密该邮箱对接 Gravatar API 。

/** 对邮箱类型判定,并调用QQ头像的实现 */
function isqq($email) {
    if($email) {
        if(strpos($email,"@qq.com") !== false) {
            $email = str_replace('@qq.com','',$email);
            echo "//q1.qlogo.cn/g?b=qq&nk=".$email."&";
        } else {
            $email = md5($email);
            echo "//cdn.v2ex.com/gravatar/".$email."?";
        }
    } else {
        echo "//cdn.v2ex.com/gravatar/null?";
    }
}

使用时根据不同模板有不同的调用代码,下面代码输出为头像 URL 地址。(一年多后我再次修改此文章的时候,已经不记得有没有亲自尝试这个方法了,请先自行测试)

<!-- 文章列表及内容页作者头像 -->
<?php isqq($this->author->mail); ?>s=100

<!-- 评论列表用户头像 -->
<?php isqq($comments->mail); ?>s=100

<!-- 当前登录用户头像 -->
<?php isqq($this->user->mail); ?>s=100

法③ 邮箱改 QQ

这个方法是 2018 年 12 月逛 Typecho 官方社区时在秀博客主题的分区发现的,发现有个站长直接将填写邮箱的地方用 QQ 替换了,但是,众所周知,Typecho 后台对评论区提交的数据处理时肯定会将留言者邮箱记录在数据库中的。所以我想知道站长对这个 input 框进行了怎样的处理呢?于是我看到了站内的两篇文章《Typecho 自带评论功能 Gravatar 头像改 QQ 头像》《Typecho 自带评论改 QQ 头像 第二波》。请参考原帖,不再赘述。

 

如果以上全都失败了还可以看一下这个《获取 QQ 头像地址,并且不暴露 QQ 号 - Typecho 爱好者博客

(溜了溜了…