Cause, when I was looking for a gift for the object of marriage, I was worried (difficulty in choosing, I felt low when sending flowers). When I opened the nuggets, I found that a big man had written a template to push, and AS the front end, I began to move

Wechat service number

We found that individuals with service numbers could not apply, so we applied for a test public account (template push).

Egg Quick Start

Eggjs.org/zh-cn/intro…

  • Create a project (Hit enter)
$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i
Copy the code
  • Start the project
$ npm run dev
$ open http://localhost:7001
Copy the code
Creating a service
  • Access token
async getToken() {
  const {ctx, app} = this;
  const result = await ctx.curl(
    `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${app.config.appID}&secret=${app.config.appsecret}`,
    {
      dataType: "json".method: "GET"}); ctx.logger.info("getToken: %j", app.config.appID, app.config.appsecret);

  if (result.status === 200) {
    ctx.logger.info("getToken: %j", result.data);
    return result.data.access_token;
  }
  return result;
}
Copy the code
  • Send a message to wechat
async sendWeChat(token, openid, templateId, data) {
  const {ctx} = this;
  const result = await ctx.curl(
    `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`,
    {
      dataType: "json".headers: {
        "content-type": "application/json",},method: "POST".data: JSON.stringify({
        touser: openid,
        template_id: templateId,
        topcolor: "#FF0000",
        data,
      }),
    }
  );
  return result;
}
Copy the code
  • Initialize template data
async initTemplateData() {
  const dateTime = this.getDatetime();
  const loveDay = this.getLoveDay();
  const wageDay = this.getWageDay();
  const birthday = this.getbirthday();
  const oneSentence = await this.getOneSentence();
  const weather = await this.getWeather();
  return {
    dateTime: {
      value: dateTime + "" + weather.city,
      color: "#ef5b9c",},love: {
      value: loveDay,
      color: "#f15b6c",},wage: {
      value: wageDay,
      color: "#f8aba6",},birthday: {
      value: birthday,
      color: "#f69c9f",},message: {
      value: oneSentence,
      color: "#ca8687",},tem: {
      value: weather.tem,
      color: "#deab8a",},tem1: {
      value: weather.tem1,
      color: "#fedcbd",},tem2: {
      value: weather.tem2,
      color: "#d64f44",},win: {
      value: `${weather.win} ${weather.win_speed}`.color: "# 444693",},air: {
      value: `${weather.air_level} ${weather.air_tips}`.color: "#2b4490",},chuanyi: {
      value: weather.zhishu.chuanyi.tips,
      color: "#2a5caa",},daisan: {
      value: weather.zhishu.daisan.tips,
      color: "#f58220",},ganmao: {
      value: weather.zhishu.ganmao.tips,
      color: "# 843900",},ziwaixian: {
      value: weather.zhishu.ziwaixian.tips,
      color: "#6a6da9",}}; }Copy the code
  • Example Initialize the recommended daily data
initRecommendData() {
  const dateTime = this.getDatetime();
  const food = this.getDayEat();
  const timeColors = ["#cc99090"."#9933cc"."#00cc99"."# 990033"."#cc33cc"];
  const foodColors = [
    "#ff0066"."#cc66ff"."#9900ff"."#ffff33"."#ff3300"."#99ffff",];return {
    dateTime: {
      value: dateTime,
      color: timeColors[Math.floor(Math.random() * timeColors.length)],
    },
    food: {
      value: food,
      color: foodColors[Math.floor(Math.random() * foodColors.length)],
    },
    emojiTop: {
      value: "🧑 πŸ’› πŸ’š πŸ’™ πŸ’œ πŸ–€ πŸ–€ πŸ’œ πŸ’™ πŸ’š πŸ’› 🧑",},emojiFooter: {
      value: "🍎 🍏 🍐 πŸ‘ πŸ’ πŸ“ πŸ“ πŸ’ πŸ‘ 🍐 🍏 🍎",}}; }Copy the code
  • Initialize payroll-to-hand reminder data
initWageTipsData() {
  const colors = [
    "#ff0066"."#cc66ff"."#9900ff"."#ffff33"."#ff3300"."#99ffff",];const wageMessage = "Baby, I got paid today, please check!!";
  return {
    wageMessage: {
      value: wageMessage,
      color: colors[Math.floor(Math.random() * colors.length)],
    },
    emoji: {
      value: "🧑 πŸ’› πŸ’š πŸ’™ πŸ’œ πŸ–€ πŸ–€ πŸ’œ πŸ’™ πŸ’š πŸ’› 🧑",}}; }Copy the code
  • Get the current time
