diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go
index 885cde3bc5..089f51952f 100644
--- a/services/webhook/feishu.go
+++ b/services/webhook/feishu.go
@@ -97,23 +97,40 @@ func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 
 // Issue implements PayloadConvertor Issue method
 func (f *FeishuPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
-	text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)
-
-	return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil
+	title, link, by, operator, result, assignees := getIssuesInfo(p)
+	var res api.Payloader
+	if assignees != "" {
+		if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
+			res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.Issue.Body))
+		} else {
+			res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.Issue.Body))
+		}
+	} else {
+		res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Issue.Body))
+	}
+	return res, nil
 }
 
 // IssueComment implements PayloadConvertor IssueComment method
 func (f *FeishuPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
-	text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)
-
-	return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + p.Comment.Body), nil
+	title, link, by, operator := getIssuesCommentInfo(p)
+	return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Comment.Body)), nil
 }
 
 // PullRequest implements PayloadConvertor PullRequest method
 func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
-	text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
-
-	return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil
+	title, link, by, operator, result, assignees := getPullRequestInfo(p)
+	var res api.Payloader
+	if assignees != "" {
+		if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
+			res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.PullRequest.Body))
+		} else {
+			res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.PullRequest.Body))
+		}
+	} else {
+		res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.PullRequest.Body))
+	}
+	return res, nil
 }
 
 // Review implements PayloadConvertor Review method
