钉钉机器人开发实战:快速实现消息通知自动化

一、创建最简单的机器人

步骤 1:创建钉钉群聊**

  1. 打开钉钉应用,进入工作台。
  2. 点击左上角的「+」号,选择「创建群聊」。
  3. 填写群聊名称,选择群聊类型(如部门群、项目群等),然后点击「创建」。

步骤 2:进入群聊设置

  1. 在群聊中,点击右上角的「群聊设置」图标。
  2. 在群聊设置页面,选择「智能群助手」。

步骤 3:添加机器人

  1. 在「智能群助手」页面,点击「添加机器人」。
  2. 在机器人列表中,选择「自定义机器人」。
  3. 填写机器人名称,选择应用权限(如仅限群内成员使用),然后点击「完成」。

步骤 4:配置机器人安全设置

  1. 在机器人详情页面,点击「安全设置」。
  2. 根据需要配置以下选项:
    • 关键词:设置机器人只能在消息中包含特定关键词时才会响应。
    • IP 限制:设置允许机器人接收消息的 IP 地址范围。
    • 签名:设置机器人消息的签名,用于验证消息来源。
  3. 配置完成后,点击「保存」。

步骤 5:获取机器人 Webhook 地址

  1. 在机器人详情页面,点击「Webhook 地址」。
  2. 复制机器人 Webhook 地址,用于后续的 API 调用。

步骤 6:测试机器人

  1. 使用机器人 Webhook 地址,发送测试消息到群聊中。
  2. 检查机器人是否能够正常接收和响应消息。

以上步骤即可完成钉钉群机器人的添加和配置。

机器人发送统一通知代码

python 复制代码
import requests
import json

# 钉钉机器人的 Webhook URL
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=4a10d9366a8eb63e7c795cdec00cb5bf39f2617d986faa6b9b16d9bf16c5d023'

# 请求头
headers = {'Content-Type': 'application/json'}
content='今晚送试车台所有设备进行计量。'
# 消息内容
text = {
    'msgtype': 'text',
    'text': {
        'content': f'通知:{content}'
    }
}

# 发送 POST 请求
response = requests.post(url=webhook, headers=headers, data=json.dumps(text))

# 打印响应结果
print(response.status_code)
print(response.text)

@指定人发送消息代码

python 复制代码
import requests
import json

# 钉钉机器人的 Webhook URL
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=4a10d9366a8eb63e7c795cdec00cb5bf39f2617d986faa6b9b16d9bf16c5d023'

# 请求头
headers = {'Content-Type': 'application/json'}

# 定义消息内容和被@的人(手机号码)
content = '今晚送试车台所有设备进行计量。'
at_mobiles = ['15367870527']  # 被@人的手机号码

# 消息内容
text = {
    'msgtype': 'text',
    'text': {
        'content': f'通知:{content} @15367870527'  # 在消息内容中添加@符号和手机号
    },
    'at': {
        'atMobiles': at_mobiles,  # 被@人的手机号列表
        'isAtAll': False  # 是否@所有人
    }
}

# 发送 POST 请求
response = requests.post(url=webhook, headers=headers, data=json.dumps(text))

# 打印响应结果
print(response.status_code)
print(response.text)

@所有人发送消息代码

python 复制代码
import requests
import json

# 钉钉机器人的 Webhook URL
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=4a10d9366a8eb63e7c795cdec00cb5bf39f2617d986faa6b9b16d9bf16c5d023'

# 请求头
headers = {'Content-Type': 'application/json'}

# 定义消息内容和被@的人(手机号码)
content = '今晚送试车台所有设备进行计量。'


# 消息内容
text = {
    'msgtype': 'text',
    'text': {
        'content': f'通知:{content} '  # 在消息内容中添加@符号和手机号
    },
    'at': {

        'isAtAll': True  # 是否@所有人
    }
}

# 发送 POST 请求
response = requests.post(url=webhook, headers=headers, data=json.dumps(text))

# 打印响应结果
print(response.status_code)
print(response.text)

根据时间运行某函数代码

python 复制代码
import datetime
import time
def run_function_at_target_time(target_time_str, function):
    # 将目标时间字符串转换为 datetime 对象
    target_time = datetime.datetime.strptime(target_time_str, "%Y-%m-%d %H:%M:%S")

    while True:
        # 获取当前时间
        current_time = datetime.datetime.now()

        # 检查当前时间是否等于目标时间
        if current_time >= target_time:
            function()
            break

        # 暂停 1 秒后再次检查
        time.sleep(1)


