【SpringBoot】✈️整合飞书群机器人发送消息

news2025/5/20 13:33:51

💥💥✈️✈️欢迎阅读本文章❤️❤️💥💥

🏆本篇文章阅读大约耗时3分钟。

⛳️motto:不积跬步、无以千里

📋📋📋本文目录如下:🎁🎁🎁

目录

前言

账号创建

代码实现

         1、添加配置

         2、测试接口

安全校验

章末

前言

        小伙伴们大家好,上篇文章是简单实现了常见的图形验证码的使用,文章链接如下:

【验证码】⭐️集成图形验证码实现安全校验-CSDN博客

        这篇文章来看下,如何整合飞书的群机器人发送自定义消息,一切从简(摆烂 bushi )

账号创建

        本地是在电脑端,点击左上角的加号,选择创建群组,之后在对应群组页面的右上角打开设置,点击群机器人,添加机器人,选择下面这一个即可

         点击创建机器人后可以获取到对应的 webhook 地址

代码实现

         1、添加配置

        将 webhook 加到配置文件中,然后用配置类来读取,将配置类交由 spring 管理

ext:
  larkBotConfig:
    webhookUrl: https://open.feishu.cn/open-apis/bot/v2/hook/3e2c19d1-8fdd-4b56-b147-b613e90064a5
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author benbenhuang
 * @date 2025/5/18 21:13
 */
@Configuration
@ConfigurationProperties(prefix = "ext")
@Data
public class ExtProperties {
    private final LarkBotConfig larkBotConfig = new LarkBotConfig();

    @Data
    public static class LarkBotConfig{
        private String webhookUrl;
    }
}
        2、测试接口

        将需要发送的消息,传递给接口,测试下 效果如下:

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author benbenhuang
 * @date 2025年05月18日 19:28
 */
@RequestMapping("/testLark")
@RestController
@Slf4j
public class LarkController {

    @Autowired
    private ExtProperties extProperties;
    @PostMapping("/send")
    public void sendLark(@RequestParam("notice") String notice){
        send(notice);
    }

    private void send(String notice){
        try {
            Map<String,Object> header=new HashMap();
            Map<String,Object> text=new HashMap();
            text.put("text",  notice);
            header.put("msg_type", "text");
            header.put("content", text);
            //发送post请求
            String result = HttpRequest.post(extProperties.getLarkBotConfig().getWebhookUrl()).body(JSON.toJSONString(header), "application/json;charset=UTF-8").execute().body();

            log.info("lark resp:{}", result);
        } catch (Exception e) {
            log.error("lark发送消息异常", e);
        }
    }

    
}

 

安全校验

        1、上面的方式是没有加权限校验的实现,也就是说只要获取到 webhook 链接,谁都可以向这个群里发送消息,针对此情况可以开启群机器人的 权限校验,从这里开启,获取到秘钥之后,点击保存即可

         2、调整配置

        加入秘钥配置:

        3、测试接口

         安全校验具体到代码层面就是,请求参数中根据官方文档中要求的时间戳和加密后的sign值

自定义机器人使用指南 - 开发指南 - 飞书开放平台

@RequestMapping("/teatLark")
@RestController
@Slf4j
public class LarkController {

    @Autowired
    private ExtProperties extProperties;

    @PostMapping("/sendWithToken")
    public void sendLarkWithToken(@RequestParam("notice") String notice){
        sendWithSignature(notice);
    }

    private void sendWithSignature(String notice) {
            String secret = extProperties.getLarkBotConfig().getSecret(); // 从 Lark 后台获取
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000); // 当前时间戳,单位秒
            String sign = calculateSignature(timestamp, secret);
        try {
                Map<String,Object> json=new HashMap();
                Map<String,Object> text=new HashMap();
                text.put("text",  notice);
                json.put("msg_type", "text");
                json.put("content", text);
                json.put("timestamp", timestamp);
                json.put("sign", sign);
                //发送post请求
                String result = HttpRequest.post(extProperties.getLarkBotConfig().getWebhookUrl()).body(JSON.toJSONString(json), "application/json;charset=UTF-8").execute().body();

                log.info("lark resp:{}", result);
            } catch (Exception e) {
                log.error("lark发送消息异常", e);
            }
    }


    private static String calculateSignature(String timestamp, String secret) {
        try {
            //把timestamp+"\n"+密钥当做签名字符串
            String stringToSign = timestamp + "\n" + secret;
            //使用HmacSHA256算法计算签名
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(new byte[]{});
            return new String(Base64.getEncoder().encodeToString(signData));
        } catch (Exception e) {
            throw new RuntimeException("sign 计算异常");
        }
    }

}