diff --git a/services/webhook/feishu_test.go b/services/webhook/feishu_test.go
index 84549c1fa5..a3182e82b0 100644
--- a/services/webhook/feishu_test.go
+++ b/services/webhook/feishu_test.go
@@ -72,7 +72,7 @@ func TestFeishuPayload(t *testing.T) {
 		require.NotNil(t, pl)
 		require.IsType(t, &FeishuPayload{}, pl)
 
-		assert.Equal(t, "#2 crash\r\n[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.(*FeishuPayload).Content.Text)
+		assert.Equal(t, "[Issue-test/repo #2]: opened\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.(*FeishuPayload).Content.Text)
 
 		p.Action = api.HookIssueClosed
 		pl, err = d.Issue(p)
@@ -80,7 +80,7 @@ func TestFeishuPayload(t *testing.T) {
 		require.NotNil(t, pl)
 		require.IsType(t, &FeishuPayload{}, pl)
 
-		assert.Equal(t, "#2 crash\r\n[test/repo] Issue closed: #2 crash by user1", pl.(*FeishuPayload).Content.Text)
+		assert.Equal(t, "[Issue-test/repo #2]: closed\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.(*FeishuPayload).Content.Text)
 	})
 
 	t.Run("IssueComment", func(t *testing.T) {
@@ -92,7 +92,7 @@ func TestFeishuPayload(t *testing.T) {
 		require.NotNil(t, pl)
 		require.IsType(t, &FeishuPayload{}, pl)
 
-		assert.Equal(t, "#2 crash\r\n[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.(*FeishuPayload).Content.Text)
+		assert.Equal(t, "[Comment-test/repo #2]: created\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\n\nmore info needed", pl.(*FeishuPayload).Content.Text)
 	})
 
 	t.Run("PullRequest", func(t *testing.T) {
@@ -104,7 +104,7 @@ func TestFeishuPayload(t *testing.T) {
 		require.NotNil(t, pl)
 		require.IsType(t, &FeishuPayload{}, pl)
 
-		assert.Equal(t, "#12 Fix bug\r\n[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.(*FeishuPayload).Content.Text)
+		assert.Equal(t, "[PullRequest-test/repo #12]: opened\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\nAssignees: user1\n\nfixes bug #2", pl.(*FeishuPayload).Content.Text)
 	})
 
 	t.Run("PullRequestComment", func(t *testing.T) {
@@ -116,7 +116,7 @@ func TestFeishuPayload(t *testing.T) {
 		require.NotNil(t, pl)
 		require.IsType(t, &FeishuPayload{}, pl)
 
-		assert.Equal(t, "#12 Fix bug\r\n[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.(*FeishuPayload).Content.Text)
+		assert.Equal(t, "[Comment-test/repo #12]: created\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\n\nchanges requested", pl.(*FeishuPayload).Content.Text)
 	})
 
 	t.Run("Review", func(t *testing.T) {
diff --git a/services/webhook/general.go b/services/webhook/general.go
index b9cc3dc845..986467bc99 100644
--- a/services/webhook/general.go
+++ b/services/webhook/general.go
@@ -28,6 +28,69 @@ func htmlLinkFormatter(url, text string) string {
 	return fmt.Sprintf(`<a href="%s">%s</a>`, html.EscapeString(url), html.EscapeString(text))
 }
 
+// getPullRequestInfo gets the information for a pull request
+func getPullRequestInfo(p *api.PullRequestPayload) (title, link, by, operator, operateResult, assignees string) {
+	title = fmt.Sprintf("[PullRequest-%s #%d]: %s\n%s", p.Repository.FullName, p.PullRequest.Index, p.Action, p.PullRequest.Title)
+	assignList := p.PullRequest.Assignees
+	assignStringList := make([]string, len(assignList))
+
+	for i, user := range assignList {
+		assignStringList[i] = user.UserName
+	}
+	if p.Action == api.HookIssueAssigned {
+		operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName)
+	} else if p.Action == api.HookIssueUnassigned {
+		operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName)
+	} else if p.Action == api.HookIssueMilestoned {
+		operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID)
+	}
+	link = p.PullRequest.HTMLURL
+	by = fmt.Sprintf("PullRequest by %s", p.PullRequest.Poster.UserName)
+	if len(assignStringList) > 0 {
+		assignees = fmt.Sprintf("Assignees: %s", strings.Join(assignStringList, ", "))
+	}
+	operator = fmt.Sprintf("Operator: %s", p.Sender.UserName)
+	return title, link, by, operator, operateResult, assignees
+}
+
+// getIssuesInfo gets the information for an issue
+func getIssuesInfo(p *api.IssuePayload) (issueTitle, link, by, operator, operateResult, assignees string) {
+	issueTitle = fmt.Sprintf("[Issue-%s #%d]: %s\n%s", p.Repository.FullName, p.Issue.Index, p.Action, p.Issue.Title)
+	assignList := p.Issue.Assignees
+	assignStringList := make([]string, len(assignList))
+
+	for i, user := range assignList {
+		assignStringList[i] = user.UserName
+	}
+	if p.Action == api.HookIssueAssigned {
+		operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName)
+	} else if p.Action == api.HookIssueUnassigned {
+		operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName)
+	} else if p.Action == api.HookIssueMilestoned {
+		operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.Issue.Milestone.ID)
+	}
+	link = p.Issue.HTMLURL
+	by = fmt.Sprintf("Issue by %s", p.Issue.Poster.UserName)
+	if len(assignStringList) > 0 {
+		assignees = fmt.Sprintf("Assignees: %s", strings.Join(assignStringList, ", "))
+	}
+	operator = fmt.Sprintf("Operator: %s", p.Sender.UserName)
+	return issueTitle, link, by, operator, operateResult, assignees
+}
+
+// getIssuesCommentInfo gets the information for a comment
+func getIssuesCommentInfo(p *api.IssueCommentPayload) (title, link, by, operator string) {
+	title = fmt.Sprintf("[Comment-%s #%d]: %s\n%s", p.Repository.FullName, p.Issue.Index, p.Action, p.Issue.Title)
+	link = p.Issue.HTMLURL
+	if p.IsPull {
+		by = fmt.Sprintf("PullRequest by %s", p.Issue.Poster.UserName)
+	} else {
+		by = fmt.Sprintf("Issue by %s", p.Issue.Poster.UserName)
+	}
+	operator = fmt.Sprintf("Operator: %s", p.Sender.UserName)
+	return title, link, by, operator
+}
+
 func getIssuesPayloadInfo(p *api.IssuePayload, linkFormatter linkFormatter, withSender bool) (string, string, string, int) {
 	repoLink := linkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
 	issueTitle := fmt.Sprintf("#%d %s", p.Index, p.Issue.Title)
diff --git a/services/webhook/general_test.go b/services/webhook/general_test.go
index ba58ca4f90..64bd72f5a0 100644
--- a/services/webhook/general_test.go
+++ b/services/webhook/general_test.go
@@ -123,6 +123,10 @@ func issueTestPayload() *api.IssuePayload {
 			HTMLURL: "http://localhost:3000/test/repo/issues/2",
 			Title:   "crash",
 			Body:    "issue body",
+			Poster: &api.User{
+				UserName:  "user1",
+				AvatarURL: "http://localhost:3000/user1/avatar",
+			},
 			Assignees: []*api.User{
 				{
 					UserName:  "user1",
@@ -161,7 +165,11 @@ func issueCommentTestPayload() *api.IssueCommentPayload {
 			URL:     "http://localhost:3000/api/v1/repos/test/repo/issues/2",
 			HTMLURL: "http://localhost:3000/test/repo/issues/2",
 			Title:   "crash",
-			Body:    "this happened",
+			Poster: &api.User{
+				UserName:  "user1",
+				AvatarURL: "http://localhost:3000/user1/avatar",
+			},
+			Body: "this happened",
 		},
 	}
 }
@@ -190,6 +198,10 @@ func pullRequestCommentTestPayload() *api.IssueCommentPayload {
 			HTMLURL: "http://localhost:3000/test/repo/pulls/12",
 			Title:   "Fix bug",
 			Body:    "fixes bug #2",
+			Poster: &api.User{
+				UserName:  "user1",
+				AvatarURL: "http://localhost:3000/user1/avatar",
+			},
 		},
 		IsPull: true,
 	}
@@ -254,6 +266,10 @@ func pullRequestTestPayload() *api.PullRequestPayload {
 			Title:     "Fix bug",
 			Body:      "fixes bug #2",
 			Mergeable: true,
+			Poster: &api.User{
+				UserName:  "user1",
+				AvatarURL: "http://localhost:3000/user1/avatar",
+			},
 			Assignees: []*api.User{
 				{
 					UserName:  "user1",