首页 > 其他分享 >微信公众号菜单点击发送天气预报

微信公众号菜单点击发送天气预报

时间:2022-11-30 17:31:35浏览次数:70  
标签:xml 菜单 fromUserName 微信 weather let latitude const 天气预报


本文介绍如何为公众号添加一个菜单点击后给用户发送天气预报的功能

上一次介绍了如何为公众号添加​​关注自动回复​​的功能,这次我们来扩展一个比较实用的功能--天气查询

​​#​​ 程序思路

  • 用户进入公众号会话,上传经纬度信息,服务器进行缓存
  • 用户点击菜单后,服务端获取相应菜单的点击事件并调用接口将缓存中的用户经纬度信息进行逆地址解析为城市名称
  • 根据城市名称调用天气API获取即时天气数据并返回xml数据

​​#​​ 开发准备

  • 注册百度地图开放平台,新建服务端应用,获取百度AK​
  • 微信公众号菜单点击发送天气预报_vue


  • 注册天气API,获取免费实况天气接口的appid及appsecret
  • 确认在微信公众号管理后台开启了获取用户地理位置接口权限

​​#​​ 关键代码

app.js

const getRawBody = require('raw-body')
const xml2js = require('xml2js')
const rp = require('request-promise')
// 缓存使用node-localstorage
if (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 = '欢迎关注'
//关注后
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) {
// 当前用户的经纬度
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 = `您当前的城市${weather.city}\n天气:${weather.wea}\n温度:${weather.tem2}~${weather.tem1}℃\n实时温度:${weather.tem}℃\n风力:${weather.win}${weather.win_speed}\n空气质量:${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>`
}
})


完整代码请移步​​github仓库 ​

​​#​​ 扫码体验

测试号二维码



微信公众号菜单点击发送天气预报_vue_02


​​#​​ 效果预览




微信公众号菜单点击发送天气预报_java_03

​​


​​#​​ 参考资料


标签:xml,菜单,fromUserName,微信,weather,let,latitude,const,天气预报
From: https://blog.51cto.com/xuedingmaojun/5900037

相关文章