如何制作一个发送每日一图的小工具?

目录

  • 如何制作一个发送每日一图的小工具?
    • 前言
    • 第一步:获取图片
      • 方法一:使用随机图片接口
      • 方法二:从Pixiv网站获取好看的插图
    • 第二步:存储图片
    • 第三步:将图片链接存储至数据库
    • 第四步:设置定时任务,发送每日一图

前言

之前看到一个博客,介绍了nodemailer库,使用nodemailer可以给自己发送每日一言。我突发奇想,是不是可以每天给自己和其他小伙伴发送每日一图呢?说干就干,每日一图的主要难点在以下四部分:

  • 图片如何获取
  • 如何存储图片
  • 如何将图片地址存入数据库,以供每日读取
  • 如何可配置的给目标邮箱每日发送图片

因为我不希望在以后打开邮件看的时候会出现图片404的情况,所以不打算使用现成的随机图片的接口或者使用三方的图床用于图片存储,所以我们从头获取图片,存储到自己图床、将图片地址写入数据库、每天读取数据库的数据发送给指定邮箱。

友情提醒,我学习JavaScript为主,以下所有代码均为nodejs,可以通过别的语言达成同样效果,js程序员可以直接使用我的代码,其余语言可以借鉴一下思路。

第一步:获取图片

此处我使用了两种方法来下载图片:通过现成的随机图片接口和下载Pixiv上的图片。

方法一:使用随机图片接口

最开始,我接触到一些随机的图片接口,每次调用都能返回随机的图片,我就写了一个小程序反复调用这类接口,然后直接上传至OSS(OSS将在下面提及,如果使用此方法请自行替换OSS相关参数),因为采用数字命名,导入数据库非常方便,当然你可以将地址直接存入数据库,但是怕网速限制或者后面资源不在的情况,我选择转存一次。以下是nodejs代码。

const https = require('https');
const axios = require('axios');
const oss = require('ali-oss');const client = oss({//设置OSS参数accessKeyId: '[OSS accessKeyId]',accessKeySecret: '[OSS accessKeySecret]',bucket: '[OSS bucket]',region: '[OSS region]'
});(async function begin() {let re = await axios.post('https://api.lolicon.app/setu/v2', {num: 5})let array = re.data.data.map(i => i.urls.original)console.log(array)for (let i = 0; i < 5; i++) {let res = await axios.get(array[i], {responseType: 'arraybuffer'})let file = res.datalet result = await client.put(`/PLMM/${i + 1}.png`, file)console.log(`第${i + 1}张上传成功`)}
})()

PS:此处使用了Tsuk1ko (神代綺凛) 大佬的随机图片接口,具体接口参数可以参考这里。

方法二:从Pixiv网站获取好看的插图

Pixiv是个优秀的插画分享网站,上面有很多优秀的插画可供查看下载,当然一张一张下载肯定不符合程序员的逻辑,我使用了pxder这个工具,这个工具的好处在于你登录过后可以一键下载你关注的画师的所有作品以及你收藏的所有插画作品,而且它通过多线程进行下载,速度还是非常快的(这个工具也是上面那个大佬写的)。

第二步:存储图片

之前提到,我不想在以后无法访问图片,所以,我们需要使用自己的图床,此处我使用的是阿里云的OSS服务。如果第一次接触OSS的朋友可以在这里查看搭建方法或者查看官方文档,我在这里不过多赘述了。

使用官方提供的OSS图形化管理工具ossbrowser上传我们整个图片文件夹

第三步:将图片链接存储至数据库

之前提到,我们将整个文件夹统一放至OSS,所以在OSS上文件的路径和本地路径是一致的,我们只需读取出本地的图片路径再将基地址替换成OSS地址就可以获取到所有图片的地址了:

const fs = require('fs')
const path = require('path')
function getFiles(dirname) {fs.readdir(dirname, {withFileTypes: true}, (err, files) => {files.forEach(file => {const pathName = path.resolve(dirname, file.name)if (file.isDirectory()) {getFiles(pathName)} else {if(['.png','.jpg'].includes(path.extname(pathName))){let originPath=pathName.replace('/Users/dell/Pictures/','[Your OSS Address]')fs.writeFileSync('file.sql', `INSERT INTO emailurl (url) VALUES ("${originPath}");` + '\n', {flag: 'a+'})console.log(originPath)}}})})
}getFiles('/Users/dell/Pictures/pixiv/')