getDatetime() {
  const week = {
    1: "Monday".2: "Tuesday".3: "Wednesday".4: "Thursday".5: "Friday".6: "Saturday".0: "Sunday"};return (
    moment().format("YYYY: MM: SS A") +
    "" +
    week[moment().weekday()]
  );
}
Copy the code
  • How many days we love
getLoveDay() {
  const {app} = this;
  const loveDay = app.config.loveDay;
  return moment(moment().format("YYYY-MM-DD")).diff(loveDay, "days");
}
Copy the code
  • Find out how many days are left before payday
getWageDay() {
  const {app} = this;
  // What date do you get paid
  const wageDay = Number(app.config.wageDay);

  // How many days this month
  const curentDays = Number(moment().daysInMonth());

  // How many days of the month is the current time

  const curentDay = Number(moment().date());

  // Payroll date minus current date

  const flag = wageDay - curentDay;

  return flag >= 0 ? flag : curentDays - curentDay + wageDay;
}
Copy the code
  • Get how many days away from your birthday
getbirthday() {
  const {app} = this;
  // Determine whether an ordinary year is a leap year
  // const isLeapYear = moment([moment().year()]).isLeapYear();
  // If this year's birthday minus the current date is negative, then this year's birthday has passed
  let day = Math.ceil(
    (moment(moment().year() + "-" + app.config.birthday).valueOf() -
     moment().valueOf()) /
    1000 /
    60 /
    60 /
    24
  );
  if (day < 0) {
    day = Math.ceil(
      (moment(moment().year() + 1 + "-" + app.config.birthday).valueOf() -
       moment().valueOf()) /
      1000 /
      60 /
      60 /
      24
    );
  }
  return day;
}
Copy the code
  • Get a sentence of the day
async getOneSentence() {
  const {ctx} = this;
  const result = await ctx.curl("https://v1.hitokoto.cn/", {
    method: "GET".dataType: "json".headers: {
      "content-type": "application/json",}}); ctx.logger.info("getOneSentence %j:", result.data);

  if (result.status === 200) {
    return result.data.hitokoto;
  }

  return "Only I love you today!";
}
Copy the code
  • For the weather
async getWeather() {
  const {ctx} = this;
  const result = await ctx.curl("https://v0.yiketianqi.com/api", {
    method: "GET".dataType: "json".headers: {
      "content-type": "application/json",},data: {
      appid: "* * *".appsecret: "* * *".cityid: "* * *".version: "* * *",}}); ctx.logger.info(result);return result.data;
}
Copy the code
  • What do you randomly eat every day
getDayEat() {
  const menus = [
    malatang."Spicy spicy pot"."Dumplings"."Braised chicken"."Rice noodle"."Chicken"."Fried rice"."McDonald's"."Sushi"."Snail noodle"."Porridge"."Fish with pickled cabbage"."Take a dish"."Liangpi"."Wonton"."Barbecue"."θ‚―εΎ·εŸΊ"."Hot and sour powder"."Pizza"."Hot pot"."Noodles"."Hamburger"."Lanzhou Noodles"."Dumplings"."Chongqing noodles"."Steamed buns"."Pancake fruit"."Noodles with soy sauce"."Chicken Pot"."BBQ bibimbab."."Noodles"."Clay Pot rice"."Baked cold noodles"."KFC"."Fried noodles"."Steamed vermicelli roll"."Covered rice"."Bibimbap"."Braised chicken with rice".Burger King."Cooking"."Little bowl of vegetables."."Shaxian Snacks"."Curry rice"."Pig's foot rice"."Wallace"."Beef noodles"."Roast rice."."Beef soup"."Spicy sauce",];const random = Math.floor(Math.random() * menus.length);
  return menus[random];
}
Copy the code
  • Group tasks are sent periodically
sendAllWeChat(openids, templateId, data, token) {
  let sends = [];
  // Group tasks are sent periodically
  openids.forEach(async (openidItem) => {
    if (openidItem.status === 0) {
      sends.push(this.sendWeChat(token, openidItem.openid, templateId, data)); }});return Promise.all(sends);
}
Copy the code
  • Recommended Daily delivery
async sendRecommend(token, openid) {
  const {ctx, app} = this;
  const data = this.initRecommendData();
  const result = await this.sendWeChat(
    token,
    openid,
    app.config.templateIds.recommend,
    data
  );
  ctx.logger.info("sendRecommend: %j", result);
  return result;
}
Copy the code
  • Message sent by default
