网站项目通过钉钉机器人向钉钉群发送信息

项目使用场景描述

PC网站内填好的数据发送至钉钉群,以钉钉机器人卡片形式发送
样例如图:
网站项目通过钉钉机器人向钉钉群发送信息_第1张图片

开发思路

首先我使用的是vue前端和egg.js后端(基于node.js)
开发思路流程:

  1. 网页内填写数据(表单或者其他都可以)
  2. 将数据整理到一个data里
  3. 将钉钉API相关信息与data一起通过钉钉API接口传过去
  4. 实现功能,钉钉机器人会发送消息

钉钉API简述

要将数据传到钉钉里有一个重要的参数就是access_token
这个参数的获取方法如下:
1. 首先需要有钉钉企业的开发者权限,如果没有需要跟自己企业的钉钉管理员进行申请,没有这个,后续的功能寸步难行。但是可以自己在钉钉建立一个企业组织就权限了,至少测试功能什么的够用了
2. 登录钉钉的开发者后台 钉钉开发者后台 ,登陆后选择有开发者权限的企业,进入页面后在右上角会看到 CorpId 和 API Token ,有权限的是直接可以看到的,没权限的看到的是 ******
无权限如下图
网站项目通过钉钉机器人向钉钉群发送信息_第2张图片
有权限的如下图:
网站项目通过钉钉机器人向钉钉群发送信息_第3张图片
3. 获取appkey和 appsecret
在企业内部开发-钉钉应用里找到应用的appkey和 appsecret,没有应用的话建立一个

4. 通过 appkey和 appsecret 获取 access_token
进入钉钉开发文档,找到获取企业内部应用的access_token的方法介绍,里面有HTTP请求和JAVA SDK的两种方法,其他后端语言在API调试工具里面有方法,我用的是HTTP的方法
将 appkey和 appsecret 两个参数通过GET请求发送过去,会得到一个含有access_token的json

GET https://oapi.dingtalk.com/gettoken?appkey=appkey&appsecret=appsecret

因为某种不知名的原因,我实在后端进行请求的,不过我在后端是发送的HTTP请求
代码如下:

const appkey = '';
const appsecret = '';
const requestPromise = require("request-promise");

// 获取钉钉access_token
const getAccessToken = async (corpid, corpsecret) => {
  const result = await requestPromise({ uri: 'https://oapi.dingtalk.com/gettoken', qs: { appkey, appsecret } });
};
	console.log(result);

网站项目通过钉钉机器人向钉钉群发送信息_第4张图片
后续涉及到钉钉的API基本都需要access_token作为参数传过去
如果使用后端进行调用access_token的话,可以使用钉钉的API在线调试工具
如果是用后端调用需要先下载安装后端对应的钉钉SDK
基本上常用的后端语言都有对应的SDK包

钉钉机器人消息发送

首先,要在企业内有一个钉钉机器人,在这里设置钉钉开放平台-企业内部应用
右侧有机器人选项,设置好之后能够看到钉钉机器人的AppKey 这个是一会要用到的

之后需要有钉钉群的群会话openConversationId,相当于群的唯一ID,通过钉钉API文档 - 中的方法获取openConversationId

还需要有一个钉钉机器人的卡片消息模板(因为我用的是卡片消息)进入到卡面模板页面 创建一个卡片,拿到卡片模板的ID
准备工作做完了,下面就可以发消息了
首先先看下钉钉机器人发消息的API文档
同样有HTTP请求和后端语言的请求方法
我还是在后端用的HTTP请求,后端语言的需要自行下载SDK,并根据API调试工具生成的代码自行调整

