or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

custom-tokens.mdindex.mdoauth1a-providers.mdoauth2-providers.mdspecialized-services.mdtoken-extractors.md

token-extractors.mddocs/

0

# Token Extractors

1

2

Custom token extractors for providers that use non-standard JSON response formats or require special error handling beyond the default OAuth 2.0 token response format. These extractors parse provider-specific token responses and create appropriate token objects.

3

4

## Capabilities

5

6

### Facebook Access Token Extractor

7

8

Facebook-specific token extractor that handles Facebook's non-standard error response format.

9

10

```java { .api }

11

public class FacebookAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {

12

public static FacebookAccessTokenJsonExtractor instance();

13

14

// Inherited from OAuth2AccessTokenJsonExtractor

15

public OAuth2AccessToken extract(Response response) throws IOException;

16

17

// Facebook-specific error handling

18

public void generateError(Response response) throws IOException;

19

}

20

```

21

22

Facebook returns errors in a non-standard format with specific error structure:

23

```json

24

{

25

"error": {

26

"message": "This authorization code has been used.",

27

"type": "OAuthException",

28

"code": 100,

29

"fbtrace_id": "DtxvtGRaxbB"

30

}

31

}

32

```

33

34

**Usage Example:**

35

```java

36

// Automatically used by FacebookApi

37

OAuth20Service service = new ServiceBuilder("app_id")

38

.apiSecret("app_secret")

39

.build(FacebookApi.instance());

40

41

try {

42

OAuth2AccessToken token = service.getAccessToken("invalid_code");

43

} catch (FacebookAccessTokenErrorResponse e) {

44

System.out.println("Facebook Error: " + e.getMessage());

45

System.out.println("Error Type: " + e.getType());

46

System.out.println("Error Code: " + e.getCode());

47

System.out.println("Trace ID: " + e.getFbTraceId());

48

}

49

```

50

51

### Salesforce JSON Token Extractor

52

53

Salesforce-specific token extractor that creates `SalesforceToken` objects with additional Salesforce metadata.

54

55

```java { .api }

56

public class SalesforceJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

57

public static SalesforceJsonTokenExtractor instance();

58

59

public OAuth2AccessToken extract(Response response) throws IOException;

60

}

61

```

62

63

Extracts Salesforce-specific fields from token response:

64

```json

65

{

66

"access_token": "00Dxx0000000000!...",

67

"instance_url": "https://mycompany.salesforce.com",

68

"id": "https://login.salesforce.com/id/00Dxx.../005xx...",

69

"token_type": "Bearer",

70

"issued_at": "1234567890",

71

"signature": "base64signature"

72

}

73

```

74

75

### OpenID JSON Token Extractor

76

77

OpenID Connect token extractor that creates `OpenIdOAuth2AccessToken` objects with ID token and claims.

78

79

```java { .api }

80

public class OpenIdJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

81

public static OpenIdJsonTokenExtractor instance();

82

83

public OAuth2AccessToken extract(Response response) throws IOException;

84

}

85

```

86

87

Extracts OpenID Connect ID token and decodes JWT claims:

88

```json

89

{

90

"access_token": "ya29.a0...",

91

"expires_in": 3599,

92

"refresh_token": "1//0...",

93

"scope": "openid profile email",

94

"token_type": "Bearer",

95

"id_token": "eyJhbGciOiJSUzI1NiIs..."

96

}

97

```

98

99

### Slack JSON Token Extractor

100

101

Slack-specific token extractor that creates `SlackOAuth2AccessToken` objects with user access token information.

102

103

```java { .api }

104

public class SlackJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

105

public static SlackJsonTokenExtractor instance();

106

107

public OAuth2AccessToken extract(Response response) throws IOException;

108

}

109

```

110

111

Extracts Slack-specific fields from token response:

112

