Skip to content

Conversation

@ealexandrohin
Copy link
Contributor

Added two new methods for generating DCF tokens, also tests and docs for them:

  • RequestDeviceVerificationURI()
  • RequestDeviceAccessToken()

New structs for requests/responses as well.

New methods SetDeviceAccessToken()/GetDeviceAccessToken() for DeviceAccessToken in Options.
Also tests for them too.

UserAccessToken still prioritized in headers over DeviceAccessToken, which is also prioritized over AppAccessToken.

Argued against adding new method for refreshing DCF tokens, when existing RefreshToken already works, as it doesn't return an error for missing ClientSecret. Still open for consideration. Also updated canRefreshToken() to support both ACF and DCF at the same time.

@nicklaw5 nicklaw5 requested a review from Copilot November 8, 2025 09:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for Device Access Tokens using OAuth Device Code Flow to the Helix Twitch API client. This enables authentication for standalone devices like game consoles and CLIs that may not have easy access to a web browser.

  • Added DeviceAccessToken field to the Options struct and corresponding getter/setter methods
  • Implemented RequestDeviceVerificationURI and RequestDeviceAccessToken methods for the device code flow
  • Updated token precedence logic in setRequestHeaders to include device tokens (between app and user tokens)

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
helix.go Added DeviceAccessToken field to Options struct, implemented getter/setter methods, updated token precedence logic, and modified canRefreshToken logic
helix_test.go Added comprehensive test coverage for device access token functionality including getter/setter tests and token header priority tests
authentication.go Implemented device code flow with RequestDeviceVerificationURI and RequestDeviceAccessToken methods and associated types
authentication_test.go Added test cases for device verification URI and device access token requests
docs/authentication_docs.md Added documentation for device access token flow including examples for getting and refreshing device tokens
docs/README.md Updated documentation to include device access tokens in the Options struct and access token priority explanation
SUPPORTED_ENDPOINTS.md Added device access token OAuth flow to the list of supported endpoints
Comments suppressed due to low confidence (1)

helix.go:442

  • The refreshToken() method only handles user access token refresh by calling RefreshUserAccessToken and updating UserAccessToken. However, the canRefreshToken() method now allows device tokens to pass through (line 423). When a device token is being used without a user token, the refresh will still call RefreshUserAccessToken, which may not be appropriate for device tokens. This could cause incorrect token refresh behavior.
func (c *Client) refreshToken() error {
	resp, err := c.RefreshUserAccessToken(c.opts.RefreshToken)
	if err != nil || resp.StatusCode != http.StatusOK {
		statusCode := -1
		var errorMessage string
		if resp != nil {
			statusCode = resp.StatusCode
			errorMessage = resp.ErrorMessage
		}
		return fmt.Errorf("failed to refresh token: (%d: %s) %v", statusCode, errorMessage, err)
	}

	c.mu.Lock()
	c.opts.UserAccessToken = resp.Data.AccessToken
	c.opts.RefreshToken = resp.Data.RefreshToken
	c.mu.Unlock()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ealexandrohin
Copy link
Contributor Author

Reviewed Copilot suggestions and fixed them.

Copy link
Owner

@nicklaw5 nicklaw5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nicklaw5 nicklaw5 merged commit 3b94224 into nicklaw5:main Nov 12, 2025
2 of 3 checks passed
@coveralls
Copy link

Pull Request Test Coverage Report for Build 19297569553

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 55 of 55 (100.0%) changed or added relevant lines in 2 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.2%) to 92.965%

Files with Coverage Reduction New Missed Lines %
channels_points.go 2 96.61%
Totals Coverage Status
Change from base Build 14026929583: 0.2%
Covered Lines: 1784
Relevant Lines: 1919

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants