本文同步刊載於 Clarence 部落格:[LINE bot 好好玩 30 天玩轉 LINE API] 第 18 天:語句分析器
前兩章說完了怎麼寫爬蟲與怎麼用 Flex Message 做出美麗的 UI,今天就來讓它們和再一起吧!
我們之前範例的 Event handle 是用 message.text 做一個處理,這次我們希望指令可以是
如此類型的指令,先來用一個正規表示做 Test
/^鐵人賽/.test(message.text)
如上可以知道使用者的指令是 鐵人賽
開頭
^
的意思是開頭
下一步我們來抓取後面的數字
const execString = /^鐵人賽(\d\d)/.exec(message.text);
(\d)
是數字的意思
如此我們就可以把它抓下來了!
使用 execString[1]
,可以取得後面的數字
好了,現在有了指令也有數字了,我們來組合前面的 Parse
async function ithome2020api(team) {
const teams = {};
const url = `https://ithelp.ithome.com.tw/2020ironman/signup/team/${team}`;
const options = {
uri: url,
transform: function (body) {
return cheerio.load(body);
}
};
const $ = await rp(options);
ithome2020Parse($, teams);
return { teams };
}
先做出一個 function 來處理 ithome request 的內容,把收到的 response 丟給 cheerio 處理,之後把 cheerio 做出來的 $
丟給 ithome2020Parse
處理
function ithome2020Parse($, teams) {
const teamDashboardNum = $('span', '.team-dashboard__num');
if (Object.getOwnPropertyNames(teams).length === 0) {
teams.title = $('.team-detail__title').text().trim(); // 團隊隊名
teams.img = $('.team-detail__img').find('img').attr('src'); // 團隊圖片
teams.desc = $('.team-detail__desc').text().trim(); // 團隊介紹
teams.cumulativeArticle = $(teamDashboardNum[0]).text(); //累計文章
teams.bar = $('.progress-bar').attr('aria-valuenow'); // 團隊進度
teams.numberTeams = $(teamDashboardNum[1]).text(); // 團隊人數
teams.memberTeams = parseInt($(teamDashboardNum[1]).text(), 10);
teams.teamStatus = $('.team-dashboard__text').text();
teams.challengeProgress = $('.team-dashboard__day').text().trim(); // 挑戰進度
const numberChallengeProgress = /\d/g.exec($('.team-dashboard__day').text().trim());
teams.numberChallengeProgress = numberChallengeProgress[0]; // 挑戰進度
}
}
這邊開始把資料 object 做處理後回傳,如果不清楚可以回去看前面的鐵人賽
把處理完的資料丟回去,建立 Flex 顯示我們要的內容
return client.replyMessage(replyToken, {
type: 'flex',
altText: `鐵人賽組別:${res.teams.title}`,
contents: {
type: 'bubble',
header: {
type: 'box',
layout: 'vertical',
contents: [
{
type: 'box',
layout: 'horizontal',
contents: [
{
type: 'image',
url: 'https://ithelp.ithome.com.tw/images/ironman/11th/event/kv_event/kv-bg-addfly.png',
aspectMode: 'cover',
aspectRatio: '2:1',
flex: 1,
size: 'full'
}
]
}
],
paddingAll: '0px'
},
body: {
type: 'box',
layout: 'vertical',
contents: [
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'text',
contents: [],
size: 'xl',
wrap: true,
text: res.teams.title,
color: '#ffffff',
weight: 'bold'
},
{
type: 'text',
text: res.teams.desc,
color: '#ffffffcc',
size: 'sm',
wrap: true
}
],
spacing: 'sm'
},
{
type: 'text',
text: `${res.teams.bar}%`,
color: '#ffffffde',
margin: 'lg',
size: 'xs'
},
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'filler'
}
],
width: `${res.teams.bar}%`,
height: '6px',
backgroundColor: '#ffffff5A'
}
]
},
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'box',
layout: 'vertical',
contents: [
{
type: 'text',
contents: [],
size: 'sm',
wrap: true,
margin: 'lg',
color: '#ffffffde',
text: `累計文章:${res.teams.cumulativeArticle}`
},
{
type: 'text',
contents: [],
size: 'sm',
wrap: true,
margin: 'lg',
color: '#ffffffde',
text: `團隊人數:${res.teams.numberTeams}人`
},
{
type: 'text',
contents: [],
size: 'sm',
wrap: true,
margin: 'lg',
color: '#ffffffde',
text: `團隊狀態:${res.teams.teamStatus}`
}
]
}
],
paddingAll: '13px',
backgroundColor: '#ffffff1A',
cornerRadius: '2px',
margin: 'xl'
}
]
}
],
paddingAll: '20px',
backgroundColor: '#464F69'
}
}
});
如此我們的 Command 就完成拉!
CSScoke - 金魚都能懂的這個網頁畫面怎麼切 - 金魚都能懂了你還怕學不會嗎
King Tzeng - IoT沒那麼難!新手用JavaScript入門做自己的玩具~
Hina Hina - 陣列大亂鬥
阿斬 - Python 程式交易 30 天新手入門
塔塔默 - 用Python開發的網頁不能放到Github上?Lektor說可以!!
Vita Ora - 好 Js 不學嗎 !? JavaScript 入門中的入門。