[DC機器人] 維基百科API

維基百科這類的網站都是由一個有2.6K星星的開源專案 MediaWiki 所建置而成,我對API文件的第一印象就是:很亂。

可能是功能太多的緣故,單單就參數的部分滑鼠就要滾九圈才看得完。

維基百科的API文件雖然有中文頁面,但實際上只翻譯了前面一點點。網路上的跟維基API有關的中文資料相較於金流、天氣等服務,更是少得可憐。也因為如此,我只好花30分鐘乖乖讀官方文件了。

除了最原始的API外,他還有 REST API ,但囿於原本的 DC chatbot 框架,我選擇了較為熟悉的原始API。

這次會用到的API是這個:

`https://zh.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=${keyword}`

替換子域名 zh -> en 就會切換至英文頁面。

如果說今天我把${keyword}改成柴犬的話,就會request這個JSON頁面。

我們要的就是他respond的snippet,然而,仔細一看,會發現他給我們的資料是html格式,因此,我們還要寫個函式去除Html標籤。

function stripHTML(input) {
    var output = '';
    if(typeof(input)=='string'){
        var output = input.replace(/(<([^>]+)>)/ig,"");
    }
    return output;
}

進到主程式的部分:

新增了兩個別名"enwiki"、"zhwiki"來處理不同語言的搜尋結果,而無添加的"wiki"則是中文搜尋的結果。

之後建立一個 embed message 來回覆搜尋結果,並在程式正式開始先做簡單的邊緣測試。

在這裡使用了 request 套件,因為會發送請求,所以放了兩個try-catch做例外處理。我發現 request 的 URL 不能放中文的字串,所以還要 encode 成 URL。

接下來就依照返回的JSON數據,填入 embed message 裡。

比較重要的坑是貌似javascript的變數是類似c的傳址,所以,請求外面即使是全域變數也不能存裡面數據。(這我不確定,只是一種感覺而已)。

cmds/wiki.js
const request = require('request')

module.exports={
    name: 'wiki',
    description: 'getting wikipedia search result',
    aliases: ['enwiki', 'zhwiki',],
    cooldown: 0,
    async execute(msg, args, cmd, client, Discord){
        const Embed = new Discord.MessageEmbed()
            .setColor('#5B00AE')
            .setTimestamp()
	        .setFooter('Wikipedia');

        if(!args){
            msg.channel.send('請輸入欲搜尋的關鍵字');
            return;
        }
        if(cmd === 'wiki' || cmd === 'zhwiki') var url = `https://zh.wikipedia.org/`;
        else if(cmd === 'enwiki') var url = `https://en.wikipedia.org/`;
        try{
            request({
                url: encodeURI(url+`w/api.php?action=query&format=json&list=search&utf8=1&srsearch=${args}`),
                json: true
            }, (err, res, req) => {
                try{
                    Embed.addFields({
                        name: req.query.search[0].title,
                        value: stripHTML(req.query.search[0].snippet)
                    })
                        .setTitle('查看更多搜尋結果')
                        .setURL(url+`w/index.php?search=${args}&ns0=1`);
                    msg.channel.send(Embed);
                }catch(e){
                    console.log(`Error:${e}`);
                    Embed.setTitle('查看線上搜尋結果')
                        .setURL(url+`w/index.php?search=${args}&ns0=1`)
                        .setDescription('搜尋失敗');
                }
            });
        }catch(e){
            console.log(`Error${e}`);
            msg.channel.send('伺服器連線失敗,請稍後再試,謝謝');
        }
    }
}

最後看一下成果:

後記

這個小翠兒chatbot是我本地測試用的,跟微笑柴柴的prefix(@)不同,是#。

因為微笑柴柴因為已經部署了,所以還沒更新這個新功能,會等以後有其他更新時一併處理。

附錄

維基百科API文件

 

按讚

發佈留言

%d 位部落客按了讚: