[LINE bot 好好玩 30 天玩轉 LINE API] 第 18 天:語句分析器

2020 11th 鐵人賽 LINE

本文同步刊載於 iT 邦幫忙第11屆鐵人賽:[LINE bot 好好玩 30 天玩轉 LINE API] 第 18 天:語句分析器

前言:

前兩章說完了怎麼寫爬蟲與怎麼用 Flex Message 做出美麗的 UI,今天就來讓它們和再一起吧!

Event 處理

我們之前範例的 Event handle 是用 message.text 做一個處理,這次我們希望指令可以是

  • 鐵人賽01
  • 鐵人賽02
  • 鐵人賽82

如此類型的指令,先來用一個正規表示做 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 就完成拉!