def output_1():
    print(1)


# 定义目标时间(这里以 2025 年 2 月 18 日 9 点 20 分为例)
target_time_str = "2025-02-18 09:22:00"

# 调用函数,等待目标时间并运行指定函数
run_function_at_target_time(target_time_str, output_1)

带颜色的md消息

python 复制代码
import requests
import json

# 钉钉机器人的 Webhook URL
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=4a10d9366a8eb63e7c795cdec00cb5bf39f2617d986faa6b9b16d9bf16c5d023'

# 请求头
headers = {'Content-Type': 'application/json'}

# 定义消息内容和被@的人(手机号码)
content = '今晚送试车台所有设备进行计量。'
at_mobiles = ['15367870527']  # 被@人的手机号码

# 消息内容(富文本格式)
text = {
    'msgtype': 'markdown',
    'markdown': {
        'title': '通知:',
        'text': f'<font color="#FF0000">**通知:**</font>\n\n<font color="#0000FF">{content}</font>\n\n@{at_mobiles[0]}'
    },
    'at': {
        'atMobiles': at_mobiles,  # 被@人的手机号列表
        'isAtAll': False  # 是否@所有人
    }
}

# 发送 POST 请求
response = requests.post(url=webhook, headers=headers, data=json.dumps(text))

# 打印响应结果
print(response.status_code)
print(response.text)

二、企业应用机器人:API机器人

1.创建企业内部应用机器人

特别需要注意机器人的权限设置需要开启,需要向企业管理员获取开发者权限。

以下是将您提供的链接内容整理成Markdown格式的文档:


2.如何获取钉钉群聊的 chatid(群聊已存在的情况下)

(1)步骤概述

在开发钉钉相关应用时,获取已存在的钉钉群聊的 chatid 是一个常见需求。以下是详细步骤:

(2)操作步骤

1. 获取 CorpId
  • 登录钉钉开发者后台。
  • 在开发者后台的 "企业信息" 页面,找到并复制 CorpId
2. 使用 API 调试工具
  • 打开钉钉的 API Explorer
  • 在 API Explorer 页面,找到 "群会话" 相关接口。
  • 将第一步复制的 CorpId 粘贴到接口的 CorpId 参数中。
  • 点击 "发送调用",此时会生成一个二维码。
3. 扫码授权
  • 使用钉钉扫码工具扫描生成的二维码。
  • 扫码成功后,再次点击 "发送调用"
4. 选择群会话
  • 钉钉会提示选择一个群会话。
  • 选择目标群聊后,接口会返回该群聊的 chatid

3.注意事项

  • 确保在开发过程中,钉钉账户具有足够的权限。
  • chatid 是群聊的唯一标识,用于后续的群消息发送、群管理等操作。

以上是获取钉钉群聊 chatid 的详细步骤,希望对您有所帮助。

向指定群发送文件基础脚本

python 复制代码
import requests
import json
import os

# 钉钉应用的 App Key 和 App Secret
APP_KEY = "dingltflzz1cgbrr3wsm"  # 替换为你的 AppKey
APP_SECRET = "cYTn6qTOhvbgvJ13JGA_Y9Fbs2Cm8DzV1JQLPjAc2SMhxYh7z2TEqK2CC_T-GBtW"  # 替换为你的 AppSecret

# 获取 Access Token
def get_access_token(app_key, app_secret):
    url = "https://oapi.dingtalk.com/gettoken"
    params = {
        "appkey": app_key,
        "appsecret": app_secret
    }
    response = requests.get(url, params=params)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("access_token")
        else:
            raise Exception(f"Failed to get access token: {result.get('errmsg')}")
    else:
        raise Exception(f"Failed to get access token: HTTP {response.status_code}, {response.text}")

# 获取群聊成员列表
def get_chat_members(access_token, chat_id):
    url = "https://oapi.dingtalk.com/chat/get"
    params = {
        "access_token": access_token,
        "chatid": chat_id
    }
    response = requests.get(url, params=params)
    print(f"群聊API完整响应: {response.text}")  # 调试信息
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            # 返回群成员的userid列表
            return result.get("chat_info", {}).get("useridlist", [])
        else:
            raise Exception(f"Failed to get chat members: {result.get('errmsg')}")
    else:
        raise Exception(f"Failed to get chat members: HTTP {response.status_code}, {response.text}")

