去哪吃

背景

看到这个题目,你也许会想『啥意思,什么去哪吃,想去哪吃去哪吃呗』。说得好,关键是不知道去哪吃,纠结啊。于是,就想着可不可以搞一个每天定时告诉我去哪吃的小脚本,定时发个邮件告诉我去哪吃,距离、价格最好也能一并告诉我。正所谓:『行胜于言』,搞起:rofl:

其实这篇文章没啥技术含量,就是挺好玩的。:stuck_out_tongue:

准备工作

  • axios:请求库
  • nodemailer:用于发送邮件
1
2
3
4
mkdir getCating
cd getCanting
npm init --yes
npm i axios nodemailer

获取周边餐馆:v:

检索周边地点主要是调用了百度地图的Web服务API。

可参考地点检索服务服务文档。

原型区域检索API(GET请求):http://api.map.baidu.com/place/v2/search?query=银行&location=39.915,116.404&radius=2000&output=xml&ak=您的密钥。具体的请求参数也可参考地点检索服务服务文档。

这个query参数里面唯一需要自己去获取的就是经纬度(location)。这个具体的获取方法如下:

1
2
3
4
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude);
console.log(position.coords.longitude)
})

这个要打开浏览器的定位服务。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
const request = require('axios');
const fs = require('fs');
const path = require('path');
const ak = 'xxxxxxxxxxxxxxxxxxxx';
const query = encodeURI(`query=小吃$快餐$中餐&tag=小吃&location=40.04171,116.312820086&scope=2&radius_limit=true&page_size=20&radius=500&output=json&ak=${ak}`);

request.get(`http://api.map.baidu.com/place/v2/search?${query}`)
.then(res => {
fs.writeFileSync(path.resolve(__dirname, 'cantingList.json'), JSON.stringify(res.data, null, '\t'));
})

返回的结果如下:

发送邮件:dizzy:

发送邮件主要用了nodemailer这个第三方库,使用方法可参考usage以及内置支持的服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const nodemailer = require('nodemailer');

const transport = nodemailer.createTransport({
service: 'QQ',
auth: {
user: 'xxxxxxx@qq.com',
//这个密码不是qq密码,而是qq邮箱的授权码
pass: 'xxxxxxxx'
}
})

let mailOption = {
from: '"xxxx" <xxxxxxxx@qq.com>',
to: ['email-list'],
subject: '中午/晚上吃什么? 我来告诉你',
}

function send(_item) {
transport.sendMail(Object.assign(mailOption, {
text: `
名称:${_item.name}
地址:${_item.address}
距离:${_item.detail_info.distance}
人均价格:${_item.detail_info.price || '暂无数据'}
评分:${_item.detail_info.overall_rating || '暂无数据'}
经纬度:${_item.location.lat}, ${_item.location.lng}
电话:${_item.telephone || '暂无电话'}
在地图中查看:${_item.detail_info.detail_url}
`
}), (err, info) => {
if (err) {
return;
}
console.log('Message send successfully: %s', info.messageId);
})
}

看这:eyes: qq邮箱的授权码怎么获取?

最后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const request = require('axios');
const nodemailer = require('nodemailer');
const fs = require('fs');
const path = require('path');
const ak = 'xxxxxxxxxxxxxxx';
const query = encodeURI(`query=小吃$快餐$中餐&tag=小吃&location=40.04171,116.312820086&scope=2&radius_limit=true&page_size=20&radius=500&output=json&ak=${ak}`)

let item;

const transport = nodemailer.createTransport({
service: 'QQ',
auth: {
user: 'xxxxxx@qq.com',
pass: 'xxxxxxxx'
}
})

let mailOption = {
from: '"name" <xxxxxx@qq.com>',
to: ['email-list'],
subject: '中午/晚上吃什么? 我来告诉你',
}

function send(_item) {
transport.sendMail(Object.assign(mailOption, {
text: `
名称:${_item.name}
地址:${_item.address}
距离:${_item.detail_info.distance}
人均价格:${_item.detail_info.price || '暂无数据'}
评分:${_item.detail_info.overall_rating || '暂无数据'}
经纬度:${_item.location.lat}, ${_item.location.lng}
电话:${_item.telephone || '暂无电话'}
在地图中查看:${_item.detail_info.detail_url}
`
}), (err, info) => {
if (err) {
return;
}
console.log('Message send successfully: %s', info.messageId);
})
}

request.get(`http://api.map.baidu.com/place/v2/search?${query}`)
.then(res => {
fs.writeFileSync(path.resolve(__dirname, 'cantingList.json'), JSON.stringify(res.data, null, '\t'));
item = res.data.results[parseInt(Math.random() * 20)]
send(item);
})

定时执行 :clock11:

用的crontab,crontab -e直接编辑如下:

1
30 11,17 * * 1-5 /usr/local/bin/node /Users/{your path}/getCanting/getCanting.js

最后

感觉挺好玩的,虽然没啥含金量,但是感觉还是有那么「yinainai」(就是一点点的意思 :dog:)收获。

好啦 就到这吧。

土遁~~~~ :wave: :wave: