AWS と LINE を連携させてbotを作ってみよう・天気予報編

このブログは下記ブログの手順を終えていることを前提に進めていきます。
AWS と LINE を連携させてbotを作ってみよう・準備編
AWS と LINE を連携させてbotを作ってみよう・Lambda編

前回の記事でLINEからAWSを呼び出し、LINEへ返信するところまで作りました。
今回は、AWSから天気予報のサーバーへ通信し、その結果をLINEへ返す方法をお伝えします。

天気予報のサーバーは色々ありますが、今回は導入が簡単な
livedoor天気情報を使用します。

http://weather.livedoor.com/weather_hacks/webservice

前回、AWS Lambda を作成したので、それを変更していきます。

 

コードを入力する欄に次のソースコードを入力します。

'use strict';
const line = require('@line/bot-sdk');
const http = require('http');
var event;
var context;
var callback;
exports.handler = (_event, _context, _callback) => {
    event    = _event;
    context  = _context;
    callback = _callback;
    http.get('http://weather.livedoor.com/forecast/webservice/json/v1?city=130010', main)
    .on('error', (e) => {
        callback(null, {});
    });
};
let main = function(res) {
    let body = ”;
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
        body += chunk;
    });
    res.on('end', (res) => {
        var jBody = JSON.parse(body);
        const client = new line.Client({
            channelAccessToken: 'channelAccessToken'
        });
        const message = {
            type: 'text',
             text: jBody.description.text
        };
        client.replyMessage(event.events[0].replyToken, message)
        .then(() => {
            callback(null, {});
        })
        .catch((err) => {
            callback(null, {});
        });
    });
};

 

"保存"してLINEから実行してみましょう

 

 

 

 

なかなか天気予報らしくなってきました。

"http.get(‘http://weather.livedoor.com/forecast/webservice/json/v1?city=130010’, main)"
ここで天気予報のサーバーへ天気情報をくれるようリクエストしています。

JSON形式でレスポンスが返ってくるため、"var jBody = JSON.parse(body);"でパースして
必要な部分を抽出しています。

LINEのメッセージには最大2000文字という制限があるため、
全部の情報を返したい場合は、適宜、分割し
て"client.replyMessage(event.events[0].replyToken, message)"で
送信してください。

しかしこれでは東京の天気しか答えてくれないため、人によっては不便でしょう。
「東京」と発言した場合は「東京」の天気を、
「大阪」と発言した場合は「大阪」の天気を教えてくれるようにしてみましょう。

次のコードをLambdaに貼り付けてください