# 上传文件到钉钉服务器
def upload_file(access_token, file_path):
    if not os.path.exists(file_path):
        raise Exception(f"File not found: {file_path}")

    url = f"https://oapi.dingtalk.com/media/upload?access_token={access_token}&type=file"
    files = {
        "media": open(file_path, "rb")
    }
    response = requests.post(url, files=files)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("media_id")
        else:
            raise Exception(f"Failed to upload file: {result.get('errmsg')}")
    else:
        raise Exception(f"Failed to upload file: HTTP {response.status_code}, {response.text}")

# 发送文件消息到小群聊
def send_file_message_to_chat(access_token, chat_id, agent_id, media_id, user_id):
    url = "https://oapi.dingtalk.com/chat/send"
    params = {
        "access_token": access_token
    }
    headers = {
        "Content-Type": "application/json"
    }
    payload = {
        "chatid": chat_id,  # 群聊ID
        "msg": {
            "msgtype": "file",
            "file": {
                "media_id": media_id
            }
        }
    }
    response = requests.post(url, params=params, headers=headers, data=json.dumps(payload))
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result
        else:
            raise Exception(f"Failed to send file message: {result.get('errmsg')}")
    else:
        raise Exception(f"Failed to send file message to chat: {response.text}")

# 主程序
if __name__ == "__main__":
    try:
        # 获取 Access Token
        access_token = get_access_token(APP_KEY, APP_SECRET)
        print(f"Access Token: {access_token}")

        # 参数配置
        chat_id = "chatff759538dda3afa4222d9e43f79f19ea"  # 替换为实际的小群聊ID
        agent_id = "3435777894"  # 替换为实际应用ID,确保是一个长整数类型的字符串
        file_path = r"C:\Users\11255\Desktop\测试文件.docx"  # 替换为实际文件路径

        # 检查文件是否存在
        if not os.path.exists(file_path):
            raise Exception(f"File not found: {file_path}")

        # 获取群聊成员列表
        print(f"正在获取群聊 {chat_id} 的成员列表...")
        members = get_chat_members(access_token, chat_id)
        print(f"API返回的群成员列表: {members}")
        if not members:
            raise Exception("Chat has no members")

        # 上传文件并获取 media_id
        media_id = upload_file(access_token, file_path)
        # 发送文件消息到小群聊
        result = send_file_message_to_chat(access_token, chat_id, agent_id, media_id, None)
        print(f"Result: {result}")
    except Exception as e:
        print(f"Error: {e}")

钉钉消息发送的整合优化代码

python 复制代码
import requests
import json
import os
import argparse
import sys

# 钉钉应用的 App Key 和 App Secret
APP_KEY = "dingltflzz1cgbrr3wsm"
APP_SECRET = "cYTn6qTOhvbgvJ13JGA_Y9Fbs2Cm8DzV1JQLPjAc2SMhxYh7z2TEqK2CC_T-GBtW"
CHAT_ID = "chatff759538dda3afa4222d9e43f79f19ea"


def format_text(text, color=None, bold=False):
    """
    格式化文本,支持颜色和加粗
    :param text: 原始文本
    :param color: 颜色(支持:red, blue, green, yellow)
    :param bold: 是否加粗
    :return: 格式化后的markdown文本
    """
    if bold:
        text = f"**{text}**"
    if color:
        color_map = {
            'red': '#FF0000',
            'blue': '#0000FF',
            'green': '#00FF00',
            'yellow': '#FFFF00'
        }
        hex_color = color_map.get(color.lower(), color)
        text = f'<font color="{hex_color}">{text}</font>'
    return text


def get_access_token(app_key, app_secret):
    url = "https://oapi.dingtalk.com/gettoken"
    params = {
        "appkey": app_key,
        "appsecret": app_secret
    }
    response = requests.get(url, params=params)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("access_token")
        else:
            raise Exception(f"获取access_token失败: {result.get('errmsg')}")
    else:
        raise Exception(f"获取access_token失败: HTTP {response.status_code}, {response.text}")


def get_chat_members(access_token, chat_id):
    url = "https://oapi.dingtalk.com/chat/get"
    params = {
        "access_token": access_token,
        "chatid": chat_id
    }
    response = requests.get(url, params=params)
    print(f"群聊API响应: {response.text}")
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("chat_info", {}).get("useridlist", [])
        else:
            raise Exception(f"获取群成员失败: {result.get('errmsg')}")
    else:
        raise Exception(f"获取群成员失败: HTTP {response.status_code}, {response.text}")