async send(type) {
  const {ctx, app} = this;
  const {openids, templateIds} = app.config;
  const token = await this.getToken();

  // Group daily alert if sendAll is used; group daily recommended food if sendRecommend is used
  if (type === "sendAll") {
    const data = await this.initTemplateData();
    ctx.logger.info("initTemplateData %j:", data);

    const result = await this.sendAllWeChat(
      openids,
      templateIds.dailyReminder,
      data,
      token
    );
    ctx.logger.info("sendAllWeChatAll %j:", result);
    // If the countdown to payday is 0 push payday reminder
    if (data.wage.value === 0) {
      const wageTipsData = this.initWageTipsData();
      const result = await this.sendAllWeChat(
        openids,
        templateIds.wageTips,
        wageTipsData,
        token
      );
      ctx.logger.info("sendAllWeChatWageTips %j:", result);

      return result;
    }
    return result;
  } else if (type === "sendRecommend") {
    const data = await this.initRecommendData();
    ctx.logger.info("initRecommendData %j:", data);
    const result = await this.sendAllWeChat(
      openids,
      templateIds.recommend,
      data,
      token
    );
    ctx.logger.info("sendAllWeChatRecommend %j:", result);
    return result;
  }
  return "error";
}
Copy the code
Timing task

The scheduled tasks for egg must create the Schedule folder under app

  • Daily morning push
const Subscription = require("egg").Subscription;

class DailyTask extends Subscription {
  // Use the schedule attribute to set the execution interval of scheduled tasks
  static get schedule() {
    return {
      cron: 0 30 5 * * *.// Run every day at 7:30:00
      // interval: 3000, // 1 minute interval
      type: "all".// specify that all workers need to be executed
    };
  }

  // subscribe is the function that is run when the actual scheduled task is executed
  async subscribe() {
    const {ctx} = this;
    const result = await ctx.service.sendmsg.send("sendAll");
    ctx.logger.info("Scheduled Task Execution message Reminder Daily reminder result: %j", result); }}module.exports = DailyTask;
Copy the code
  • Daily Dinner Push
const Subscription = require("egg").Subscription;

class DailyRecommend extends Subscription {
  // Use the schedule attribute to set the execution interval of scheduled tasks
  static get schedule() {
    return {
      cron: "0 0 10 * * *".// Run every day at 16:30:00
      // interval: 30000, // 1 minute interval
      type: "all".// specify that all workers need to be executed
    };
  }

  // subscribe is the function that is run when the actual scheduled task is executed
  async subscribe() {
    const {ctx} = this;
    const result = await ctx.service.sendmsg.send("sendRecommend");
    ctx.logger.info("Scheduled task execution message reminder daily recommended result: %j", result); }}module.exports = DailyRecommend;

Copy the code
Configuration to add

The cofig configuration configures its own data in the Egg directory

  const userConfig = {
    // Days of love
    loveDay: "0000-00 00 -".// Payday
    wageDay: moment().endOf("month").format("DD"),

    / / birthday
    birthday: "00 00 -".openids: [{openid: "openid".name: "Changan".status: 0.// 0 indicates push and 1 indicates no push
      },
      {
        openid: "openid".name: "Home".status: 1}, {openid: "openid".name: "AmessZH.	".status: 1],},templateIds: {
      dailyReminder: "9GHyNIXKmZwOOL9Z4uQIKbLRBzMSrVIHSvhAmdcCUgk".// Daily reminders
      oneSentence: "4e1nCdyUQ7ihTlmSrsZGP9vKbCvfWwbxP-5zEa4X4hk".// One sentence of the day
      recommend: "oW5Apy-Z1vwvC5DU6lvv0JkZceiGkqyxFwVamp7CN9A".// Daily menu recommendations
      wageTips: "28pgPk2-NXMBHmgD-PoxeK36tK6s1zG9FBeZq4-Pdpc".// Pay reminder}};Copy the code
  • Individual Environment Configuration
module.exports = (appInfo) = > {
  return {
    appID: "appID".appsecret: "appsecret"}; };Copy the code
Template to add

Wechat official account template added

  • Pay submission reminder
{{emoji.DATA}} {{wageMessage.DATA}} {{emoji.DATA}}
Copy the code
  • A daily reminder
. {{dateTime DATA}} today is we fell in love and {{love. DATA}} days from salary to still use {{wage. DATA}} your birthday day distance and {{birthday. DATA}} days The current temperature {{tem. DATA}} Today's lowest temperature {{tem1.DATA}} Today's highest temperature {{tem1.DATA}} {{win.DATA}} Air quality {{air.DATA}} Clothes {{chuanyi.DATA}} umbrella {{daisan.DATA}} cold {{ganmao.DATA}} ultraviolet {{ziwaixian.DATA}}Copy the code
  • What to eat today
{{emojitop. DATA}} It's almost time to eat!! {{datetime.data}} Remember to eat!! {{food.DATA}} {{emojifooter. DATA}}Copy the code
Application deployment

Eggjs.org/zh-cn/core/…