notify-discord-issues.yml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. name: Discord Issue Notification
  2. on:
  3. issues:
  4. types: [opened, closed, reopened]
  5. workflow_dispatch:
  6. inputs:
  7. issue_number:
  8. description: "Issue number to notify about"
  9. required: true
  10. type: string
  11. jobs:
  12. Discord:
  13. runs-on: ubuntu-latest
  14. name: Discord Issue Notifier
  15. steps:
  16. - uses: actions/checkout@v4
  17. - name: Get issue info
  18. id: issue-info
  19. run: |
  20. if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
  21. # For manual trigger, get the specific issue
  22. ISSUE_NUMBER="${{ github.event.inputs.issue_number }}"
  23. # Get issue info via GitHub CLI
  24. ISSUE_INFO=$(gh issue view "$ISSUE_NUMBER" --json number,title,body,url,author,state,createdAt,closedAt,labels)
  25. echo "number=$(echo "$ISSUE_INFO" | jq -r '.number')" >> $GITHUB_OUTPUT
  26. echo "title=$(echo "$ISSUE_INFO" | jq -r '.title')" >> $GITHUB_OUTPUT
  27. # Use EOF for the body which may contain special characters
  28. echo "body<<EOF" >> $GITHUB_OUTPUT
  29. echo "$ISSUE_INFO" | jq -r '.body' >> $GITHUB_OUTPUT
  30. echo "EOF" >> $GITHUB_OUTPUT
  31. echo "html_url=$(echo "$ISSUE_INFO" | jq -r '.url')" >> $GITHUB_OUTPUT
  32. echo "author_login=$(echo "$ISSUE_INFO" | jq -r '.author.login')" >> $GITHUB_OUTPUT
  33. echo "author_html_url=https://github.com/$(echo "$ISSUE_INFO" | jq -r '.author.login')" >> $GITHUB_OUTPUT
  34. echo "state=$(echo "$ISSUE_INFO" | jq -r '.state')" >> $GITHUB_OUTPUT
  35. echo "created_at=$(echo "$ISSUE_INFO" | jq -r '.createdAt')" >> $GITHUB_OUTPUT
  36. echo "closed_at=$(echo "$ISSUE_INFO" | jq -r '.closedAt // empty')" >> $GITHUB_OUTPUT
  37. # Format labels
  38. LABELS=$(echo "$ISSUE_INFO" | jq -r '.labels[]?.name' | tr '\n' ',' | sed 's/,$//')
  39. echo "labels=${LABELS}" >> $GITHUB_OUTPUT
  40. # Set action to "opened" for manual dispatch
  41. echo "action=opened" >> $GITHUB_OUTPUT
  42. else
  43. # For automatic trigger, use event data
  44. echo "number=${{ github.event.issue.number }}" >> $GITHUB_OUTPUT
  45. echo "title=${{ github.event.issue.title }}" >> $GITHUB_OUTPUT
  46. # Use EOF for the automatic issue body as well
  47. echo "body<<EOF" >> $GITHUB_OUTPUT
  48. echo "${{ github.event.issue.body }}" >> $GITHUB_OUTPUT
  49. echo "EOF" >> $GITHUB_OUTPUT
  50. echo "html_url=${{ github.event.issue.html_url }}" >> $GITHUB_OUTPUT
  51. echo "author_login=${{ github.event.issue.user.login }}" >> $GITHUB_OUTPUT
  52. echo "author_html_url=${{ github.event.issue.user.html_url }}" >> $GITHUB_OUTPUT
  53. echo "state=${{ github.event.issue.state }}" >> $GITHUB_OUTPUT
  54. echo "created_at=${{ github.event.issue.created_at }}" >> $GITHUB_OUTPUT
  55. echo "closed_at=${{ github.event.issue.closed_at }}" >> $GITHUB_OUTPUT
  56. echo "action=${{ github.event.action }}" >> $GITHUB_OUTPUT
  57. # Format labels from event
  58. LABELS="${{ join(github.event.issue.labels.*.name, ',') }}"
  59. echo "labels=${LABELS}" >> $GITHUB_OUTPUT
  60. fi
  61. env:
  62. GH_TOKEN: ${{ github.token }}
  63. - name: Set action emoji and color
  64. id: action-style
  65. run: |
  66. case "${{ steps.issue-info.outputs.action }}" in
  67. "opened")
  68. echo "emoji=🆕" >> $GITHUB_OUTPUT
  69. echo "color=5763719" >> $GITHUB_OUTPUT
  70. echo "action_text=New Issue" >> $GITHUB_OUTPUT
  71. ;;
  72. "closed")
  73. echo "emoji=✅" >> $GITHUB_OUTPUT
  74. echo "color=3066993" >> $GITHUB_OUTPUT
  75. echo "action_text=Issue Closed" >> $GITHUB_OUTPUT
  76. ;;
  77. "reopened")
  78. echo "emoji=🔄" >> $GITHUB_OUTPUT
  79. echo "color=15158332" >> $GITHUB_OUTPUT
  80. echo "action_text=Issue Reopened" >> $GITHUB_OUTPUT
  81. ;;
  82. *)
  83. echo "emoji=📝" >> $GITHUB_OUTPUT
  84. echo "color=5763719" >> $GITHUB_OUTPUT
  85. echo "action_text=Issue Updated" >> $GITHUB_OUTPUT
  86. ;;
  87. esac
  88. - name: Prepare issue content
  89. id: prepare-content
  90. run: |
  91. # Create a temp file for the body content
  92. cat > body_content.txt << 'BODY_EOF'
  93. ${{ steps.issue-info.outputs.body }}
  94. BODY_EOF
  95. # Truncate body if too long (Discord has limits) and escape for JSON
  96. BODY_LENGTH=$(wc -c < body_content.txt)
  97. if [ $BODY_LENGTH -gt 500 ]; then
  98. BODY=$(head -c 500 body_content.txt)
  99. BODY="${BODY}..."
  100. else
  101. BODY=$(cat body_content.txt)
  102. fi
  103. # Escape the body content for JSON
  104. BODY_ESCAPED=$(echo "$BODY" | jq -Rs .)
  105. echo "body_escaped=${BODY_ESCAPED}" >> $GITHUB_OUTPUT
  106. # Prepare labels field
  107. LABELS="${{ steps.issue-info.outputs.labels }}"
  108. if [ -n "$LABELS" ]; then
  109. LABELS_FORMATTED=$(echo "$LABELS" | sed 's/,/, /g')
  110. echo "labels_field={\"name\": \"🏷️ Labels\", \"value\": \"${LABELS_FORMATTED}\", \"inline\": true}," >> $GITHUB_OUTPUT
  111. else
  112. echo "labels_field=" >> $GITHUB_OUTPUT
  113. fi
  114. # Set timestamp based on action
  115. if [ "${{ steps.issue-info.outputs.action }}" = "closed" ] && [ -n "${{ steps.issue-info.outputs.closed_at }}" ]; then
  116. echo "timestamp=${{ steps.issue-info.outputs.closed_at }}" >> $GITHUB_OUTPUT
  117. else
  118. echo "timestamp=${{ steps.issue-info.outputs.created_at }}" >> $GITHUB_OUTPUT
  119. fi
  120. - name: Create Discord webhook payload
  121. run: |
  122. # Create the Discord payload using jq to properly escape everything
  123. jq -n \
  124. --arg avatar_url "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" \
  125. --arg title "${{ steps.action-style.outputs.emoji }} ${{ steps.action-style.outputs.action_text }}: #${{ steps.issue-info.outputs.number }} - ${{ steps.issue-info.outputs.title }}" \
  126. --argjson description ${{ steps.prepare-content.outputs.body_escaped }} \
  127. --arg url "${{ steps.issue-info.outputs.html_url }}" \
  128. --argjson color ${{ steps.action-style.outputs.color }} \
  129. --arg thumbnail_url "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" \
  130. --arg issue_number "#${{ steps.issue-info.outputs.number }}" \
  131. --arg author_name "${{ steps.issue-info.outputs.author_login }}" \
  132. --arg author_url "${{ steps.issue-info.outputs.author_html_url }}" \
  133. --arg repo_name "${{ github.event.repository.name }}" \
  134. --arg repo_url "${{ github.event.repository.html_url }}" \
  135. --arg issue_url "${{ steps.issue-info.outputs.html_url }}" \
  136. --arg timestamp "${{ steps.prepare-content.outputs.timestamp }}" \
  137. --arg labels "${{ steps.issue-info.outputs.labels }}" \
  138. '{
  139. "avatar_url": $avatar_url,
  140. "embeds": [
  141. {
  142. "title": $title,
  143. "description": $description,
  144. "url": $url,
  145. "color": $color,
  146. "thumbnail": {
  147. "url": $thumbnail_url
  148. },
  149. "fields": ([
  150. {
  151. "name": "📋 Issue #",
  152. "value": $issue_number,
  153. "inline": true
  154. },
  155. {
  156. "name": "👤 Author",
  157. "value": "[\($author_name)](\($author_url))",
  158. "inline": true
  159. },
  160. {
  161. "name": "📁 Repository",
  162. "value": "[\($repo_name)](\($repo_url))",
  163. "inline": true
  164. }
  165. ] + (if $labels != "" then [{
  166. "name": "🏷️ Labels",
  167. "value": ($labels | split(",") | join(", ")),
  168. "inline": true
  169. }] else [] end) + [{
  170. "name": "🔗 View Issue",
  171. "value": "[Open on GitHub](\($issue_url))",
  172. "inline": true
  173. }]),
  174. "timestamp": $timestamp,
  175. "footer": {
  176. "text": "Workout Cool • Issues",
  177. "icon_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
  178. }
  179. }
  180. ]
  181. }' > discord_payload.json
  182. - name: Send Discord notification
  183. run: |
  184. curl -H "Content-Type: application/json" \
  185. -d @discord_payload.json \
  186. "${{ secrets.DISCORD_ISSUES_WEBHOOK }}"