Вы можете быть роботом-напоминателем для корпоративного WeChat, не тратя денег

Serverless
Вы можете быть роботом-напоминателем для корпоративного WeChat, не тратя денег

Ли Чэнси, руководитель клиентского отдела Shopee Airpay. Он присоединился к Tencent AlloyTeam после выпуска в 2014 году и отвечал за такие проекты, как QQ Group, Fantasia Live и Tencent Documents. Позже он присоединился к команде разработчиков Tencent Cloud в 2018 году. Сосредоточьтесь на оптимизации производительности, инжиниринге и небольших программах.Вейбо | Знай почти | Github

Придя в новую компанию, я обнаружил, что также использую корпоративный WeChat. Но, к сожалению, WeChat, внешнее предприятие, не имеет роботов. Это очень неудобно для меня, который раньше использовал корпоративный WeChat в качестве напоминания на гусиной фабрике. Наконец, в начале июля корпоративный WeChat наконец-то запустил функцию робота.

Щелкните правой кнопкой мыши карточку группового чата, чтобы добавить групповых ботов.

При наведении курсора на аватарку робота отобразится адрес вебхука. Нажав на этот адрес, вы перейдете к документации по разработке робота.

Разработка робота-напоминания на самом деле очень проста, по сути, это отправить запрос на этот адрес вебхука в формате, предусмотренном документом, после чего может быть реализован push сообщения. Самый простой пример, вы можете использоватьNode.jsизaxiosБиблиотека классов:

const axios = require('axios')

async function bookLunch() {
    let result = await axios.post(baseUrl, {
        msgtype: 'text',
        text: {
            content: '大佬,订午餐啦!',
            mentioned_list: ['@all'] // 可以使用邮箱或者手机号码
        }
    })

    return result.data
}

bookLunch.then((res) => {
    console.log(res)
})

Выше приведен самый простой пример. В дополнение к обычному текстовому содержимому также можно отправлятьmarkdown, графику и другой контент, вы можете перейти к документации самостоятельно.

Но здесь возникает проблема: вообще говоря, напоминания должны быть рассчитаны по времени, например, напоминать всем о написании плана каждое утро и напоминать всем о написании еженедельного отчета каждую пятницу и вечер.Как может робот появиться в это время, чтобы напомнить каждый? Вы можете подумать о покупке сервера и развертывании на немcronjobУслуги, расписание услуг регулярно. Да, это, конечно, самый распространенный способ. Но купить сервер стоит денег, а виртуальная машина стоит десятки долларов, и запускать на ней такой простой сервис явно не стоит. Есть ли экономичный способ? Да, используйте облачные функции!

В моем личном понимании есть несколько основных отличий между облачными функциями и традиционными сервисами: во-первых, это сервис, основанный на событиях, который запускается разными событиями (HTTP, изменение данных, изменение объектного хранилища и т. д.), а второй заключается в том, что это сервис, основанный на событии. Он не является резидентным и будет охлаждаться или уничтожаться после работы в течение определенного периода времени. В-третьих, из-за двух вышеуказанных характеристик для некоторых сервисов с низкой нагрузкой это дороже -эффективно использовать облачные функции. Для такого рода робота-напоминания это сервис с низкой нагрузкой, что очень подходит. Такой сервис напоминаний для небольших команд действительно можно сделать без денег в последнее время, когда его продвигают крупные производители.

Здесь я больше всего знаком с облачными функциями Tencent Cloud, поэтому использую его для практики.

Прежде всего, для удобства мы можем использовать интерфейс командной строки SCF, предоставленный Tencent Cloud, для инициализации наших облачных функций и файлов конфигурации. Я использую компьютер Macbook, который можно установить напрямую с помощью следующей команды:

pip install scf

Если это не Macbook, вы можете сначала установить его самостоятельноpythonа такжеpip

Затем необходимо настроить:

scf configure set --region ap-guangzhou --appid 1253970223 --secret-id AKIxxxxxxxxxx --secret-key uxxlxxxxxxxx

appid, secret-idа такжеsecret-keyдопустимыйключ доступаполучено со страницы. Что касаетсяregion, — это область, в которой вы хотите развернуть облачную функцию. Например, на домашней странице консоли облачных функций вы можете увидеть верхнюю область. выбрать Гуанчжоуap-guangzhou, выберите Гонконгap-hongkong. В принципеap-Плюс пинжин или английский на внутреннем рынке.

image.png

Затем инициализируем проект (пишем облачные функции с node.js версии 8.9):

# 初始化云函数
scf init --runtime nodejs8.9 --name wework-robot

cd wework-robot

# 初始化 node 项目
npm init -y

Затем вы можете получить облачную функцию:

image.png

Чтобы использовать axios на этот раз, мы установим эту зависимость:

npm i --save axios

Открытьindex.jsследующий фрагмент кода,asyncУказывает, что функцию можно использоватьNode.jsновые особенностиasync/await.

