# 前言

这里介绍如何使用 IM 模板创建插件

# 接入效果

以飞书应用为例:

# 接入流程

# 创建 TAPD 托管应用

在开发平台中选择 IM NodeJs Vue 模板插件来创建应用 创建应用

# 下载代码及授权验证

在应用概览中选择代码仓库并下载 下载代码

安装并使用 tplugin-cli 进行 Oauth 授权,参考【快速入门】实现 授权验证

# TAPD 服务集成

使用tplugin-cli serve命令启动模板插件应用,在【公司管理-开放集成-服务集成】中对插件进行管理 服务集成

# 扩展能力

IM 模板中提供了以下能力:

  • 同步组织成员
  • 消息通知
  • 一键拉群
  • 自动化助手

总体流程如图所示 流程图

# 同步组织成员

# 挂载点

app:
  modules:
    im:
      adapter:
        sync_organization: organization.sync
1
2
3
4
5

# 能力实现

用户可以对organization.js文件中的sync方法进行重写来实现同步组织成员能力,sync方法主要包含以下流程:

  1. 配置挂载点,在sync_organization中定义挂载方法
  2. 接收并解析data参数,获得协作空间相关信息,如workspace_id
  3. 同步部门、人员相关信息至 TAPD,需要的相关 API 如下
    • tapdSdk.getOrganizations:获取组织信息
    • tapdSdk.addOrganization:增加组织信息
    • tapdSdk.addRole:增加用户组
    • tapdSdk.addUser:增加用户
    • tapdSdk.updateUserOrganization:更新用户所属组织

data参数的结构如下