```json

113

{

114

"ok": true,

115

"access_token": "xoxb-...",

116

"token_type": "bearer",

117

"scope": "channels:read,users:read",

118

"authed_user": {

119

"access_token": "xoxp-..."

120

}

121

}

122

```

123

124

### Fitbit JSON Token Extractor

125

126

Fitbit-specific token extractor that creates `FitBitOAuth2AccessToken` objects with user ID.

127

128

```java { .api }

129

public class FitBitJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

130

public static FitBitJsonTokenExtractor instance();

131

132

public OAuth2AccessToken extract(Response response) throws IOException;

133

}

134

```

135

136

Extracts Fitbit user ID from token response:

137

```json

138

{

139

"access_token": "eyJhbGci...",

140

"expires_in": 28800,

141

"refresh_token": "c6a3...",

142

"scope": "activity heartrate location nutrition profile settings sleep social weight",

143

"token_type": "Bearer",

144

"user_id": "26FWFL"

145

}

146

```

147

148

### Polar JSON Token Extractor

149

150

Polar-specific token extractor that creates `PolarOAuth2AccessToken` objects with user IDs.

151

152

```java { .api }

153

public class PolarJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

154

public static PolarJsonTokenExtractor instance();

155

156

public OAuth2AccessToken extract(Response response) throws IOException;

157

}

158

```

159

160

Extracts Polar user information from token response:

161

```json

162

{

163

"access_token": "8fdf2a...",

164

"token_type": "bearer",

165

"x_user_id": 1234567,

166

"user_id": 1234567

167

}

168

```

169

170

### VKontakte JSON Token Extractor

171

172

VKontakte-specific token extractor for Russian social network token responses.

173

174

```java { .api }

175

public class VKJsonTokenExtractor extends OAuth2AccessTokenJsonExtractor {

176

public static VKJsonTokenExtractor instance();

177

178

public OAuth2AccessToken extract(Response response) throws IOException;

179

}

180

```

181

182

### Instagram Access Token Extractor

183

184

Instagram-specific token extractor for Instagram API token responses.

185

186

```java { .api }

187

public class InstagramAccessTokenJsonExtractor extends OAuth2AccessTokenJsonExtractor {

188

public static InstagramAccessTokenJsonExtractor instance();

189

190

public OAuth2AccessToken extract(Response response) throws IOException;

191

}

192

```

193

194

### Google Device Authorization Extractor

195

196

Google-specific device authorization extractor for Google's device flow.

197

198

```java { .api }

199

public class GoogleDeviceAuthorizationJsonExtractor extends DeviceAuthorizationJsonExtractor {

200

public static GoogleDeviceAuthorizationJsonExtractor instance();

201

202

public DeviceAuthorization extract(Response response) throws IOException;

203

}

204

```

205

206

Extracts Google device authorization response:

207

```json

208

{

209

"device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",

210

"user_code": "GQVQ-JKEC",

211

"expires_in": 1800,

212

"interval": 5,

213

"verification_url": "https://www.google.com/device"

214

}

215

```

216

217

## Base Classes

218

219

### OAuth2AccessTokenJsonExtractor

220

221

Base class for OAuth 2.0 JSON token extractors.

222

223

```java { .api }

224

public abstract class OAuth2AccessTokenJsonExtractor implements TokenExtractor<OAuth2AccessToken> {

225

protected static final ObjectMapper OBJECT_MAPPER; // Jackson ObjectMapper

226

227

public OAuth2AccessToken extract(Response response) throws IOException;

228

public void generateError(Response response) throws IOException;

229

230

// Helper methods for subclasses

231

protected String extractRequiredParameter(JsonNode json, String parameter, Response response)

232

throws IOException;

233

protected String extractOptionalParameter(JsonNode json, String parameter);

234

protected Integer extractExpiresIn(JsonNode json);

235

}

236

```

237

238

### DeviceAuthorizationJsonExtractor

239

240

Base class for device authorization extractors.

241

242