async sendCard() {
    const { ctx } = this;
    const { Data, out_track_id, robot_code, card_template_id, open_conversation_id } = ctx.request.body; // 接收前端传来的数据
    let access_token = eval("(" + await getAccessToken() + ")").access_token  // 通过刚才的getAccessToken()获取access_token  
    // 需要将所有的参数一起打包发出去
    let sendval = {
      cardData: JSON.stringify(Data), // 前面说过的,整理好的发送的信息,别忘了用JSON.stringify()转换下格式
      cardBizId: out_track_id,  //  卡片的唯一ID,这个自己编写就行,就是发出来的卡片,后续可以通过这个ID对卡片进行更新等操作
      cardTemplateId: card_template_id,  //  卡片模板的ID
      robotCode: robot_code,  //  机器人的AppKey
      openConversationId: open_conversation_id, // 群会话openConversationId
    }
    try {
     //  将数据通过POST请求发出去,注意access_token要在headers里面
      const result = await requestPromise({
        uri: 'https://api.dingtalk.com/v1.0/im/v1.0/robot/interactiveCards/send',
        method: "POST",
        json: true,
        headers: {
          "x-acs-dingtalk-access-token": access_token,
          "content-type": "application/json",
        },
        body: sendval,
      });
      // console.log(result, 'processQueryKey:');
      ctx.body = { errCode: 0, result };
    } catch (error) {
      console.log(error);
    }
  }

全部完整代码

'use strict';

const Controller = require('egg').Controller;

const appkey = '';
const appsecret = '';
const requestPromise = require("request-promise");


// 获取钉钉access_token
const getAccessToken = async (corpid, corpsecret) => {
  const result = await requestPromise({ uri: 'https://oapi.dingtalk.com/gettoken', qs: { appkey, appsecret } });
  // console.log(result);
  return result
};

class DingtalkController extends Controller {

  async accessToken() {
    const { ctx } = this;
    const { Data, out_track_id, robot_code, card_template_id, open_conversation_id } = ctx.request.body;
    let access_token = eval("(" + await getAccessToken() + ")").access_token
    let sendval = {
      cardData: JSON.stringify(Data),
      cardBizId: out_track_id,
      cardTemplateId: card_template_id,
      robotCode: robot_code,
      openConversationId: open_conversation_id,
    }
    try {
      const result = await requestPromise({
        uri: 'https://api.dingtalk.com/v1.0/im/v1.0/robot/interactiveCards/send',
        method: "POST",
        json: true,
        headers: {
          "x-acs-dingtalk-access-token": access_token,
          "content-type": "application/json",
        },
        body: sendval,
      });
      // console.log(result, 'processQueryKey:');
      ctx.body = { errCode: 0, result };
    } catch (error) {
      console.log(error);
    }
  }


}

module.exports = DingtalkController;

钉钉开发常用网址

  1. 钉钉开发者后台 https://open-dev.dingtalk.com/#/
  2. 钉钉API在线调试工具 https://open-dev.dingtalk.com/apiExplorer#/
  3. 钉钉API开发文档 https://open.dingtalk.com/document/orgapp-server/how-to-call-apis
  4. 钉钉开放平台-企业内部应用https://open-dev.dingtalk.com/fe/app#/corp/app

补充:

部分企业会对自己公司内部的网络做出一定的限制,例如上互联网(例如:浏览百度等)需要使用网络代理的情况,不使用代理只能查看公司内部的局域网络,这种情况钉钉的请求是无法实现的,对于这种情况,在request请求中加入代理即可,可以参考下列示例:

const request = require('request-promise');
const options = {
    uri: 'https://api.dingtalk.com/v1.0/im/v1.0/robot/interactiveCards/send',
    method: 'POST',
    json: true,
    headers: {
        "x-acs-dingtalk-access-token": access_token, 
        "content-type": "application/json",
    },
    body: sendval,
    proxy: 'http://代理地址'
};
 
const result = await request(options);

如果使用钉钉的SDK包,需要找到对应添加代理的位置加入代理,下列示例是python语言的,重点是在util_models.RuntimeOptions中添加代理地址,其他编程语言找到对应的位置添加代理地址即可

import requests
 
from alibabacloud_dingtalk.im_1_0.client import Client as dingtalkim_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dingtalk.im_1_0 import models as dingtalkim__1__0_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
 
res = client.send_interactive_card_with_options(send_interactive_card_request, send_interactive_card_headers,util_models.RuntimeOptions(http_proxy='http://代理地址',https_proxy='http://代理地址'))

你可能感兴趣的:(后端技术,钉钉,机器人)