{
  "workspace_id": "33564059",
  "current_user": {
    "id": "33651030",
    "nick": "nick",
    "name": "test",
    "name_pinyin": ""
  },
  "data": {
    "app_code": "tapd-app-60cc74",
    "handler": "organization.sync",
    "body": {
      "params": {
        "workspace_id": "33564059",
        "app_code": "tapd-app-60cc74",
        "app_version": "dev-tapd-app"
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

syncuserGroup.syncUserGroups等方法的具体逻辑都可以在organization.js文件中进行自定义 定义数据 用户组示例

# 使用示例

在【公司管理-成员管理】中,可以使用 IM 同步成员 同步成员

# 消息通知

# 挂载点

app:
  modules:
    im:
      adapter:
        send_at_user_msg: inform.sendAtUserMsg
        send_msg: inform.sendMsg
1
2
3
4
5
6

# 能力实现

用户可以对inform.js文件中的sendMsgsendAtUserMsg方法进行重写来实现消息通知能力,目前插件中只进行了打印操作

  1. 配置挂载点,在send_msgsendAtUserMsg中定义挂载方法
  2. 接收并解析data参数,获得 TAPD 中的相关消息
  3. 根据具体业务对消息进行处理

sendAtUserMsg方法为例,data参数的结构如下

{
    "workspace_id": "66229999",
    "current_user": {
        "id": "810118533",
        "nick": "nick",
        "name_pinyin": "",
        "enabled": "1",
        "status_name": "",
        "current_company_id": "58082844",
        "group_id": "0",
        "group_name": "",
        "group_names": "",
        "post_name": ""
    },
    "data": {
        "app_code": "tapd-app-42cb4c",
        "handler": "inform.sendAtUserMsg",
        "third_auth": [
        ],
        "body": {
            "receivers": [
                {
                    "user_id": "1438132993",
                    "user": "mooret"
                }
            ],
            "params": {
                "workspace_name": "欢迎使用TAPD DEMO",
                "workitem_name": "父需求2:解决研发痛点,打造最懂项目管理的产品",
                "entity_type": "Story",
                "url": "*",
                "operation_type": "COMMENT_AT",
                "comment": "@mooret()",
                "at_users": [
                    "mooret"
                ],
                "workspace_id": "66229999",
                "company_id": "58082844"
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

sendMsgsendAtUserMsg方法的具体逻辑都可以在inform.js文件中进行自定义 消息处理

# 使用示例

在【项目协作-项目设置-消息与报告】中,可以配置接收通知事件 消息通知

同时,在任意工作项中,@用户时也会向 IM 侧对应的用户发送消息 @用户

# 一键拉群

# 挂载点

app:
  modules:
    im:
      adapter:
        chat_info: group_chat.getChatInfo
        create_group_and_send_msg: group_chat.createGroupAndSendMsg
1
2
3
4
5
6

# 能力实现

用户可以对group_chat.js文件中createGroupAndSendMsg方法进行重写来实现一键拉群能力,主要包含以下流程:

  1. 配置挂载点,在chat_infocreate_group_and_send_msg中定义挂载方法
  2. 接收并解析data参数,获取拉群信息
  3. 检测群聊是否存在
  4. 创建群聊并存储群聊信息

getChatInfo方法用于获取群聊信息

data参数的结构如下

{
    "workspace_id": "66229999",
    "current_user": {
        "id": "810118533",
        "nick": "test",
        "name_pinyin": "",
        "enabled": "1",
        "status_name": "",
        "current_company_id": "58082844",
        "group_id": "0",
        "group_name": "",
        "group_names": "",
        "post_name": ""
    },
    "data": {
        "app_code": "tapd-app-42cb4c",
        "handler": "group_chat.createGroupAndSendMsg",
        "third_auth": [

        ],
        "body": {
            "entity_id": "1166229999001000003",
            "entity_type": "story",
            "title": "【TAPD】父需求3:协作联通能力强化 + DevOps 全流程支撑讨论群",
            "tapd_users": [
                "810118533",
                "1438132993",
                "862848823"
            ],
            "workspace_id": "66229999",
            "setting": {
                "is_subscribe": true,
                "is_subscribe_related": false,
                "is_subscribe_sub": false,
                "all_sub_story_member": false,
                "all_relate_story_member": false,
                "subscribe_objects": "",
                "enable_subscribe_objects": false
            },
            "card_title": "test 邀请你参加需求讨论",
            "content": "父需求3:协作联通能力强化 + DevOps 全流程支撑",
            "url": "*",
            "owner": "810118533",
            "current_company_id": "58082844"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

getChatInfocreateGroupAndSendMsg方法的具体逻辑都可以在group_chat.js文件中进行自定义 拉群业务

# 使用示例

在任意工作项中,可以点击 IM 插件应用进行一键拉群 一键拉群

# 自动化助手

# 挂载点

app:
  modules:
    autotasks:
      - code: im
        executors:
          actions:
            - code: im::send_group_message
              desc: 群消息提醒
              exec:
                handler: handler.update
              icon: business
              name: 群消息提醒
              option:
                handler: options.option
              related:
                - story::*
                - bug::*
                - task::*
                - iteration::*
        icon: business
        name: im
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

自动化配置参考【自动化助手-配置文件示例】实现

# 能力实现

IM 模板插件中,主要需要对 Executor 进行配置,具体可以参考【自动化助手-Executor 配置】实现

  • 候选值部分在options.js中的options.option方法中进行配置
  • 执行器部分在handler.js中的handler.update方法中进行配置

options.js文件和options.option方法接收的 JSON 数据如下所示 配置候选值

{
    "nick": "nick",
    "workspace_id": "66229999",
    "company_id": "58082844",
    "object_code": "tapd-app-tapd-app-42cb4c_im",
    "trigger_object_name": "merge_story",
    "trigger_object_event": "merge_story::status_change",
    "trigger_config": {
        "obj_key": "merge_story",
        "obj_name": "需求",
        "obj_code": "merge_story",
        "obj_sub_code": "",
        "freeze": "0",
        "data": [
            {
                "value": "merge_story::status_change",
                "key": "event",
                "name": "状态流转",
                "freeze": "0",
                "operator": "single_in",
                "label": "请选择事件"
            },
            {
                "value": "all",
                "key": "workitem_type_id",
                "name": "所有类别",
                "freeze": "0",
                "operator": "multi_in",
                "label": "请选择需求类别"
            },
            {
                "value": "resolved",
                "key": "event.status:fromto:from",
                "name": "已实现",
                "freeze": "0",
                "operator": "single_in",
                "label": "流转前状态"
            },
            {
                "value": "planning",
                "key": "event.status:fromto:to",
                "name": "规划中",
                "freeze": "0",
                "operator": "multi_in",
                "label": "流转至状态"
            }
        ]
    },
    "trigger_obj_type_id": "0"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

handler.js文件和handler.update方法接收的 JSON 数据如下所示 执行规则

{
    "auto_task_id": "1166229999001000001",
    "workspace_id": "66229999",
    "object_code": "tapd-app-tapd-app-42cb4c_im",
    "auto_task_action_id": "1166229999001000001",
    "action_index": "0",
    "branch_id": "1166229999001000001",
    "events": {
        "story::status_change": {
            "workspace_id": "66229999",
            "user": "user",
            "object_type": "story",
            "id": "1166229999001000016",
            "timestamp": "1723111770",
            "timestamp_micro": "1723111771066",
            "zone": "66229999",
            "new": {
                "completed": null,
                "id": "1166229999001000016",
                "modified": "2024-08-08 18:09:30",
                "status": "planning"
            },
            "old": {
                "completed": "2024-08-08 18:08:51",
                "id": "1166229999001000016",
                "modified": "2024-08-08 18:08:51",
                "status": "resolved"
            },
            "object_info": {
                "ancestor_id": "1166229999001000016",
                "app_id": "1",
                "attachment_count": "0",
                "begin": null,
                "bug_id": null,
                "business_value": null,
                "category_id": "1166229999001000003",
                "cc": "",
                "children_id": "|",
                "completed": null,
                "confidential": "N",
                "created": "2024-07-27 12:37:44",
                "created_from": null,
                "creator": "TAPD",
                "delay_count": null,
                "description": "TAPD为各类型的企业提供覆盖业务、产品、设计、开发、测试、发布全生命周期的敏捷实践和过程管理落地能力,通过模块化组合,可插拔扩展,轻松搭建满足团队需要的专业组合方案,帮助企业打造全方位业务敏捷团队。",
                "id": "1166229999001000016",
                "name": "需求1:欢迎来到 TAPD ,敏捷协作创造新的可能!",
                "owner": "mooret;",
                "participator": ";test;mooret",
                "path": "1166229999001000016:",
                "priority": "High",
                "release_id": "1166229999001000001",
                "workitem_id": null,
                "workitem_type_id": "1166229999001000001",
                "workspace_id": "66229999"
            },
            "event_type": "",
            "event_key": "story::status_change",
            "event_identity": "story::status_change|1166229999001000001",
            "from": "web",
            "event_flow": null,
            "auto_task_event_times": "0",
            "auto_task_start_time": "0",
            "parent_event_id": "",
            "default_case_long_id": "",
            "case_id": "0",
            "event_id": "ed4071262a52eb755f76014ded45c204_tdjob_141-1723111760_33_6d24875e5c23",
            "action_result": {
                "code": "0",
                "msg": "",
                "data": null
            },
            "tapd_object_id_list": null,
            "event_task_id": "0"
        }
    },
    "actions": [
    ],
    "start_event": "story::status_change",
    "case_long_id": "4dc11a8b-556e-11ef-84c4-9ed780bf2108",
    "case_id": "59953235",
    "event_task_id": "0",
    "search_branches": [
        "1166229999001000001"
    ],
    "company_id": "58082844",
    "nick": "nick",
    "creator": "creator",
    "event": "tapd-app-tapd-app-42cb4c_im::im::send_group_message",
    "field": "fieldA",
    "fieldVal": "2",
    "executor_config": {
        "event": "tapd-app-tapd-app-42cb4c_im::im::send_group_message",
        "field": "fieldA",
        "fieldVal": "2"
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

# 使用示例

在【项目协作-项目设置-自动化助手】中创建自动化规则 创建自动化规则

自动化助手中可以选择 IM 应用进行消息提醒 自动化助手

选择群消息提醒后,修改字段为options.js文件中options.option方法配置的字段 显示字段

# 插件工程目录示例

├── handler
│   ├── config.js
│   └── hello.js
├── index.js
├── Makefile
├── modules
│   ├── autotasks
│   │   ├── handler.js
│   │   └── options.js
│   ├── im
│   │   ├── group_chat.js
│   │   ├── inform.js
│   │   ├── organization
│   │   │   ├── department.js
│   │   │   ├── user_group.js
│   │   │   └── user.js
│   │   ├── organization.js
│   │   └── storage
│   │       ├── config.js
│   │       ├── organization
│   │       │   ├── department_relation.js
│   │       │   ├── organization_sync_log.js
│   │       │   ├── user_group_relation.js
│   │       │   ├── user_group_settings.js
│   │       │   └── user_relation.js
│   │       └── storage.js
│   └── webhooks
│       └── inform_events.js
├── package.json
├── plugin.yaml
├── resources
│   └── pages
│       ├── app_for_global_config
│       │   ├── feishu.vue
│       │   └── index.css
│       ├── app_for_global_config.js
│       └── index.html
├── utils.js
└── webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# plugin.yaml 示例

app:
  code: tapd-app-42cb4c
  desc: im demo
  modules:
    autotasks:
      - code: im
        executors:
          actions:
            - code: im::send_group_message
              desc: 群消息提醒
              exec:
                handler: handler.update
              icon: business
              name: 群消息提醒
              option:
                handler: options.option
              related:
                - story::*
                - bug::*
                - task::*
                - iteration::*
        icon: business
        name: im
    im:
      adapter:
        chat_info: group_chat.getChatInfo
        create_group_and_send_msg: group_chat.createGroupAndSendMsg
        send_at_user_msg: inform.sendAtUserMsg
        send_msg: inform.sendMsg
        sync_organization: organization.sync
      code: im
      desc: TAPD集成im
      name: im
      support:
        group_chat: true
        host_user_ralation:
          enabled: true
          sync_text: 同步im成员
        send_at_user_msg: true
        send_msg: true
  name: im
  resources:
    - key: app_for_global_config
      name: Demo应用
      path: pages/app_for_global_config
  scopes:
    - user
    - story
    - organization
    - workspace#read
    - bug
    - task
    - member
    - setting
  tag:
    - name: im
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
上次更新: 2024-08-12 16:45:15