```java { .api }

243

public abstract class DeviceAuthorizationJsonExtractor {

244

public abstract DeviceAuthorization extract(Response response) throws IOException;

245

}

246

```

247

248

## Error Handling

249

250

### Standard OAuth 2.0 Errors

251

Most extractors handle standard OAuth 2.0 error responses:

252

```json

253

{

254

"error": "invalid_grant",

255

"error_description": "Authorization code has expired"

256

}

257

```

258

259

### Provider-Specific Errors

260

Some extractors handle provider-specific error formats:

261

262

**Facebook Errors:**

263

```java

264

try {

265

OAuth2AccessToken token = service.getAccessToken("code");

266

} catch (FacebookAccessTokenErrorResponse e) {

267

// Access Facebook-specific error information

268

String message = e.getMessage();

269

String type = e.getType(); // "OAuthException"

270

int code = e.getCode(); // 100

271

String traceId = e.getFbTraceId(); // "DtxvtGRaxbB"

272

}

273

```

274

275

## Automatic Usage

276

277

Token extractors are automatically used by their corresponding APIs:

278

279

```java

280

// Token extractor is automatically selected based on API

281

OAuth20Service service = new ServiceBuilder("client_id")

282

.apiSecret("client_secret")

283

.build(FacebookApi.instance()); // Uses FacebookAccessTokenJsonExtractor

284

285

OAuth2AccessToken token = service.getAccessToken("code"); // Returns appropriate token type

286

```

287

288

## Complete Extractor List

289

290

| Extractor Class | API | Token Type | Special Features |

291

|----------------|-----|------------|------------------|

292

| `FacebookAccessTokenJsonExtractor` | `FacebookApi` | `OAuth2AccessToken` | Custom error handling |

293

| `SalesforceJsonTokenExtractor` | `SalesforceApi` | `SalesforceToken` | Instance URL |

294

| `OpenIdJsonTokenExtractor` | `GoogleApi20` | `OpenIdOAuth2AccessToken` | JWT ID token, claims |

295

| `SlackJsonTokenExtractor` | `SlackApi` | `SlackOAuth2AccessToken` | User access token |

296

| `FitBitJsonTokenExtractor` | `FitbitApi20` | `FitBitOAuth2AccessToken` | User ID |

297

| `PolarJsonTokenExtractor` | `PolarAPI` | `PolarOAuth2AccessToken` | User ID, X-User-ID |

298

| `VKJsonTokenExtractor` | `VkontakteApi` | `OAuth2AccessToken` | VK-specific format |

299

| `InstagramAccessTokenJsonExtractor` | `InstagramApi` | `OAuth2AccessToken` | Instagram format |

300

| `GoogleDeviceAuthorizationJsonExtractor` | `GoogleApi20` | `DeviceAuthorization` | Device flow support |

301

302

## Custom Extractor Implementation

303

304

To create a custom token extractor:

305

306

```java

307

public class CustomTokenExtractor extends OAuth2AccessTokenJsonExtractor {

308

private static final CustomTokenExtractor INSTANCE = new CustomTokenExtractor();

309

310

public static CustomTokenExtractor instance() {

311

return INSTANCE;

312

}

313

314

@Override

315

public OAuth2AccessToken extract(Response response) throws IOException {

316

JsonNode json = OBJECT_MAPPER.readTree(response.getBody());

317

318

// Extract standard fields

319

String accessToken = extractRequiredParameter(json, "access_token", response);

320

String tokenType = extractOptionalParameter(json, "token_type");

321

Integer expiresIn = extractExpiresIn(json);

322

String refreshToken = extractOptionalParameter(json, "refresh_token");

323

String scope = extractOptionalParameter(json, "scope");

324

325

// Extract custom fields

326

String customField = extractOptionalParameter(json, "custom_field");

327

328

return new CustomToken(accessToken, tokenType, expiresIn, refreshToken,

329

scope, customField, response.getBody());

330

}

331

}

332

```