在指定数据库运行file.sql文件,就可以将所有的图片地址导入进数据库啦。

具体构建数据库结构语句如下:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for emailconfig
-- ----------------------------
DROP TABLE IF EXISTS `emailconfig`;
CREATE TABLE `emailconfig`  (`id` int(3) NOT NULL AUTO_INCREMENT,`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`value` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;-- ----------------------------
-- Records of emailconfig
-- ----------------------------
INSERT INTO `emailconfig` VALUES (1, 'alreadyNo', '0');
INSERT INTO `emailconfig` VALUES (2, 'pageSize', '5');-- ----------------------------
-- Table structure for emailurl
-- ----------------------------
DROP TABLE IF EXISTS `emailurl`;
CREATE TABLE `emailurl`  (`id` int(6) NOT NULL AUTO_INCREMENT,`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;-- ----------------------------
-- Records of emailurl
-- ------------------------------ ----------------------------
-- Table structure for emailuser
-- ----------------------------
DROP TABLE IF EXISTS `emailuser`;
CREATE TABLE `emailuser`  (`id` int(11) NOT NULL AUTO_INCREMENT,`userName` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`emailAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`del_flag` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0',PRIMARY KEY (`id`) USING BTREE,INDEX `id`(`id` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;-- ----------------------------
-- Records of emailuser
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;

你可以在用户表配置要发送给的用户列表和对他们的称呼,并在配置表里配置当前发送的位置和每天需要发送的图片数量。

第四步:设置定时任务,发送每日一图

const mysql = require('mysql');
const nodemailer = require("nodemailer")
const schedule = require("node-schedule")
const config = {host: '[database url]',//mysql数据库域名/ipport: '3306',//mysql数据库端口,默认3306user: '[database user]',//数据库用户password: '[database password]',//数据库密码database: '[database name]',//数据库名称connectTimeout: 5000, //连接超时multipleStatements: false //是否允许一个query中包含多条sql语句
}const user = "[send user]"//发件人邮箱
const pass = "[send user pass]"//发件人授权码//定义发件人
const transporter = nodemailer.createTransport({host: "smtp.qq.com",port: 587,secure: false,auth: {user: user,pass: pass},
});async function sendMail() {//定义数据库连接let connection = mysql.createConnection(config);connection.connect();//封装数据库请求方法function asyncSql(sql) {return new Promise(resolve => {connection.query(sql, (err, result) => {if (err) throw errresolve(result)})})}//查询需要发送的用户const users = await asyncSql('SELECT * from EmailUser where del_flag=0')//获取发送条数和开始位置const emailConfig = await asyncSql('select * from emailconfig')let alreadyNo = +emailConfig.find(i => i.name === 'alreadyNo').valuelet pageSize = +emailConfig.find(i => i.name === 'pageSize').value//获取将要发送的图片地址const paths = await asyncSql(`select * from emailurl where id Between ${+alreadyNo} AND ${+alreadyNo+pageSize-1}`)let imgs = ''paths.forEach(i => imgs += `<img src="${i.url}" alt="">\n`)//更新开始位置await asyncSql(`UPDATE emailconfig SET value = ${alreadyNo+pageSize+''} WHERE name='alreadyNo'`)//遍历查询到的用户列表发送邮件users.map(async (i) => {await transporter.sendMail({from: `每日快乐源泉<${user}>`, // sender addressto: i.emailAddress, // list of receiverssubject: `${i.userName},今天也要元气满满哦`, // Subject linehtml: `<h2>亲爱的${i.userName},这是今日美图分享,今天也要开开心心的哦(*^▽^*)</h2>${imgs}<h5 style="color: #ccc">退订:退订?退订是不可能退订的,这辈子都不可能的(\`へ´*)ノ</h5>`});console.log(`${new Date()}---------${i.userName}已发送`)})//关闭数据库连接connection.end();
}console.log("服务启动")
//开启每天九点半的定时任务
schedule.scheduleJob('0 30 9 * * *', () => {sendMail()
})

将代码放到服务器上,使用forever进行node进程守护,然后在数据库配置好对应收件人信息就可以等待每天收到美美的图片啦。