章末

       文章到这里就结束了~

往期推荐 > > > 

 【服务器搭建】✈️用自己电脑搭建一个服务器!

 【IDEA】✈️自定义模板,自动生成类和方法注释

 【日志链路】⭐️SpringBoot 整合 TraceId 日志链路追踪!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第 1 章:数字 I/O 与串口通信(GPIO UART)

本章目标: 掌握 GPIO 的硬件原理、寄存器配置与典型驱动框架 深入理解 UART/USART 的帧格式、波特率配置、中断与 DMA 驱动 通过实战案例,将 GPIO 与 UART 结合,实现 AT 命令式外设控制 章节结构 GPIO 概述与硬件原理 GPIO 驱动实现:寄存器、中断与去抖 UART/USART 原理与帧…

【图像生成大模型】Wan2.1:下一代开源大规模视频生成模型

Wan2.1&#xff1a;下一代开源大规模视频生成模型 引言Wan2.1 项目概述核心技术1. 3D 变分自编码器&#xff08;Wan-VAE&#xff09;2. 视频扩散 Transformer&#xff08;Video Diffusion DiT&#xff09;3. 数据处理与清洗 项目运行方式与执行步骤1. 环境准备2. 安装依赖3. 模…

interface接口和defer场景分析

接口 接口这里主要两点&#xff1a; 设计业务结构时采用依赖倒转&#xff1a;业务层向下依赖抽象层&#xff0c;实现层向上依赖抽象层。 相比于之前&#xff1a; 之后&#xff1a; 注意struct中嵌套interface和不嵌套interface的区别&#xff1a; type Myinterface interfac…

调用百度云API机器翻译

新建Python文件&#xff0c;叫 text_translator.py 输入 import requests import jsonAPI_KEY "glYiYVF2dSc7EQ8n78VDRCpa" # 替换为自己的API Key SECRET_KEY "kUlhze8OQZ7xbVRp" # 替换为自己的Secret Keydef main():# 选择翻译方向while True:di…

uni-app学习笔记六-vue3响应式基础

一.使用ref定义响应式变量 在组合式 API 中&#xff0c;推荐使用 ref() 函数来声明响应式状态&#xff0c;ref() 接收参数&#xff0c;并将其包裹在一个带有 .value 属性的 ref 对象中返回 示例代码&#xff1a; <template> <view>{{ num1 }}</view><vi…

『已解决』Python virtualenv_ error_ unrecognized arguments_--wheel-bundle

📣读完这篇文章里你能收获到 🐍 了解 virtualenv 参数错误的原因及解决方案📦 学习如何正确配置 Python 虚拟环境文章目录 前言一、问题描述1.1 错误现象1.2 影响范围二、问题分析2.1 根本原因三、解决方案3.1 兼容处理3.2 完整解决方案四、总结前言 本文详细介绍了在 D…

【Unity 2023 新版InputSystem系统】新版InputSystem 如何进行人物移动(包括配置、代码详细实现过程)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、InputSystem配置二、GameInput 游戏输入脚本1.实现思路2.完整代码三、Player 游戏人物移动脚本1.实现思路2.完整代码四、场景脚本设置1.组件设置五、问题解决1.人物一直下落2.人物跳跃时,…

单片机-STM32部分:13-1、编码器

飞书文档https://x509p6c8to.feishu.cn/wiki/BpEywhaX9iqbiLkdqdAcmDnwnab EC旋转编码器 在产品开发过程中&#xff0c;需要位置闭环的的产品&#xff0c;类似电机类产品来说&#xff0c;编码器至关重要&#xff0c;它不仅可以使我们对带年纪进行精确的速度闭环&#xff0c;位…

关于我在使用stream().toList()遇到的问题

关于我在使用stream().toList()遇到的问题 问题描述 在测试以上程序的时候抛出了空指针异常 于是我以为是我数据库中存在null字段&#xff0c;但查看后发现并不存在为null的数据 问题排查 起初我以为问题出现在sort排序方法这&#xff0c;事实也确实是&#xff0c;当我把s…