'use strict';
exports.main_handler = async (event, context, callback) => {
    console.log("%j", event);
    return "hello shopee!"
};

После того, как я сделал некоторые удаления, стало так. Измените имя функции наmain, а с момента использованияasync/awaitты сможешьcallbackОбработка асинхронная. Но изменить имяtemplate.yaml,Будуmain_handlerизменить наmain

exports.main = async (event, context) => {
    return "hello shopee!"
};

image.png

Отлично. Время написать логику напоминаний. Логика не сложная, но главное замечать время. После тестирования время здесь, в облачной функции, единообразно использует стандартное международное время, то есть пекинское время отстает от него на 8 ч. Подробную логику можно увидеть в комментариях к следующему коду:

const axios = require('axios')
const baseUrl =
    'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=[token]'

async function bookLunch() {
    let result = await axios.post(baseUrl, {
        msgtype: 'text',
        text: {
            content: '大佬,订午餐啦!',
            mentioned_list: ['@all'] // 提醒所有人
        }
    })

    return result.data
}

async function bookTaxi() {
    let result = await axios.post(baseUrl, {
        msgtype: 'text',
        text: {
            content: '辛苦了,早点回家休息吧。9点打车可以报销哦。',
            mentioned_list: ['@all']
        }
    })

    return result.data
}

async function remindWeeklyReport() {
    let result = await axios.post(baseUrl, {
        msgtype: 'text',
        text: {
            content: '周五了,记得写周报看看你这周有没偷懒!',
            mentioned_list: ['@all']
        }
    })

    return result.data
}

async function remindGoHome() {
    let result = await axios.post(baseUrl, {
        msgtype: 'text',
        text: {
            content: '11点半了,早点休息吧!'
        }
    })

    return result.data
}

// 是否周五
function isFriday(day) {
    return day === 5
}

// 是否工作日
function isWeekDay(day) {
    return day > 0 && day < 6
}

// 是否30分,多预留1分钟以防云函数延迟启动或执行
function isHalfHour(min) {
    return min >= 30 && min <= 31
}

// 是否正点,多预留1分钟以防云函数延迟启动或执行
function isSharp(min) {
    return min >= 0 && min <= 1
}

exports.main = async (event, context) => {
    let d = new Date() // js 时间对象
    let day = d.getDay() // 获取今天是星期几,0 表示周日
    let hour = d.getHours() // 获取当前的 时
    let min = d.getMinutes() // 获取当前的 分

    let hourGap = 8 // 咱们在东8区
    hour += hourGap // 获取当前准确的时间数

   // 打一下 log 看看具体时间
    console.log(`day: ${day} hour: ${hour} min: ${min} hourGap: ${hourGap}`)

    // 每周五4点到4点半通知写周报
    if (isFriday(day) && hour === 4 && isHalfHour(min)) {
        return await remindWeeklyReport()
    }

    // 工作日每天11点提醒订餐
    if (isWeekDay(day) && hour === 11 && isSharp(min)) {
        return await bookLunch()
    }

    // 工作日每天晚上9点提醒打车可以报销
    if (isWeekDay(day) && hour === 21 && isSharp(min)) {
        return await bookTaxi()
    }

    // 工作日每天晚上11点半提醒休息
    if (isWeekDay(day) && hour === 23 && isHalfHour(min)) {
        return await remindGoHome()
    }

    return 'hi shopee!'
}

Вся логика написана, но нам нужно, чтобы она запускалась периодически, например, каждые 30 минут. В это время нам нужно добавить «таймерный триггер». Триггер времени, который мы можемtemplate.yamlДобавьте его внутрь, вы можете удалить комментарий, а затем изменить его, чтобы получить:

image.png

CronExpressionДля получения подробной информации см. этот документ:cloud.Tencent.com/document/cheat…

Пожалуйста, используйте рекомендуемые обозначения:

image.png

Вот несколько примеров для справки, которые можно применять напрямую:

image.png

Я написал здесь:0 */30 * * * MON-FRI *, что означает, что вызов облачной функции будет запускаться каждые 30 минут с понедельника по пятницу.

Конечно, мы также хотим включить триггер HTTP, чтобы использовать адрес для прямого доступа к облачной функции для некоторой логической отладки, чтобы увидеть, действительно ли сообщение может быть успешно отправлено.

мы можем прийти сноваtemplate.yamlдобавить это кHTTPвызывать:

image.png

Ну все готово, осталось только использовать сноваSCF CLIПросто опубликуйте.

# 打包
scf package -t template.yaml 
Generate deploy file 'deploy.yaml' success

# 发布
scf deploy -t deploy.yaml 
Deploy function 'wework-robot' success

После завершения выпуска мы можем перейти в консоль Tencent Cloud и убедиться, что он уже существует:

image.png

Нажмите, чтобы увидеть метод триггера, и обнаружите, что есть триггер синхронизации и триггер шлюза API (триггер HTTP).

Итак, готово! Взгляните на эффект: