LoginSignup
0

More than 1 year has passed since last update.

Organization

IFTTT有料化したので前回作ったなんちゃってポケモンGOをLINE Beaconで作ってみた

前回の記事では、IFTTTと連携しGPSでポケモン情報をLINEにpushしました。

IFTTT有料化(無料にきつい制限化)に伴い、これを無料でできるよう自作したビーコンに近づいたらポケモンとエンカウントしてみようと思います。

今回はobnizをビーコンにし、LINE Beaconを利用しました。

開発環境

  • obniz Board
  • Node.js v14.5.0
  • express v4.17.1
  • line/bot-sdk v7.0.0
  • axios v0.19.2

ポケモンのAPIとしてこちらを利用しました。
利用したときはv2でした。

手順概要、目次

  1. LINE BOTなどの作成は前回の記事まで進んでいるとします
    1. LINE BeaconのハードウェアID発行
    2. ソースコード
  2. obniz
    1. バージョンアップ
    2. ソースコード
  3. obnizにスマートフォンを持って近づく

LINE BOTの作成

前回同様、こちらの通りに作りました!

「1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest」
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d

今回は前回の記事のBOTを引き続いて編集していきました

LINE Beaconの設定

こちらの記事を参考に
ここから、連携したいBOTを選んで、

Image from Gyazo

ハードウェアIDを発行

Image from Gyazo

BOT側ソースコード

'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const axios = require('axios');

const config = {
  channelSecret: 'チャンネルシークレット',
  channelAccessToken:'アクセストークン',
};

const app = express();

const client = new line.Client(config);

async function getRandomPoke() {
  const res = await axios.get(
    'https://pokeapi.co/api/v2/pokemon/' + Math.floor(Math.random() * 807)
  );
  // 日本語情報をデータに入れ込む
  const species = await axios.get(res.data.species.url);
  species.data.names.forEach((e) => {
    if (e.language.name == 'ja') species.data.ja_name = e.name;
  });
  species.data.flavor_text_entries.forEach((e) => {
    if (e.language.name == 'ja') species.data.ja_flavor_text = e.flavor_text;
  });
  res.data.species = species.data;

  return res.data;
}

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/ifttt', async (req, res) => {
  // 今回はここは省略
  // IFTTTでGPS連携の場合は https://qiita.com/drafts/bdfee3416792737fd48d こちらを参考に
});

// 以下replay message用
app.post('/webhook', line.middleware(config), (req, res) => {
  console.log(req.body.events);

  if (
    req.body.events[0].replyToken === '00000000000000000000000000000000' &&
    req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'
  ) {
    res.send('Hello LINE BOT!(POST)');
    console.log('疎通確認用');
    return;
  }

  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});
async function handleEvent(event) {
  if (event.type === 'message' && event.message.type === 'text') { // オウムがえし用
    const echo = { type: 'text', text: event.message.text };
    console.log(echo);
    return client.replyMessage(event.replyToken, echo);
  } else if (event.type === 'beacon' && event.beacon) { // beacon用
    console.log(`beacon device(${event.beacon.hwid})から${event.beacon.dm}が届いたよ`)
    const poke = await getRandomPoke();
    const toUri = 'https://yakkun.com/swsh/zukan/n' + poke.id;
    return client.replyMessage(event.replyToken, {
      type: 'template',
      altText: 'This is a buttons template',
      template: {
        type: 'buttons',
        thumbnailImageUrl: poke.sprites.front_default,
        imageAspectRatio: 'rectangle',
        imageSize: 'cover',
        imageBackgroundColor: '#FFFFFF',
        title: poke.species.ja_name + ' ' + poke.name,
        text: poke.species.ja_flavor_text,
        actions: [
          {
            type: 'uri',
            label: '捕まえる',
            uri: toUri,
          },
        ],
      },
    });
  }
  return Promise.resolve(null);
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

これを自分は、ngrokでトンネリングさせ、LINE BOTとして動作させておきました

obnizについて

Image from Gyazo

こちらから購入できます。

ライセンスだけ買って、ESP系のマイコンにosインストールすることもできます!すごい。

本来ならBluetoothとバッティングするWi-Fiを常時使用するobnizではないもののほうがいいと思うのですが、何か作ろうとしたときに腰が軽くできるobnizはやはり素晴らしいと改めて思いました。

obnizのバージョンアップ

Bluetoothを使う場合はobnizのOSが古いとできませんでしたので、バージョンアップします

こちらのデバイス一覧から

Image from Gyazo

最新を選んでインストールします

Image from Gyazo

ビーコン側ソースコード

こちらの記事からコードをもらいつつ、Node.js用に書き換えました

const Obniz = require("obniz");
const obniz = new Obniz("XXXX-XXXX");
obniz.onconnect = async function () {

  let adv = [];
  const UUID_FOR_LINECORP = [0x6F, 0xFE];
  const deviceMessage = [01, 02, 10];  //サーバーに送るメッセージ 1~13byte
  const hardwareId = [0x01, 0x43, 0x6f, 0xb5, 0x48]; //払い出されたID

  // flag
  adv = adv.concat([0x02, 0x01, 0x06]);  //LE General Discoverable Mode & BR/EDR Not Supported

  //16bit uuid
  adv = adv.concat([0x03, 0x03]);
  adv = adv.concat(UUID_FOR_LINECORP);

  //simple beacon
  adv = adv.concat([1 + 9 + deviceMessage.length, 0x16]);
  adv = adv.concat(UUID_FOR_LINECORP);
  adv = adv.concat([0x02]);
  adv = adv.concat(hardwareId);
  adv = adv.concat([0x7F]);
  adv = adv.concat(deviceMessage);


  await obniz.ble.initWait()
  obniz.ble.advertisement.setAdvDataRaw(adv);
  obniz.ble.advertisement.start();
}

obnizにスマートフォンを持って近づく

Image from Gyazo

見た目同じ!でもできた!!

このobnizや他のビーコンデバイスを草むらなどに仕掛けておくと楽しそう!!!!

今回はやってないですが、ビーコンからのデバイスIDの情報や、その他センサー値をもらってBOT側で全部ランダムにしているところを偏らせたりできたらもっと楽しいと思った。

ただ、LINEのほうで、ハードは10個までの登録らしいです…
151個のハードとかは無理だよねぇ…

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0