def upload_file(access_token, file_path):
    if not os.path.exists(file_path):
        raise Exception(f"文件不存在: {file_path}")

    url = f"https://oapi.dingtalk.com/media/upload?access_token={access_token}&type=file"
    files = {
        "media": open(file_path, "rb")
    }
    response = requests.post(url, files=files)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("media_id")
        else:
            raise Exception(f"上传文件失败: {result.get('errmsg')}")
    else:
        raise Exception(f"上传文件失败: HTTP {response.status_code}, {response.text}")


def send_message(text=None, file_path=None, color=None, bold=False, chat_id=CHAT_ID):
    """
    发送消息到钉钉群聊
    :param text: 文本消息内容(可选)
    :param file_path: 文件路径(可选)
    :param color: 文本颜色(可选)
    :param bold: 是否加粗(可选)
    :param chat_id: 群聊ID(可选,默认使用预设值)
    :return: 发送结果
    """
    if not text and not file_path:
        raise ValueError("文本消息和文件至少需要提供一个")

    try:
        access_token = get_access_token(APP_KEY, APP_SECRET)
        url = "https://oapi.dingtalk.com/chat/send"
        params = {
            "access_token": access_token
        }
        headers = {
            "Content-Type": "application/json"
        }

        results = []

        # 发送文本消息
        if text:
            formatted_text = format_text(text, color, bold)
            text_payload = {
                "chatid": chat_id,
                "msg": {
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "通知",
                        "text": formatted_text
                    }
                }
            }
            response = requests.post(url, params=params, headers=headers, data=json.dumps(text_payload))
            results.append(("文本消息", response.json()))

        # 发送文件
        if file_path:
            media_id = upload_file(access_token, file_path)
            file_payload = {
                "chatid": chat_id,
                "msg": {
                    "msgtype": "file",
                    "file": {
                        "media_id": media_id
                    }
                }
            }
            response = requests.post(url, params=params, headers=headers, data=json.dumps(file_payload))
            results.append(("文件消息", response.json()))

        return results

    except Exception as e:
        print(f"发送失败: {str(e)}")
        return None


def main():
    parser = argparse.ArgumentParser(description='发送钉钉消息和文件')
    parser.add_argument('-t', '--text', help='要发送的文本消息')
    parser.add_argument('-f', '--file', help='要发送的文件路径')
    parser.add_argument('-c', '--color', help='文本颜色 (red/blue/green/yellow 或 十六进制颜色码)')
    parser.add_argument('-b', '--bold', action='store_true', help='是否加粗文本')

    args = parser.parse_args()

    if not args.text and not args.file:
        parser.print_help()
        sys.exit(1)

    results = send_message(
        text=args.text,
        file_path=args.file,
        color=args.color,
        bold=args.bold
    )

    if results:
        for msg_type, result in results:
            print(f"\n{msg_type}发送结果: {result}")


if __name__ == "__main__":
    main()

引用发动消息的代码示例

python 复制代码
import requests
import json
import os
import argparse
import sys

# 钉钉应用的 App Key 和 App Secret
APP_KEY = "dingltflzz1cgbrr3wsm"
APP_SECRET = "cYTn6qTOhvbgvJ13JGA_Y9Fbs2Cm8DzV1JQLPjAc2SMhxYh7z2TEqK2CC_T-GBtW"
CHAT_ID = "chatff759538dda3afa4222d9e43f79f19ea"


def format_text(text, color=None, bold=False):
    """
    格式化文本,支持颜色和加粗
    :param text: 原始文本
    :param color: 颜色(支持:red, blue, green, yellow)
    :param bold: 是否加粗
    :return: 格式化后的markdown文本
    """
    if bold:
        text = f"**{text}**"
    if color:
        color_map = {
            'red': '#FF0000',
            'blue': '#0000FF',
            'green': '#00FF00',
            'yellow': '#FFFF00'
        }
        hex_color = color_map.get(color.lower(), color)
        text = f'<font color="{hex_color}">{text}</font>'
    return text


def get_access_token(app_key, app_secret):
    url = "https://oapi.dingtalk.com/gettoken"
    params = {
        "appkey": app_key,
        "appsecret": app_secret
    }
    response = requests.get(url, params=params)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("access_token")
        else:
            raise Exception(f"获取access_token失败: {result.get('errmsg')}")
    else:
        raise Exception(f"获取access_token失败: HTTP {response.status_code}, {response.text}")


def get_chat_members(access_token, chat_id):
    url = "https://oapi.dingtalk.com/chat/get"
    params = {
        "access_token": access_token,
        "chatid": chat_id
    }
    response = requests.get(url, params=params)
    print(f"群聊API响应: {response.text}")
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("chat_info", {}).get("useridlist", [])
        else:
            raise Exception(f"获取群成员失败: {result.get('errmsg')}")
    else:
        raise Exception(f"获取群成员失败: HTTP {response.status_code}, {response.text}")