'use strict';
const line = require('@line/bot-sdk');
const http = require('http');
var event;
var context;
var callback;
exports.handler = (_event, _context, _callback) => {
    event    = _event;
    context  = _context;
    callback = _callback;
    if (!event.events[0].message.text) {
        callback(null, {});
    }
    var cityId = getCityId(event.events[0].message.text);
    if (!cityId) {
        callback(null, {});
    }
    http.get('http://weather.livedoor.com/forecast/webservice/json/v1?city=' + cityId, main)
    .on('error', (e) => {
        callback(null, {});
    });
};
let main = function(res) {
    let body = ";
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
        body += chunk;
    });
    res.on('end', (res) => {
        var jBody = JSON.parse(body);
        const client = new line.Client({
            channelAccessToken: 'channelAccessToken'
        });
        const message = {
            type: 'text',
             text: jBody.description.text
        };
        client.replyMessage(event.events[0].replyToken, message)
        .then(() => {
            callback(null, {});
        })
        .catch((err) => {
            callback(null, {});
        });
    });
};
let getCityId = function(title) {
    var titles = {
        "稚内":"011000",
        "旭川":"012010",
        "留萌":"012020",
        "網走":"013010",
        "北見":"013020",
        "紋別":"013030",
        "根室":"014010",
        "釧路":"014020",
        "帯広":"014030",
        "室蘭":"015010",
        "浦河":"015020",
        "札幌":"016010",
        "岩見沢":"016020",
        "倶知安":"016030",
        "函館":"017010",
        "江差":"017020",
        "青森":"020010",
        "むつ":"020020",
        "八戸":"020030",
        "盛岡":"030010",
        "宮古":"030020",
        "大船渡":"030030",
        "仙台":"040010",
        "白石":"040020",
        "秋田":"050010",
        "横手":"050020",
        "山形":"060010",
        "米沢":"060020",
        "酒田":"060030",
        "新庄":"060040",
        "福島":"070010",
        "小名浜":"070020",
        "若松":"070030",
        "水戸":"080010",
        "土浦":"080020",
        "宇都宮":"090010",
        "大田原":"090020",
        "前橋":"100010",
        "みなかみ":"100020",
        "さいたま":"110010",
        "熊谷":"110020",
        "秩父":"110030",
        "千葉":"120010",
        "銚子":"120020",
        "館山":"120030",
        "東京":"130010",
        "大島":"130020",
        "八丈島":"130030",
        "父島":"130040",
        "横浜":"140010",
        "小田原":"140020",
        "新潟":"150010",
        "長岡":"150020",
        "高田":"150030",
        "相川":"150040",
        "富山":"160010",
        "伏木":"160020",
        "金沢":"170010",
        "輪島":"170020",
        "福井":"180010",
        "敦賀":"180020",
        "甲府":"190010",
        "河口湖":"190020",
        "長野":"200010",
        "松本":"200020",
        "飯田":"200030",
        "岐阜":"210010",
        "高山":"210020",
        "静岡":"220010",
        "網代":"220020",
        "三島":"220030",
        "浜松":"220040",
        "名古屋":"230010",
        "豊橋":"230020",
        "津":"240010",
        "尾鷲":"240020",
        "大津":"250010",
        "彦根":"250020",
        "京都":"260010",
        "舞鶴":"260020",
        "大阪":"270000",
        "神戸":"280010",
        "豊岡":"280020",
        "奈良":"290010",
        "風屋":"290020",
        "和歌山":"300010",
        "潮岬":"300020",
        "鳥取":"310010",
        "米子":"310020",
        "松江":"320010",
        "浜田":"320020",
        "西郷":"320030",
        "岡山":"330010",
        "津山":"330020",
        "広島":"340010",
        "庄原":"340020",
        "下関":"350010",
        "山口":"350020",
        "柳井":"350030",
        "萩":"350040",
        "徳島":"360010",
        "日和佐":"360020",
        "高松":"370000",
        "松山":"380010",
        "新居浜":"380020",
        "宇和島":"380030",
        "高知":"390010",
        "室戸岬":"390020",
        "清水":"390030",
        "福岡":"400010",
        "八幡":"400020",
        "飯塚":"400030",
        "久留米":"400040",
        "佐賀":"410010",
        "伊万里":"410020",
        "長崎":"420010",
        "佐世保":"420020",
        "厳原":"420030",
        "福江":"420040",
        "熊本":"430010",
        "阿蘇乙姫":"430020",
        "牛深":"430030",
        "人吉":"430040",
        "大分":"440010",
        "中津":"440020",
        "日田":"440030",
        "佐伯":"440040",
        "宮崎":"450010",
        "延岡":"450020",
        "都城":"450030",
        "高千穂":"450040",
        "鹿児島":"460010",
        "鹿屋":"460020",
        "種子島":"460030",
        "名瀬":"460040",
        "那覇":"471010",
        "名護":"471020",
        "久米島":"471030",
        "南大東":"472000",
        "宮古島":"473000",
        "石垣島":"474010",
        "与那国島":"474020"
    };
    return titles[title];
};

 

先ほどと同じように保存し、LINEで発言してみましょう。

 

 

「大阪」の問いに対して、近畿の天気を返してくれました。

"var cityId = getCityId(event.events[0].message.text);"
このメソッドを挟むことによって動的に場所を変更するようにしました。
地名とIDのマッピングlivedoor 天気情報 のサイトにあります。
http://weather.livedoor.com/forecast/rss/primary_area.xml

ちなみに、「メッセージありがとうございます〜」の応答メッセージはLINE@の設定で消すことができます。

 

 

いかがでしたでしょうか。
まだまだ作り込みとしては甘いですが、LINEを通して色々な所から情報拾集できることは分かっていただけたと思います。

 

 

 

アプリケーション開発バナー