Skip to content

Commit c250a4a

Browse files
update README documentation for new feature
1 parent d396bd7 commit c250a4a

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed

README.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ cog.outl(f"- Django {', '.join([version for version in DJ_VERSIONS if version !=
211211
212212
## Getting Started
213213
214+
### Webhook Events
215+
214216
django-github-app provides a router-based system for handling GitHub webhook events, built on top of [gidgethub](https://github.com/gidgethub/gidgethub). The router matches incoming webhooks to your handler functions based on the event type and optional action.
215217
216218
To start handling GitHub webhooks, create your event handlers in a new file (e.g., `events.py`) within your Django app.
@@ -315,6 +317,77 @@ For more information about GitHub webhook events and payloads, see these pages i
315317
316318
For more details about how `gidgethub.sansio.Event` and webhook routing work, see the [gidgethub documentation](https://gidgethub.readthedocs.io).
317319
320+
### Mentions
321+
322+
django-github-app provides a `@gh.mention` decorator to easily respond when your GitHub App is mentioned in comments. This is useful for building interactive bots that respond to user commands.
323+
324+
For ASGI projects:
325+
326+
```python
327+
# your_app/events.py
328+
import re
329+
from django_github_app.routing import GitHubRouter
330+
from django_github_app.mentions import MentionScope
331+
332+
gh = GitHubRouter()
333+
334+
# Respond to mentions of your bot
335+
@gh.mention(username="mybot")
336+
async def handle_bot_mention(event, gh, *args, context, **kwargs):
337+
"""Respond when someone mentions @mybot"""
338+
mention = context.mention
339+
issue_url = event.data["issue"]["comments_url"]
340+
341+
await gh.post(
342+
issue_url,
343+
data={"body": f"Hello! You mentioned me at position {mention.position}"}
344+
)
345+
346+
# Use regex to match multiple bot names
347+
@gh.mention(username=re.compile(r".*-bot"))
348+
async def handle_any_bot(event, gh, *args, context, **kwargs):
349+
"""Respond to any mention ending with '-bot'"""
350+
mention = context.mention
351+
await gh.post(
352+
event.data["issue"]["comments_url"],
353+
data={"body": f"Bot {mention.username} at your service!"}
354+
)
355+
356+
# Restrict to pull request mentions only
357+
@gh.mention(username="deploy-bot", scope=MentionScope.PR)
358+
async def handle_deploy_command(event, gh, *args, context, **kwargs):
359+
"""Only respond to @deploy-bot in pull requests"""
360+
await gh.post(
361+
event.data["issue"]["comments_url"],
362+
data={"body": "Starting deployment..."}
363+
)
364+
```
365+
366+
For WSGI projects:
367+
368+
```python
369+
# your_app/events.py
370+
import re
371+
from django_github_app.routing import GitHubRouter
372+
from django_github_app.mentions import MentionScope
373+
374+
gh = GitHubRouter()
375+
376+
# Respond to mentions of your bot
377+
@gh.mention(username="mybot")
378+
def handle_bot_mention(event, gh, *args, context, **kwargs):
379+
"""Respond when someone mentions @mybot"""
380+
mention = context.mention
381+
issue_url = event.data["issue"]["comments_url"]
382+
383+
gh.post(
384+
issue_url,
385+
data={"body": f"Hello! You mentioned me at position {mention.position}"}
386+
)
387+
```
388+
389+
The mention decorator automatically extracts mentions from comments and provides context about each mention. Handlers are called once for each matching mention in a comment.
390+
318391
## Features
319392
320393
### GitHub API Client
@@ -485,6 +558,121 @@ The library includes event handlers for managing GitHub App installations and re
485558
486559
The library loads either async or sync versions of these handlers based on your `GITHUB_APP["WEBHOOK_TYPE"]` setting.
487560
561+
### Mentions
562+
563+
The `@gh.mention` decorator provides a powerful way to build interactive GitHub Apps that respond to mentions in comments. When users mention your app (e.g., `@mybot help`), the decorator automatically detects these mentions and routes them to your handlers.
564+
565+
#### How It Works
566+
567+
The mention system:
568+
1. Monitors incoming webhook events for comments containing mentions
569+
2. Extracts all mentions while ignoring those in code blocks, inline code, or blockquotes
570+
3. Filters mentions based on your specified criteria (username pattern, scope)
571+
4. Calls your handler once for each matching mention, providing rich context
572+
573+
#### Mention Context
574+
575+
Each handler receives a `context` parameter with detailed information about the mention:
576+
577+
```python
578+
@gh.mention(username="mybot")
579+
async def handle_mention(event, gh, *args, context, **kwargs):
580+
mention = context.mention
581+
582+
# Access mention details
583+
print(f"Username: {mention.username}") # "mybot"
584+
print(f"Position: {mention.position}") # Character position in comment
585+
print(f"Line: {mention.line_info.lineno}") # Line number (1-based)
586+
print(f"Line text: {mention.line_info.text}") # Full text of the line
587+
588+
# Navigate between mentions in the same comment
589+
if mention.previous_mention:
590+
print(f"Previous: @{mention.previous_mention.username}")
591+
if mention.next_mention:
592+
print(f"Next: @{mention.next_mention.username}")
593+
594+
# Check the scope (ISSUE, PR, or COMMIT)
595+
print(f"Scope: {context.scope}")
596+
```
597+
598+
#### Filtering Options
599+
600+
##### Username Patterns
601+
602+
Filter mentions by username using exact matches or regular expressions:
603+
604+
```python
605+
# Exact match (case-insensitive)
606+
@gh.mention(username="deploy-bot")
607+
608+
# Regular expression pattern
609+
@gh.mention(username=re.compile(r".*-bot"))
610+
611+
# Respond to all mentions (no filter)
612+
@gh.mention()
613+
```
614+
615+
##### Scopes
616+
617+
Limit mentions to specific GitHub contexts:
618+
619+
```python
620+
from django_github_app.mentions import MentionScope
621+
622+
# Only respond in issues (not PRs)
623+
@gh.mention(username="issue-bot", scope=MentionScope.ISSUE)
624+
625+
# Only respond in pull requests
626+
@gh.mention(username="review-bot", scope=MentionScope.PR)
627+
628+
# Only respond in commit comments
629+
@gh.mention(username="commit-bot", scope=MentionScope.COMMIT)
630+
```
631+
632+
Scope mappings:
633+
- `MentionScope.ISSUE`: Issue comments only
634+
- `MentionScope.PR`: PR comments, PR reviews, and PR review comments
635+
- `MentionScope.COMMIT`: Commit comments only
636+
637+
#### Parsing Rules
638+
639+
The mention parser follows GitHub's rules:
640+
641+
- **Valid mentions**: Must start with `@` followed by a GitHub username
642+
- **Username format**: 1-39 characters, alphanumeric or single hyphens, no consecutive hyphens
643+
- **Position**: Must be preceded by whitespace or start of line
644+
- **Exclusions**: Mentions in code blocks, inline code, or blockquotes are ignored
645+
646+
Examples:
647+
```
648+
@bot help ✓ Detected
649+
Hey @bot can you help? ✓ Detected
650+
@deploy-bot start ✓ Detected
651+
See @user's comment ✓ Detected
652+
653+
[email protected] ✗ Not a mention
654+
@@bot ✗ Invalid format
655+
`@bot help` ✗ Inside code
656+
```@bot in code``` ✗ Inside code block
657+
> @bot quoted ✗ Inside blockquote
658+
```
659+
660+
#### Multiple Mentions
661+
662+
When a comment contains multiple mentions, each matching mention triggers a separate handler call:
663+
664+
```python
665+
@gh.mention(username=re.compile(r".*-bot"))
666+
async def handle_bot_mention(event, gh, *args, context, **kwargs):
667+
mention = context.mention
668+
669+
# For comment: "@deploy-bot start @test-bot validate @user check"
670+
# This handler is called twice:
671+
# 1. For @deploy-bot (mention.username = "deploy-bot")
672+
# 2. For @test-bot (mention.username = "test-bot")
673+
# The @user mention is filtered out by the regex pattern
674+
```
675+
488676
### System Checks
489677
490678
The library includes Django system checks to validate your webhook configuration:

0 commit comments

Comments
 (0)