在前序中,我们介绍了同步Jira Issue信息到飞书项目,那么如果反过来,同步过来的缺陷数据在飞书项目中发生了变化,能不能把信息同步到Jira呢,答案是肯定的,那么接下来我们就一起来看看如何将信息从飞书项目同步到Jira。
我们还是拿前面同步过来的数据做例子,给大家讲解如何操作。
时序图
下图为调用的时序图,从图中可以大致了解整个操作过程的数据流向。插件会通过Webhook监听到工作项数据的变化,再根据工作项id获取该工作项的基本信息,然后通过Jira API更新Jira。
飞书项目Webhook
如果想要近实时的感知到数据的变化,并把变化的数据同步过去,我们就要依托于飞书项目的Webhook能力。 飞书项目提供了丰富的Webhook事件,可以参考以下的帮助文档: project.feishu.cn/b/helpcente…
自动化规则
飞书项目中的Webhook可以通过自动化规则进行配置,入口在“空间配置--->自动化”。
例如,当缺陷的名称经过评估发生更改时,需要同步更新Jira中的名称字段,我们配置的自动化规则如下: 当缺陷工作项的名称字段发生变化时,就会发送一个Webhook
上述截图示例中我们配置了一个自动化规则,当缺陷工作项的名称发生变化时触发Webhook,飞书项目就会向下一步配置的webhook地址,demo.com/sync_issue 发送http请求。我们在sync_issue接口后端接收到的事件信息如下所示:
Webhook数据
{
"header": {
"operator": "xxx", // string, 操作者的userkey
"event_type": "WorkitemUpdateEvent", // string, webhook的event_type
"token": "token-xxxx", // string,注册webhook填入的token,可用于校验
"uuid": "" // string,幂等串
},
"payload": {
"id": 5018740550, // int,64位,工作项id
"name": "Update Issue Name", // string,工作项名称
"project_key": "xxxxx", // string,空间ID
"project_simple_name": "xxxxx", // string,空间域名
"updated_at": 1639548775000, // int,64位,更新时间戳
"updated_by": "xxxxx", // string,更新人的userkey
"work_item_type_key": "issue", // string,工作项类型
"changed_fields": [
{
"field_alias": "name", // 字段对接标识
"field_key": "name", // 字段key
"field_type_key": "_name", // 字段类型
"pre_field_value": "This is a issue demo, please confirm it.", // 变更前的值
"cur_field_value": "Update Issue Name" // 变更后的值
},
]
}
}
在上述请求结构体中,我们可以看到发生变化的工作项id,工作项名称,空间key,空间名称,工作项类型以及变化的字段,变化字段参数中会将变化字段的字段key,类型,变更前后值都一一给出。
获取工作项详情
至此,我们在逻辑中可以对上述的报文信息进行解析,获得到变更后的名称是“Update Issue Name”。 在获得到更新后的缺陷名称后,我们还要进一步得到需要更新的是哪一条Jira Issue。此时需要根据工作项id来通过工作项详情接口来获得到当前实例的基本信息。
Postman获取实例详情
获取详情代码示例
func queryWorkItemDetail(ctx context.Context, projectKey string, workItemTypeKey string,
workItemIDs []int64, filterFields []string, expand *workitem.Expand, userKey string) (Data []*workitem.WorkItemInfo, err error) {
log.Println("start to query work item detail")
cli := getCli()
if expand == nil {
expand = &workitem.Expand{}
}
req := workitem.NewQueryWorkItemDetailReqBuilder().ProjectKey(projectKey).WorkItemTypeKey(workItemTypeKey).WorkItemIDs(workItemIDs).Fields(filterFields).
Expand(expand).Build()
resp, err := cli.WorkItem.QueryWorkItemDetail(ctx, req, core.WithUserKey(userKey))
if err != nil {
log.Println("QueryWorkItem detail failed, err: ", err.Error())
return nil, err
}
if !resp.Success() {
msg := fmt.Sprintf("QueryWorkItemDetail failed,api err=%s,rpc err=%s,logid=%s", resp.Error(), resp.Err.Msg, resp.RequestId())
log.Printf("QueryWorkItemDetail failed,api err=%s,rpc err=%s,logid=%s", resp.Error(), resp.Err.Msg, resp.RequestId())
return nil, errors.New(msg)
}
log.Printf("QueryWorkItemDetail success,len=%d,logid=%s", len(resp.Data), resp.RequestId())
return resp.Data, nil
}
例如上述逻辑中我们遍历该工作项的字段信息,通过事先在字段管理中配置的关联字段的对接标识sync_jira_id,获取到Jira的ID值.
获取Jira ID信息代码示例
func getJiraID(wii *workitem.WorkItemInfo) (string, error) {
if wii == nil {
return "", errors.New("work item is nil")
}
for _, field := range wii.Fields {
if field.FieldAlias == "sync_jira_id" {
return field.FieldValue.(string), nil
}
}
return "", errors.New("sync_jira_id not found")
}
上述代码中是通过字段的对接标识来获取字段的,因为在创建自定义字段时,字段key(field_key)是系统生成的,这个无法控制,但是我们可以指定对接标识,这个就相当于是字段别名,这个是由我们自己控制的,通过字段别名,一样可以拿到字段信息。
更新Jira
如上述逻辑所示,假如我们获得到的Jira ID 为10000。 我们拿到了变更后的内容,以及当前缺陷关联的Jira Issue,就可以调用Jira的API做字段的更新,如下图所示:
我们去Jira中查看,发现名称已经更新了
以上就是我们通过Webhook监听到工作项字段的变化,然后去更新Jira Issue的详细过程,赶快来试试吧~