基于函数计算的钉钉回调函数接口

本文涉及的产品
简介: 由于企业内部管理的需要,用到了钉钉的业务事件回调能力,正好将这个轻量级的接口使用无服务器技术来实现部署,以应对流量无规律下的动态扩展伸缩、按需使用、按量计费等需求。 阿里云函数计算版本 由于公司系统部署在阿里云,首先选择使用阿里云函数计算来实现及部署。

由于企业内部管理的需要,用到了钉钉的业务事件回调能力,正好将这个轻量级的接口使用无服务器技术来实现部署,以应对流量无规律下的动态扩展伸缩、按需使用、按量计费等需求。

阿里云函数计算版本

由于公司系统部署在阿里云,首先选择使用阿里云函数计算来实现及部署。该接口使用了JVM上语言Kotlin开发,虽然阿里云函数计算官方支持的开发语言有Java但没有Kotlin。其实无论Java或Kotlin最终部署文件都是Java Class字节码,加上Kotlin与Java良好的互操作性,实测函数计算可以完美支持Kotlin开发(个人认为任意JVM上的开发语言都是支持的)。

同时该函数使用了表格存储来持久化回调事件。表格存储是个按量计费的分布式存储,有兴趣的可以自行查阅文档了解更多。

该函数通过API网关表格存储触发器来触发。访问日志和执行日志被存储在日志服务中。

函数的本地测试和线上部署,使用了函数计算提供的命令行工具Fun。基于Fun定义的阿里云Serverless模型实现了对函数们使用资源的声明和编排,集成Gitlab CI实现了函数的CI/CD自动化发布流程

不涉及公司业务的代码已开源在Github,有兴趣的可以作为参考。

目前函数计算表格存储有各自的免费配额,在业务量不大的情况下,该服务完全免费。

AWS Lambda版本

AWS Lambda是目前全球使用最为广泛的serverless服务,同时也是函数计算发展方向的引领者。

由于一些个人原因,笔者最近接触了部分AWS服务,同时尝试将钉钉回调函数移植到了AWS Lambda上。阿里云上使用的云服务改为由AWS上对应服务来实现,例如存储使用了DynamoDB,日志使用CloudWatch收集和查询。

本地测试和部署工具,使用的是SAM CLI,持续集成和持续部署使用的是AWS CodeBuildAWS CodePipeline。此外AWS通过AWS CloudFormation提供一种非常强大的能力,可以将AWS上的各种资源通过配置声明的方式来管理(也就是现在非常热门的一个概念--Infrastructure as Code)。AWS CloudFormation会为每次一个或多个资源的变更生成ChangeSet,提供查看对比、版本管理、遇到变更错误整体回退等能力。所以,AWS版本也将该项目的CI/CD部署用到的AWS CodeBuildAWS CodePipelineAmazon DynamoDB等资源通过CloudFormation的配置管理起来。

配置代码段如下,

Description: Create a CodePipeline to include Github source, CodeBuild and Lambda deployment.

Parameters:
  AppBaseName:
    Type: String
    Description: App base name
    Default: dingtalk-callback
  ArtifactStoreS3Location:
    Type: String
    Description: Name of the S3 bucket to store CodePipeline artificat.
  BranchName:
    Description: GitHub branch name
    Type: String
    Default: master
  RepositoryName:
    Description: GitHub repository name
    Type: String
    Default: dingtalk-callback-on-aws
  GitHubOAuthToken:
    Type: String
    NoEcho: true