多卡跑ollama run deepseek-r1

# 设置环境变量并启动模型 export CUDA_VISIBLE_DEVICES0,1,2,3 export OLLAMA_SCHED_SPREAD1 # 启用多卡负载均衡 ollama run deepseek-r1:32b 若 deepseek-r1:32b 的显存需求未超过单卡容量&#xff08;如单卡 24GB&#xff09;&#xff0c;Ollama 不会自动启用多卡 在run…

基于Java在高德地图面查询检索中使用WGS84坐标的一种方法-以某商场的POI数据检索为例

前言 随着移动互联网的飞速发展&#xff0c;基于位置的服务&#xff08;LBS&#xff09;需求日益增长&#xff0c;越来越多的应用需要从地图中检索特定区域内的地理信息&#xff0c;例如商业场所、公共服务设施等。商场作为城市商业活动的重要载体&#xff0c;其周边的地理信息…

本地部署dify+ragflow+deepseek ,结合小模型实现故障预测,并结合本地知识库和大模型给出维修建议

1.准备工作 使用ollama 拉取deepseek-r1:7b 官网下载ollama ollama run deepseek-r1:7b ollama list Ragflow专注于构建基于检索增强生成&#xff08;RAG&#xff09;的工作流&#xff0c;强调模块化和轻量化&#xff0c;适合处理复杂文档格式和需要高精度检索的场景。Dify…

SECERN AI提出3D生成方法SVAD!单张图像合成超逼真3D Avatar!

SECERN AI提出的3D生成方法SVAD通过视频扩散生成合成训练数据&#xff0c;利用身份保留和图像恢复模块对其进行增强&#xff0c;并利用这些经过优化的数据来训练3DGS虚拟形象。SVAD在新的姿态和视角下保持身份一致性和精细细节方面优于现有最先进&#xff08;SOTA&#xff09;的…

【物联网】 ubantu20.04 搭建L2TP服务器

部署篇 序言 为了是两个客户端在同一个网络内&#xff0c;需要找一台服务器&#xff0c;搭建一个L2TP服务器&#xff0c;通过L2TP使两个客户端在同一个网络内,为什么要搭建&#xff0c;主要是解决例如员工出差后&#xff0c;还需要连接公司内网资源的问题&#xff0c;本文主要…

网络安全深度解析:21种常见网站漏洞及防御指南

一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…

从零启动 Elasticsearch

elastic 有弹力的 ElaticSearch &#xff08;ES&#xff09;是一个基于 Lucene 的分布式全文检索引擎。可以做到近乎实时地存储、检索数据&#xff0c;并且本身具有良好的扩展性&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别&#xff08;1 Petabyte 1024TB&…

Nginx基础知识

Nginx是什么&#xff1f; Nginx 是一款高性能的 Web 服务器、反向代理服务器和负载均衡器&#xff0c;以其高并发处理能力和低内存消耗著称。以下是 Nginx 的基础知识和常见配置示例&#xff1a; 1. 核心概念 • 配置文件位置&#xff1a;通常为 /etc/nginx/nginx.conf 或 /us…

Vue-监听属性

监听属性 简单监听 点击切换名字&#xff0c;来回变更Tom/Jerry&#xff0c;输出 你好&#xff0c;Tom/Jerry 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>监听属性</title><!-- …

python fastapi + react, 写一个图片 app

1. 起因&#xff0c; 目的: 上厕所的时候&#xff0c;想用手机查看电脑上的图片&#xff0c;但是又不想点击下载。此app 应运而生。 2. 先看效果 单击图片&#xff0c;能放大图片 3. 过程: 过程很枯燥。有时候&#xff0c; 有一堆新的想法。 但是做起来太麻烦&#xff0c;…

vscode c++编译onnxruntime cuda 出现的问题

问题描述 将onnx的dll文件和lib文件copy到可执行文件所在文件夹下后&#xff0c;现象&#xff1a; 双击可执行文件能正常运行 在vscode中点击cmake插件的运行按钮出现报错为 c [ONNXRuntimeError] : 1 : FAIL : LoadLibrary failed with error 126 “” when trying to load尝试…