制作一个每日一图小工具相关推荐

  1. 利用 C# 中的 FileSystemWatcher 制作一个文件夹监控小工具

    利用 C# 中的 FileSystemWatcher 制作一个文件夹监控小工具 独立观察员 2020 年 12 月 26 日 前一段看到微信公众号 "码农读书" 上发了一篇文章&l ...

  2. [python运维] 使用python3制作一个mysql压测小工具!

    ​​0x01 argparse模块​​ ​ argparse是Python 标准库中推荐的命令行解析模块,他可以实现给出参数提示和接收用户输入的参数,类似linux的命令行功能:​ [root@yun ...

  3. Python下借助百度翻译API制作一个翻译pdf的小工具-01

    出于需要经常会读一些英语的pdf文档,奈何英语太差只得借助机翻.每次都需要把pdf里的文档复制粘贴到翻译软件里,接着在把结果复制到word文档里,之间还需要排版什么的.今天突然发现百度翻译有一个公开的 ...

  4. Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~

    本文地址:http://www.jb51.net/article/8314.htm Aveiconifier是一个非常实用方便的制作ico格式文件的小工具~ 也许有一些对网页知识不是很了解的网友并不清 ...

  5. 利用python来自己写一个服务器台账统计小工具

    利用python来自己写一个服务器台账统计小工具 前言 无奈呀,压力创造成品 背景是这样的,相信在看的各位在管理服务器密码的时候,肯定会有个台账啥的,当然咱也有,但是吧,为了安全期间,不允许出现在服务 ...

  6. Photoshop制作一个质感的卡通小公仔

    Photoshop制作一个质感的卡通小公仔,效果图看上去有点3D的效果,不过人物部分非常简单,用PS也很容易做出来.制作的时候,高光部分的制作非常重要,需要用高光来渲染物体的质感.质感越好,人物的立体 ...

  7. 用Python条件判断简单制作一个12星座速配工具

    今天是学习Python语言第二天,今天主要学习的是Python的条件判断,感觉和php基本上还是比较类似的.感觉Python的输出函数比较实用,在学习Python条件判断的过程中,突发奇想我可以借助P ...

  8. OpenCV的HSV空间度量与标准HSV不一样,使用的时候需要换算;另附一个调色取色的小工具

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 在对图像的颜色进行处理时,RGB通道并不能很好地 ...

  9. 用 C# 写一个 Redis 数据同步小工具

    用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一 ...

最新文章

  1. 2022-2028年中国钢铁智能制造产业竞争现状及发展趋势分析报告
  2. 【神经网络】(10) Resnet18、34 残差网络复现,附python完整代码
  3. SQLite.swift的简单使用
  4. 51nod 1013【快速幂+逆元】
  5. 适合初学者快速入门的Numpy实战全集
  6. Uipath 学习栏目基础教学:13、Uipath调用python代码
  7. boost::fibers模块实现适配方法调用的测试程序
  8. ElasticSearch聚合查询
  9. 枚举算法:最小连续n个合数。试求出最小的连续n个合数(其中n是键盘输入的任意正整数)。
  10. 0宽字符加密_vulnhub实战靶场攻略:Breach 1.0
  11. PyTorch——torch.Tensor与np.ndarray(NumPy)之间的类型转换
  12. CRT远程工具连接服务器CentOS
  13. 预处理: 主成分分析和白化
  14. nginx-rtmp一些指令
  15. DevExpress Windows Form(1) DevExpress控件之主题
  16. 交换机SERDES介绍
  17. 基于R语言做层次聚类分析
  18. VS2019 C#开发手机App环境配置和开发
  19. php读取路由器arp表,详解ARP地址解析协议的工作流程
  20. echarts 实现图表缩放功能 dataZoom自带属性实现

热门文章

  1. ADB FORWARD
  2. 5分钟了解赴港上市公司CEO薪酬
  3. 研发里那只看不见的手,勒的很疼
  4. python汇率兑换双向_汇率兑换—python第一课
  5. 《缠中说禅108课》1:不会赢钱的经济人,只是废人
  6. 云原生系列六:容器和Docker
  7. Visionpro棋盘格校正
  8. 计算机管理如何格式化u盘,如何格式化U盘【图文教程】
  9. Android studio 多渠道打包(包括不同的包使用不同的资源文件、不同的包写不同的代码,包名等等)
  10. 网站页面制作教程[纯萌新]