JavaScript
Meteor

Meteorで作ったチャットアプリにbot機能をつける

More than 1 year has passed since last update.

仕様

  • 外部サイトをクローリングして更新情報を取得
  • twitterのつぶやきを取得
  • それらを取得してチャットアプリに投稿する
  • cronを使って自動でbot機能を実行

必要なもの

  • node
  • npm
  • cheerio(外部サイトをクローリングするパッケージ)
  • twitterAPIの「Consumer Key」「Consumer Secret」
  • percolate:synced-cron(meteorのcronパッケージ)

外部サイトをクローリング

requireを使うのでnpmをインストール

command
$ meteor npm install

外部サイトをスクレイピングするためのパッケージインストール

command
$ npm install cheerio

外部サイトを指定してクローリング

server
import { Meteor } from 'meteor/meteor';
const cheerio = require('cheerio');
Meteor.http.get('https://hogehoge.com', (err, result) => {
  $ = cheerio.load(result.content);
  const newsText = $('.hoge').eq(0).find('a').text();
  if (!newsText) return;
  Meteor.call('scrapingPost', newsText,);
});

Twitter Application Only Authentication

twitterのAPIを使って、指定したアカウントのツイートを取得

BEARER TOKENを取得

server
const request = require('request');
const consumerKey = 'CONSUMER_KEY';
const consumerSecret = 'CONSUMER_SECRET';
const encodeSecret = new Buffer(consumerKey + ':' + consumerSecret).toString('base64');

const options = {
  url: 'https://api.twitter.com/oauth2/token',
  headers: {
    'Authorization': 'Basic ' + encodeSecret,
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
  body: 'grant_type=client_credentials'
};

request.post(options, function(error, response, body) {
  console.log(body); // <<<< This is your BEARER TOKEN !!!
});

指定したアカウントのツイートを取得

server
const twitterBot = (url, userName) => {
  const twitterApi = 'https://api.twitter.com/1.1/search/tweets.json?q=from:' + userName; // 取得したツイッターアカウントを指定
  const bearerToken = 'BEARER TOKEN';

  const options = {
    method: 'GET',
    url: twitterApi,
    qs: {
      'screen_name': 'twitterapi'
    },
    json: true,
    headers: {
      'Authorization': 'Bearer ' + bearerToken
    },
  };

  request(options, (error, response, body) => {
    if (!body.statuses[0]) return;          // twitterのデータが取得できないときの対応
    const newsText = body.statuses[0].text; // 最新のツイートを取得
    if (!newsText) return;
    twitterBotPost(newsText);
  });
};

// “Meteor code must always run within a Fiber” errorの対応
const twitterBotPost = Meteor.bindEnvironment((newsText) => {
  if (Posts.findOne({ text: newsText })) return;
  Meteor.call('scrapingPost', newsText);
});

twitterBot('https://twitter.com/hogehoge', 'hogehoge');

“Meteor code must always run within a Fiber” error

参考サイトを元にtwitterBot機能をつけたら「“Meteor code must always run within a Fiber”」エラーが発生
その対応として下記を追加

sample
Meteor.bindEnvironment

cronで自動処理

指定した時間で自動で投稿するためのパッケージインストール

command
$ meteor add percolate:synced-cron
server
Meteor.startup(() => {
  SyncedCron.start();
});

SyncedCron.add({
  name: 'BOT Function',
  schedule: (parser) => {
    return parser.text('every 2 hours'); // cronする時間を指定
  },
  job: () => {
    botFnc(); // bot機能をまとめた関数を指定
  }
});

参考サイト