def upload_file(access_token, file_path):
    if not os.path.exists(file_path):
        raise Exception(f"文件不存在: {file_path}")

    url = f"https://oapi.dingtalk.com/media/upload?access_token={access_token}&type=file"
    files = {
        "media": open(file_path, "rb")
    }
    response = requests.post(url, files=files)
    if response.status_code == 200:
        result = response.json()
        if result.get("errcode") == 0:
            return result.get("media_id")
        else:
            raise Exception(f"上传文件失败: {result.get('errmsg')}")
    else:
        raise Exception(f"上传文件失败: HTTP {response.status_code}, {response.text}")


def send_message(text=None, file_path=None, color=None, bold=False, chat_id=CHAT_ID):
    """
    发送消息到钉钉群聊
    :param text: 文本消息内容(可选)
    :param file_path: 文件路径(可选)
    :param color: 文本颜色(可选)
    :param bold: 是否加粗(可选)
    :param chat_id: 群聊ID(可选,默认使用预设值)
    :return: 发送结果
    """
    if not text and not file_path:
        raise ValueError("文本消息和文件至少需要提供一个")

    try:
        access_token = get_access_token(APP_KEY, APP_SECRET)
        url = "https://oapi.dingtalk.com/chat/send"
        params = {
            "access_token": access_token
        }
        headers = {
            "Content-Type": "application/json"
        }

        results = []

        # 发送文本消息
        if text:
            formatted_text = format_text(text, color, bold)
            text_payload = {
                "chatid": chat_id,
                "msg": {
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "通知",
                        "text": formatted_text
                    }
                }
            }
            response = requests.post(url, params=params, headers=headers, data=json.dumps(text_payload))
            results.append(("文本消息", response.json()))

        # 发送文件
        if file_path:
            media_id = upload_file(access_token, file_path)
            file_payload = {
                "chatid": chat_id,
                "msg": {
                    "msgtype": "file",
                    "file": {
                        "media_id": media_id
                    }
                }
            }
            response = requests.post(url, params=params, headers=headers, data=json.dumps(file_payload))
            results.append(("文件消息", response.json()))

        return results

    except Exception as e:
        print(f"发送失败: {str(e)}")
        return None


def main():
    parser = argparse.ArgumentParser(description='发送钉钉消息和文件')
    parser.add_argument('-t', '--text', help='要发送的文本消息')
    parser.add_argument('-f', '--file', help='要发送的文件路径')
    parser.add_argument('-c', '--color', help='文本颜色 (red/blue/green/yellow 或 十六进制颜色码)')
    parser.add_argument('-b', '--bold', action='store_true', help='是否加粗文本')

    args = parser.parse_args()

    if not args.text and not args.file:
        parser.print_help()
        sys.exit(1)

    results = send_message(
        text=args.text,
        file_path=args.file,
        color=args.color,
        bold=args.bold
    )

    if results:
        for msg_type, result in results:
            print(f"\n{msg_type}发送结果: {result}")


if __name__ == "__main__":
    main()
相关推荐
A~taoker2 小时前
jmeter接口自动化+ant执行(方案)
运维·jmeter·自动化
遇见火星4 小时前
自动化发布工具CI/CD实践Jenkins部署与配置教程
servlet·ci/cd·自动化·jenkins·自动化发布
遇见火星5 小时前
自动化发布工具CI/CD实践Jenkins各配置功能介绍和管理!
ci/cd·自动化·jenkins·自动化发布
eqwaak06 小时前
京东商品爬虫技术解析:基于Selenium的自动化数据采集实战
开发语言·人工智能·爬虫·python·selenium·自动化
天天讯通7 小时前
语音机器人与智能体结合
机器人
ZHOU_WUYI8 小时前
browser-use 库网页自动化截图
python·自动化·agent
杜子腾dd9 小时前
5.Matplotlib:高级绘图
大数据·python·信息可视化·自动化·matplotlib·数据可视化
一只栖枝9 小时前
RHCA核心课程技术解析4:红帽服务管理与自动化深度实践
linux·运维·自动化·rhca·红帽认证
PyAIGCMaster10 小时前
手搓全自动文章多平台发布系统:8、自动化脚本的测试。
运维·数据库·自动化
一禅(OneZen)11 小时前
【L2.第二章】Appium 元素定位工具
python·selenium·appium·自动化·web