Resources:
  BuildDingtalkProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name:
        Fn::Sub: ${AppBaseName}-build-${AWS::StackName}
      Description: Build, test, package dingtalk callback project
      ServiceRole:
        Fn::GetAtt: [ CodeBuildRole, Arn ]
      Artifacts:
        Type: S3
        Location:
          Ref: ArtifactStoreS3Location
        Name:
          Fn::Sub: ${AppBaseName}-build-${AWS::StackName}
        NamespaceType: BUILD_ID
        Path: 
          Fn::Sub: ${AppBaseName}/artifacts
        Packaging: NONE
        OverrideArtifactName: true
        EncryptionDisabled: true
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/java:openjdk-11
        PrivilegedMode: false
        ImagePullCredentialsType: CODEBUILD
        EnvironmentVariables:
          - Name: s3_bucket
            Value:
              Ref: ArtifactStoreS3Location
      Source:

  DingtalkCallbackPipeline:
    Type: 'AWS::CodePipeline::Pipeline'
    Properties:
      Name:
        Fn::Sub: ${AppBaseName}-pipeline-${AWS::StackName}
      RoleArn:
        Fn::GetAtt: [ CodePipelineRole, Arn ]
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Version: 1
                Provider: GitHub
              OutputArtifacts:
                - Name: 
                    Fn::Sub: ${AppBaseName}-source-changed
              Configuration:
                Owner: !Ref GitHubOwner
                Repo: !Ref RepositoryName
                Branch: !Ref BranchName
                OAuthToken: !Ref GitHubOAuthToken
                PollForSourceChanges: false
              RunOrder: 1
        - Name: Build
          Actions:
            - Name: Build_Test_Package
              InputArtifacts:
                - Name:
                    Fn::Sub: ${AppBaseName}-source-changed
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              OutputArtifacts:
                - Name: 
                    Fn::Sub: ${AppBaseName}-packaged-yml
              Configuration:
                ProjectName:
                  Ref: BuildDingtalkProject
              RunOrder: 1

AWS版本完整的代码、CloudFormation配置以及部署文档可以通过这里查看。

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
3月前
|
运维 监控 安全
调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
80 0
|
3月前
|
JSON API 数据格式
在钉钉开放平台中,创建或更新OA审批表单模板需要通过API接口进行操作
在钉钉开放平台中,创建或更新OA审批表单模板需要通过API接口进行操作【1月更文挑战第20天】【1月更文挑战第97篇】
45 1
|
3月前
|
JSON API 数据格式
您可以在钉钉开放平台的API文档中找到对应的API接口来创建审批实例
您可以在钉钉开放平台的API文档中找到对应的API接口来创建审批实例【1月更文挑战第20天】【1月更文挑战第96篇】
41 2
|
3月前
|
JSON API 数据格式
您可以在钉钉开放平台的API文档中找到对应的API接口来创建审批实例
您可以在钉钉开放平台的API文档中找到对应的API接口来创建审批实例【1月更文挑战第9天】【1月更文挑战第41篇】
127 2
|
3月前
|
API 开发工具 Python
钉钉有没有获取群消息内容的接口?怎么提工单(bug反馈或技术答疑)?
钉钉有没有获取群消息内容的接口?怎么提工单(bug反馈或技术答疑)?【1月更文挑战第6天】【1月更文挑战第29篇】
110 1
|
4月前
|
JSON API 开发者
钉钉如何调用「创建钉钉待办任务」接口?
钉钉如何调用「创建钉钉待办任务」接口?
130 0
|
4月前
|
DataWorks API 开发工具
dataworks 调用 钉钉接口?
dataworks 调用 钉钉接口?
64 7
|
4月前
|
Java
钉钉第三方扫码登录提示 code: 403, 没有调用该接口的权限,接口权限申请参考
钉钉第三方扫码登录提示 code: 403, 没有调用该接口的权限,接口权限申请参考 ,但是我明明申请了Contact.User.Read 这个权限
177 1
|
3月前
|
JSON 机器人 数据安全/隐私保护
钉钉中,如何获取机器人发送群聊消息接口返回的加密消息id(processQueryKey)?
钉钉中,如何获取机器人发送群聊消息接口返回的加密消息id(processQueryKey)?【1月更文挑战第5天】【1月更文挑战第24篇】
58 5
钉钉审批实例提交接口 按照文档格式传值后提示value为必填值
我已经按照文档格式填写了value也有值,还是报错"message": "value is mandatory for this action."

热门文章

最新文章