Skip to main content

GitHub connector

Turns pull-request and issue references into a link with a status. Two paths, deliberately separate:

InputHow it resolvesConfidence
A link already in the messagedirect lookup of that exact artifacthighest — a link is not a guess
A prose reference ("the PR", PR #482)search API, biased to the author's most recently updated open work≤ 0.95

GitHub's own preview shows you a title. This shows you whether the PR is merged, still a draft, or waiting on a review.

What it resolves​

MessageResolves to
can someone review the PR?the author's open PRs, most recently updated first
PR #482 is readythat exact pull request
EVER-123 is blockedclaimed by Jira when its key pattern matches; GitHub answers non-Jira issue refs
https://github.com/org/repo/pull/482that PR, enriched with live status (needs unfurl_links)

Reference extraction happens in the core, not here — see the pipeline. A vague reference arrives with key: None, which is the connector's instruction to infer from author + recency rather than look something up.

Configuration​

[connectors.github]
token_env = "GITHUB_TOKEN" # required — the token lives ONLY in the env var
org = "ever-co" # optional — scopes searches to one org
api_base = "https://api.github.com" # optional — the default
host = "github.com" # optional — the web host claimed for links

# chat user id -> GitHub login
[connectors.github.user_map]
U0123ABC = "octocat"
U0456DEF = "hubot"
KeyRequiredDefaultMeaning
token_env✅—Env var holding the API token
api_base—https://api.github.comREST API root; trailing slash trimmed
host—github.comWeb host claimed for link enrichment
org——Org login; when set, searches carry org:{login}
[…user_map]—emptyChat user id → GitHub login

The token​

A read token is enough. Classic PAT or fine-grained, with read access to the repositories you want resolved — Ever Async never writes to GitHub. The REST API version is pinned (2022-11-28) on every request.

GitHub Enterprise​

Set both, because they are different things:

[connectors.github]
token_env = "GITHUB_TOKEN"
api_base = "https://github.acme.internal/api/v3"
host = "github.acme.internal"

api_base is where requests go. host is which URLs this connector claims during link enrichment. Set only the first and pasted enterprise links are ignored; set only the second and every lookup goes to github.com.

User mapping​

This is the part people forget.

An author with no user_map entry resolves to nothing.

That is a normal answer, not an error — the connector returns an empty list, the pipeline moves on, and the message may get a nudge instead of a card. Nothing is logged as a failure, so a half-filled map looks exactly like a quiet connector.

The map is chat-user-id → GitHub login:

[connectors.github.user_map]
U0123ABC = "octocat"

Slack user ids look like U0123ABC — find one by clicking a profile → Copy member ID.

Diagnosing "the connector does nothing"

Post a message with an explicit reference (PR #482). If that resolves and the PR does not, the map is the problem: keyed references need no author mapping, inferred ones need it to know whose work to search.

How inference works​

For a vague reference, the connector searches:

type:pr author:{login} is:open sort:updated

scoped by org: when configured, taking the 5 most recently updated candidates. Then:

SituationConfidence
The reference carried an exact PR number0.95
The author has exactly one open PR0.85
Several candidates — best by title-token overlap with the message0.60 → 0.75

Those numbers meet [policy] min_confidence (default 0.7), which is what decides whether a card is posted publicly. One open PR clears it; a three-way guess with no keyword overlap does not. See policy → min_confidence.

With [policy] unfurl_links = true (the default), URLs already in the message are handed to every connector. This one claims:

https://{host}/{owner}/{repo}/pull/{number}
https://{host}/{owner}/{repo}/issues/{number}

Host comparison is normalized — a leading www., a default port, and letter case are all ignored, so https://GitHub.com/... and https://github.com:443/... are the same host. A trailing slash, a query string or a fragment is fine. A repo root, a non-numeric id, or any other host is not claimed — no item, no error, and the URL is left for whichever connector owns it.

Health check​

everasync doctor

Verifies the token reaches the API. A failure here is almost always an expired token or a fine-grained PAT that was never granted the repositories it is being asked about.

Behaviour and limits​

  • 6-second timeout per resolve. A slow GitHub never delays a nudge; the call is abandoned and counted as ever_async_connector_calls_total{connector="github",outcome="timeout"}.
  • Read-only. No writes, ever.
  • Top three items overall. Results from all connectors are merged, sorted by confidence, and truncated to three.
  • An error is not a failure of the message. A broken connector contributes nothing and the pipeline continues.