通过kintone发布teambition任务

cybozu发表于:2020年07月23日 16:01:13更新于:2020年08月20日 16:42:57

Index

前言

teambition是一个基于看板系统的团队协作工具,并提供了丰富的API接口。通过本文你将学会如何将teambition整合进自己的系统中。


效果图如下:

0015f22372fd29103d2df99d742d1dd


应用的自定义开发

本文目的是实现一个基于kintone的teambition客户端,只要求实现基本的项目创建、任务创建功能。其他功能请自行参考teambitionAPI文档


Step1: 添加teambition企业内部应用

登录teambition后请按照官方文档创建企业内部应用。
做到创建测试企业这一步即可,先无需发布。

请记下


Step2: 设置kintone应用的表单

由于teambition的API参数非常多,这里只列出kintone应用中必要的字段。

字段名字段类型code备注
项目名称单行文本框projectNameteambition项目名
项目类型单选框projectType默认为normal(普通项目)
项目公开性单选框projectVisibility默认为visibleInOrg(企业项目)
项目ID单行文本框projectIdteambitionAPI返回
项目是否归档单选框projectIsArchived默认为0(不归档)
任务类型 ID单行文本框templateIdteambitionAPI返回
任务列表 ID单行文本框tasklistIdteambitionAPI返回
任务分组 ID单行文本框taskgroupIdteambitionAPI返回
表格表格tableteambition任务列表
任务ID单行文本框taskIdteambitionAPI返回
优先级单选框priority默认为0(普通)
可见性单选框visible默认为projectMembers(项目成员可见)
任务内容多行文本框content任务内容


Step3: 导入公用库

teambition使用appAccessToken作为授权凭证。从官方示例中可以了解到,appAccessToken的计算依赖于JWT(JSON Web Tokens)。
因此,在kintone中,我们需要导入JWT在JS端的实现jsrsasign。
当前demo中使用的是8.0.20版


Step4: 自定义JavaScript

生成token

function genAppAccessToken(param) {
            const periodical = 3600;
            const iat = Math.floor(Date.now() / (1000 * periodical)) * periodical;
            const oHeader = {
                alg: 'HS256',
                typ: 'JWT'
            };
            const oPayload = {
                iat:iat,
                exp: iat + Math.floor(1.1 * periodical),
                _appId: param.appId,
            };
            return KJUR.jws.JWS.sign('HS256', oHeader, oPayload, { utf8: param.appSecret });
        }


通过E-mail来获取用户ID

        function getUserID(param) {
            return kintone.proxy('https://open.teambition.com/api/user/getId?email=' + param.email, 'GET', {
                'Authorization': 'Bearer ' + param.appAccessToken,
                'X-Tenant-Id': param.orgId,
                'X-Tenant-Type': 'organization'
            }, {});
        }


创建项目,这里利用kintone.proxy来实现跨域访问并返回一个kintone.Promise

        function createProject(param) {
            return kintone.proxy('https://open.teambition.com/api/project/create', 'POST', {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + param.appAccessToken,
                'X-Tenant-Id': param.orgId,
                'X-Tenant-Type': 'organization'
            }, {
                'operatorId': param.uid,
                'name': param.name,
                'description': param.description,
                'cover': param.cover,
                'type': param.type,
                'visibility': param.visibility            });
        }


创建完项目后,我们需要创建一个新的任务类型和任务列表来存放任务,并记录下相应的ID,该步骤不可省略

        function createTaskgroup(param) {
            return kintone.proxy('https://open.teambition.com/api/taskgroup/create', 'POST', {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + param.appAccessToken,
                'X-Tenant-Id': param.orgId,
                'X-Tenant-Type': 'organization'
            }, {
                'operatorId': param.uid,
                'projectId': param.projectId,
                'taskgroups': param.taskgroups            });
        }

        function createTasklist(param) {
            return kintone.proxy('https://open.teambition.com/api/tasklist/create', 'POST', {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + param.appAccessToken,
                'X-Tenant-Id': param.orgId,
                'X-Tenant-Type': 'organization'
            }, {
                'operatorId': param.uid,
                'projectId': param.projectId,
                'tasklists': param.tasklists            });
        }


创建任务

        function createTask(param) {
            const data = {
                'operatorId': param.uid,
                'projectId': param.projectId,
                'templateId': param.templateId,
                'content': param.content,
                'priority': param.priority,
                'visible': param.visible            }
            const options = ['tasklistId', 'taskgroupId', 'executorId', 'statusId', 'startDate', 'dueDate', 'note', 'parentTaskId', 'participants', 'customfields'];
            for (let i = 0; i < options.length; i++) {
                param[options[i]] && (data[options[i]] = param[options[i]]);
            }
            return kintone.proxy('https://open.teambition.com/api/task/create', 'POST', {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + param.appAccessToken,
                'X-Tenant-Id': param.orgId,
                'X-Tenant-Type': 'organization'
            }, data);
        }


绑定kintone事件,更多的kintone事件可参考这里

        kintone.events.on(['app.record.create.show'], onCreateShow);
        kintone.events.on(['app.record.create.submit'], onCreate);
        kintone.events.on(['app.record.edit.show'], onEditShow);
        kintone.events.on(['app.record.edit.submit'], onEdit);


注意事项

※ 不要在js中暴露App ID和App Serect。

※ 本文代码仅供参考。

※ 我们不为本示例代码提供技术支持。