當(dāng)前位置:首頁 > IT技術(shù) > 微信平臺(tái) > 正文

微信公眾號(hào)菜單點(diǎn)擊發(fā)送實(shí)況天氣預(yù)報(bào)
2021-07-26 11:35:03

本文介紹如何為公眾號(hào)添加一個(gè)菜單點(diǎn)擊后給用戶發(fā)送天氣預(yù)報(bào)的功能????

上一次介紹了如何為公眾號(hào)添加關(guān)注自動(dòng)回復(fù)的功能,這次我們來擴(kuò)展一個(gè)比較實(shí)用的功能---實(shí)況天氣查詢

程序思路

  • 用戶進(jìn)入公眾號(hào)會(huì)話,上傳經(jīng)緯度信息,服務(wù)端進(jìn)行緩存

  • 用戶點(diǎn)擊菜單后,服務(wù)端獲取相應(yīng)菜單的點(diǎn)擊事件并調(diào)用接口將緩存中的用戶經(jīng)緯度信息進(jìn)行逆地址解析為城市名稱

  • 根據(jù)城市名稱調(diào)用天氣API獲取即時(shí)天氣數(shù)據(jù)并返回xml數(shù)據(jù)

開發(fā)準(zhǔn)備

  • 注冊(cè)百度地圖開放平臺(tái),新建服務(wù)端應(yīng)用,獲取百度AK

  • 微信公眾號(hào)菜單點(diǎn)擊發(fā)送實(shí)況天氣預(yù)報(bào)_天氣預(yù)報(bào)

  • 注冊(cè)天氣API,獲取免費(fèi)實(shí)況天氣接口的appid及appsecret

  • 確認(rèn)在微信公眾號(hào)管理后臺(tái)開啟了獲取用戶地理位置接口權(quán)限

關(guān)鍵代碼

app.js

  • ?
const getRawBody = require('raw-body')const xml2js = require('xml2js')const rp = require('request-promise')// 緩存使用node-localstorageif (typeof localStorage === 'undefined' || localStorage === null) {  var LocalStorage = require('node-localstorage').LocalStorage  localStorage = new LocalStorage('./scratch')}
router.post('/', async (ctx, next) => { var data = await getRawBody(ctx.req, { length: ctx.length, limit: '1mb', encoding: ctx.charset, }) const xml = await parseXMLAsync(data) const createTime = Date.parse(new Date()) const msgType = xml.xml.MsgType[0] const toUserName = xml.xml.ToUserName[0] const toFromName = xml.xml.FromUserName[0] const event = xml.xml.Event ? xml.xml.Event[0] : ''
localStorage.clear() let fromUserName = localStorage.getItem('fromUserName') || []
if (event == 'LOCATION') { let latitude = xml.xml.Latitude ? xml.xml.Latitude[0] : '' let longitude = xml.xml.Longitude ? xml.xml.Longitude[0] : ''
if (fromUserName.length > 0) { if (fromUserName.findIndex((f) => f.id == toFromName) == -1) { fromUserName.push({ id: toFromName, latitude: latitude, longitude: longitude, }) localStorage.setItem('fromUserName', fromUserName) } } else { fromUserName.push({ id: toFromName, latitude: latitude, longitude: longitude, }) localStorage.setItem('fromUserName', fromUserName) } }
if (msgType == 'event') { let replyMsg = '說些什么' if (event == 'subscribe') { replyMsg = '歡迎關(guān)注' //關(guān)注后 ctx.body = `<xml> <ToUserName><![CDATA[${toFromName}]]></ToUserName> <FromUserName><![CDATA[${toUserName}]]></FromUserName> <CreateTime>${createTime}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[${replyMsg}]]></Content> </xml>` } else if (event == 'CLICK') { let eventKey = xml.xml.EventKey ? xml.xml.EventKey[0] : '' switch (eventKey) { case 'weather': let latitude = '31.467138' let longitude = '120.286194' if (fromUserName.length > 0) { // 當(dāng)前用戶的經(jīng)緯度 latitude = fromUserName.find((f) => f.id == toFromName).latitude longitude = fromUserName.find((f) => f.id == toFromName).longitude } let options = { method: 'get', uri: 'http://api.map.baidu.com/geocoder?location=' + latitude + ',' + longitude + '&output=json&key=' + config.baiduAk, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, json: true, } let cityInfo = await rp(options), city = cityInfo.result.addressComponent.city.replace('市', '')
let woptions = { method: 'get', url: 'https://tianqiapi.com/api?version=v6&appid=' + config.weatherAppid + '&appsecret=' + config.weatherSecrect + '&city=' + encodeURI(city), json: true, } let weather = await rp(woptions) let weatherTip = `您當(dāng)前的城市${weather.city} 天氣:${weather.wea} 溫度:${weather.tem2}~${weather.tem1}℃ 實(shí)時(shí)溫度:${weather.tem}℃ 風(fēng)力:${weather.win}${weather.win_speed} 空氣質(zhì)量:${weather.air_tips}` replyMsg = weatherTip ctx.body = `<xml> <ToUserName><![CDATA[${toFromName}]]></ToUserName> <FromUserName><![CDATA[${toUserName}]]></FromUserName> <CreateTime>${createTime}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[${replyMsg}]]></Content> </xml>` break default: break } } } else { //其他情況 ctx.body = `<xml> <ToUserName><![CDATA[${toFromName}]]></ToUserName> <FromUserName><![CDATA[${toUserName}]]></FromUserName> <CreateTime>${createTime}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你說啥?]]></Content> </xml>` }})

完整代碼請(qǐng)移步github倉庫:

https://github.com/xuedingmiaojun/koa-demo/blob/master/wxgh-reply/app.js

掃碼體驗(yàn)

測(cè)試號(hào)二維碼

微信公眾號(hào)菜單點(diǎn)擊發(fā)送實(shí)況天氣預(yù)報(bào)_天氣預(yù)報(bào)_02

效果預(yù)覽

微信公眾號(hào)菜單點(diǎn)擊發(fā)送實(shí)況天氣預(yù)報(bào)_天氣預(yù)報(bào)_03

參考資料

  • koa2實(shí)現(xiàn)微信公眾號(hào)關(guān)注自動(dòng)回復(fù)消息

  • 獲取用戶地理位置:https://developers.weixin.qq.com/doc/offiaccount/User_Management/Gets_a_users_location.html

  • 百度地圖開放平臺(tái):http://lbsyun.baidu.com/index.php?title=%E9%A6%96%E9%A1%B5

  • 免費(fèi)實(shí)況天氣接口:http://www.tianqiapi.com/index/doc?version=v6

?

微信公眾號(hào)菜單點(diǎn)擊發(fā)送實(shí)況天氣預(yù)報(bào)_天氣預(yù)報(bào)_04

?

本文摘自 :https://blog.51cto.com/x

開通會(huì)員,享受整站包年服務(wù)立即開通 >