Giter Site home page Giter Site logo

duolingo-dart / duolingo4d Goto Github PK

View Code? Open in Web Editor NEW
24.0 2.0 1.0 996 KB

A most easily usable Duolingo API wrapper in Dart. Duolingo4D is an open-sourced Dart library. With Duolingo4D, you can easily integrate your application with the Duolingo API. Duolingo4D is an unofficial library.

Home Page: https://pub.dev/packages/duolingo4d

License: BSD 3-Clause "New" or "Revised" License

Dart 100.00%
dart flutter library pubdev duolingo duolingo-api duolingo4d wrapper

duolingo4d's Introduction

duolingo4d

A most easily usable Duolingo API wrapper in Dart!

GitHub Gmail Line Twitter

pub package codecov Analyzer Test

1. About

Duolingo4D is an open-sourced Dart library.
With Duolingo4D, you can easily integrate your application with the Duolingo API.

Duolingo4D is an unofficial library.

Duolingo does not publish any official API references or specifications, so I reverse-engineered Duolingo by analyzing its communication content.

1.1. Supported Duolingo API

Auth Required Remarks
Manifest You can get the manifest information of Duolingo.
Version Info You can fetch metadata about the various configurations of services in Duolingo.
Authentication Authenticate user by using Duolingo registered username or email address and password.
User You can fetch detailed user information.
Overview You can fetch information on all the words user have learned in Duolingo.
Word Hint You can fetch hint information about words and sentences.
Switch Language You can switch the learning language.
Leaderboard You can get the information of leaderboard.
Dictionary You can get detailed information including discussions, audio and sample sentences associated with specific words.
Subscriptions You can get information about all following users associated with a user id.
Subscribers You can get information about all followers associated with a user id.
Follow You can follow the account associated with the user ID specified in the argument.
Unfollow You can unfollow the account associated with the user ID specified in the argument.
Shop Items You can get a list of items that can be purchased in Duolingo.
Purchase You can purchase items sold in Duoligno by spending Lingots or Gems.
Alphabets You can get alphabet information for the learning language.
Stories You can get story information for the learning language.
Achievements You can get the achievement data that the user has achieved.
Forum Topics You can get a list of forum topics related to the language you are currently learning.
Forum Topic You can get a forum topic related to the language you are currently learning and topic id.
Forum Comments You can get forum comments.
Forum Comment You can get forum comment related to the language you are currently learning and comment id.
Search Friend You can search users registered on Duolingo by search word.
Recommendations You can get recommended users on Duolingo.
Search Forum You can get search forums on Duolingo.

1.2. Introduction

1.2.1. Install Library

With Dart:

 dart pub add duolingo4d

With Flutter:

 flutter pub add duolingo4d

1.2.2. Import It

import 'package:duolingo4d/duolingo4d.dart';

1.2.3. Use Duolingo4D

The easiest way to use it is to get a singleton instance from Duolingo and call each method.

All response entities returned from the methods of Duolingo contain status codes and header information when HTTP communication is performed in internal processing.

For example, when performing the authentication process for a user, it will look like this:

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  if (authResponse.status.isNotOk) {
    // Client or Server error or something.
    authResponse.status.reasonPhrase;
    authResponse.headers;
    return;
  }

  if (authResponse.hasError) {
    // When there is an error on authentication.
    final authError = authResponse.error!;
    print(authError.code);
    print(authError.reason);

    authError.isInvalidUser; // Returns true if user is invalid.
    authError.isInvalidPassword; // Returns true if password is invalid.
    return;
  }

  // Do something if user is authenticated.
}

1.3. Using

1.3.1. Manifest

Auth Required Method JSON
manifest() Check!

You can get the manifest information of Duolingo.

This manifest information includes information about Duolingo icons and the theme and background colors used by Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final response = await duolingo.manifest();
  print(response);
}

1.3.2. Version Info API

Auth Required Method JSON
versionInfo() Check!

The Version Info API allows you to fetch metadata about the configuration of Duolingo services.
This metadata includes the TTS data used to play back the audio of the words, as well as mapping information for the languages supported by Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final versionInfoResponse = await duolingo.versionInfo();
  final ttsVoiceConfiguration = versionInfoResponse.ttsVoiceConfiguration;

  for (final voiceDirection in ttsVoiceConfiguration.voiceDirections) {
    print(voiceDirection.language);
    print(voiceDirection.voice);
  }
}

1.3.3. Authentication API

Auth Required Method JSON
authenticate({required String username, required String password}) Check!

You can use username and password to authenticate user registered with Duolingo. The registered e-mail address can be used for authentication in addition to the username.

In order to fetch the response you expect from each API that requires authentication, at first you need to use this authentication API to authenticate that the username and password entered are valid.

Note:
When a user is authenticated, the cookie information and session information for the Duolingo service is managed internally by Duolingo4D, so there is no need to be aware of this information after calling the API.

Caution:
If you try to authenticate again using information from an account that has already been authenticated, the Duolingo API will return an invalid password response.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  if (authResponse.status.isNotOk) {
    // Client or Server error or something.
    authResponse.status.reasonPhrase;
    authResponse.headers;
    return;
  }

  if (authResponse.hasError) {
    // When there is an error on authentication.
    final authError = authResponse.error!;
    print(authError.code);
    print(authError.reason);

    authError.isInvalidUser; // Returns true if user is invalid.
    authError.isInvalidPassword; // Returns true if password is invalid.
    return;
  }

  // Do something if user is authenticated.
}

1.3.4. User API

Auth Required Method JSON
user({required String userId}) Check!

From the User API, you can get detailed user information associated with the user ID.

The user ID is included in the response returned when the user authentication is completed. Please refer to the following implementation for details.

The user information also includes all the course information and skill information user have learned.

If user authentication has not been completed, data cannot be fetched.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final userResponse = await duolingo.user(userId: authResponse.userId);

  print(userResponse.name);
  print(userResponse.lingots);

  for (final course in userResponse.courses) {
    print(course.title);
    print(course.xp);
  }

  // Skill information is stored in a hierarchical structure.
  final skillBook = userResponse.currentCourse.skillBook;

  for (final chapter in skillBook.chapters) {
    for (final content in chapter.contents) {
      if (content.isAccessible) {
        print(content.name);
        print(content.proficiency);
        print(content.tipsAndNotes);
      }
    }
  }

  // If you don't like the nested structure,
  // you can use the toFlat method to make the structure flat.
  //
  // If you use the toFlat method, all the skill information that
  // exists in SkillBook will be returned as a new list.
  for (final skill in skillBook.toFlat()) {
    if (skill.isAccessible) {
      print(skill.name);
      print(skill.proficiency);
      print(skill.tipsAndNotes);
    }
  }
}

1.3.5. Overview API

Auth Required Method JSON
overview() Check!

From the Overview API, you can fetch information about all the words you have learned in the course you have selected. The details that can be retrieved about a word will vary depending on the course and word.

If user authentication has not been completed, data cannot be fetched.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final overviewResponse = await duolingo.overview();

  for (final vocabulary in overviewResponse.vocabularies) {
      print(vocabulary.word);
  }
}

1.3.6. Word Hint API

Auth Required Method JSON
wordHint({required String fromLanguage, required String learningLanguage, required String sentence}) Check!

You can fetch hint information for any word or sentence from the Word Hint API. Since the hint information is hint data managed by Duolingo, the accuracy of the translation data cannot be guaranteed.

The argument learningLanguage should be the language code corresponding to the word, and fromLanguage should be the language code corresponding to the hint. The sentence can be sentences as well as single words.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final wordHintResponse = await duolingo.wordHint(
    fromLanguage: 'en',
    learningLanguage: 'es',
    sentence: 'bolígrafos',
  );

  for (final token in wordHintResponse.tokens) {
    final headers = token.table.headers;
    for (final header in headers) {
      print(header.selected);
      print(header.token);
    }

    final rows = token.table.rows;
    for (final row in rows) {
      for (final cell in row.cells) {
        print(cell.hint);
      }
    }
  }

  // If you don't like the complex structure described above,
  // you can convert it to a simpler structure.
  print(wordHintResponse.prettify());
}

1.3.7. Switch Language API

Auth Required Method
switchLanguage({required String fromLanguage, required String learningLanguage})

The Switch Language API allows you to switch between the courses supported by Duolingo. The mapping information for the courses that can be switched using the Switch Language API can be obtained from the Version Info API.

For the argument learningLanguage, specify the language to be learned after switching. And for fromLanguage, specify the language to be used when learning that learningLanguage.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final switchLanguageResponse = await duolingo.switchLanguage(
    fromLanguage: 'es',
    learningLanguage: 'en',
  );

  print(switchLanguageResponse.statusCode);
  print(switchLanguageResponse.reasonPhrase);
}

1.3.8. Leaderboard API

Auth Required Method JSON
leaderboard({required String userId}) Check!

The Leaderboard API allows you to get information about leaderboard on Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final leaderboardResponse =
      await duolingo.leaderboard(userId: authResponse.userId);
  print(leaderboardResponse);

  final ativeThread = leaderboardResponse.activeThread;
  print(ativeThread);
  print(ativeThread.cohort);

  for (final rank in ativeThread.cohort.ranks) {
    // You can get the leaderboard ranking in ascending order of score.
    print(rank);
  }
}

1.3.9. Dictionary API

Auth Required Method JSON
dictionary({required String wordId}) Check!

Dictionary API allows you to get detailed information including discussion information associated with a particular word, URL to audio data, and sample sentences.

Specifically, you can get the information on this page on the official Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final dictionaryResponse = await duolingo.dictionary(
    wordId: 'cbdb71cdcf9e4715771206e1c0b0b94c',
  );

  print(dictionaryResponse);

  for (final alternativeForm in dictionaryResponse.alternativeForms) {
    print(alternativeForm);
  }

  for (final discussion in dictionaryResponse.relatedDiscussions) {
    print(discussion);
  }

  for (final lexeme in dictionaryResponse.relatedLexemes) {
    print(lexeme);
  }
}

1.3.10. Subscriptions API

Auth Required Method JSON
subscriptions({required String userId}) Check!

From Subscriptions API, you can get information about all following users associated with a user id.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final subscriptionsResponse = await duolingo.subscriptions(userId: 'xxxxxx');
  print(subscriptionsResponse);

  for (final followingUser in subscriptionsResponse.followingUsers) {
    print(followingUser);
  }
}

1.3.11. Subscribers API

Auth Required Method JSON
subscribers({required String userId}) Check!

From Subscribers API, you can get information about all followers associated with a user id.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final subscribersResponse = await duolingo.subscribers(
    userId: authResponse.userId,
  );

  print(subscribersResponse);

  for (final follower in subscribersResponse.followers) {
    print(follower);
  }
}

1.3.12. Follow API

Auth Required Method
follow({required String userId, required String targetUserId})

With Follow API, you can follow the account associated with the user ID specified in the argument.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final followResponse = await duolingo.follow(
    userId: authResponse.userId,
    targetUserId: 'user_id_to_follow',
  );

  print(followResponse);
}

1.3.13. Unfollow API

Auth Required Method
unfollow({required String userId, required String targetUserId})

With Unfollow API, you can unfollow the account associated with the user ID specified in the argument.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final unfollowResponse = await duolingo.unfollow(
    userId: authResponse.userId,
    targetUserId: 'user_id_to_unfollow',
  );

  print(unfollowResponse);
}

1.3.14. Shop Items API

Auth Required Method JSON
shopItems() Check!

From Shop Items API, you can get a list of items that can be purchased in Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final shopItemsResponse = await duolingo.shopItems();

  for (final product in shopItemsResponse.products) {
    print(product);
  }
}

1.3.15. Purchase API

Auth Required Method JSON
purchase({required String itemId, required String userId, required String learningLanguage}) Check!

With Purchase API, you can purchase items sold in Duoligno by spending Lingots or Gems.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final userResponse = await duolingo.user(userId: authResponse.userId);
  final shopItemsResponse = await duolingo.shopItems();

  final response = await duolingo.purchase(
    itemId: shopItemsResponse.products[0].id,
    userId: userResponse.id,
    learningLanguage: userResponse.learningLanguage,
  );

  print(response);

  if (response.isNotEstablished) {
    // It indicates purchase request was failed.
    return;
  }
}

1.3.16. Alphabets API

Auth Required Method JSON
alphabets({required String fromLanguage, required String learningLanguage}) Check!

With Alphabets API, you can get alphabet information for the learning language.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final alphabetsResponse = await duolingo.alphabets(
    fromLanguage: 'en',
    learningLanguage: 'ja',
  );

  print(alphabetsResponse);

  for (final alphabet in alphabetsResponse.alphabets) {
    print(alphabet);

    for (final group in alphabet.groups) {
      print(group);

      for (final character in group.characters) {
        if (character.isEmpty) {
          // The empty state of this character indicates a space
          // in the alphabetic table.
          continue;
        }

        print(character.value);
        print(character.transliteration);
        print(character.ttsUrl);
        print(character.proficiency);
      }
    }
  }
}

1.3.17. Stories API

Auth Required Method JSON
stories({required String fromLanguage, required String learningLanguage, IllustrationFormat format = IllustrationFormat.svg}) Check!

With Stories API, you can get story information for the learning language.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final storiesResponse = await duolingo.stories(
    fromLanguage: 'en',
    learningLanguage: 'ja',
    // You can select format in SVG, PNG and PDF.
    // The default is SVG.
    format: IllustrationFormat.png,
  );

  print(storiesResponse);

  for (final story in storiesResponse.stories) {
    print(story);
  }
}

1.3.18. Achievements API

Auth Required Method JSON
achievements({required String userId, required String fromLanguage, required String learningLanguage}) Check!

From Achievements API, you can get the achievement data that the user has achieved.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final achievementsResponse = await duolingo.achievements(
    userId: authResponse.userId,
    fromLanguage: 'en',
    learningLanguage: 'ja',
  );

  print(achievementsResponse);

  for (final achievement in achievementsResponse.achievements) {
    print(achievement);
  }
}

1.3.19. Forum Topics API

Auth Required Method JSON
forumTopics() Check!

From Forum Topics API, you can get a list of forum topics related to the language you are currently learning.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final forumTopicsResponse = await duolingo.forumTopics();
  print(forumTopicsResponse);

  for (final forumTopic in forumTopicsResponse.forumTopics) {
    print(forumTopic);
  }
}

1.3.20. Forum Topic API

Auth Required Method JSON
forumTopic({required int topicId}) Check!

From Forum Topic API, you can get a forum topic related to the language you are currently learning and topic id.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final forumTopicResponse = await duolingo.forumTopic(topicId: 909);
  print(forumTopicResponse);

  for (final comment in forumTopicResponse.comments) {
    print(comment);
  }

  for (final subtopic in forumTopicResponse.subtopics) {
    print(subtopic);
  }
}

1.3.21. Forum Comments API

Auth Required Method JSON
forumComments({int page = 0, ForumCommentsSortPattern sortPattern = ForumCommentsSortPattern.newest, int topicId = -1}) Check!

From Forum Comments API, you can get forum comments.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  // You can use this api without arguments and it's optional.
  final forumCommentsResponse = await duolingo.forumComments();
  print(forumCommentsResponse);

  if (forumCommentsResponse.hasMore) {
    for (final comment in forumCommentsResponse.comments) {
      final response = await duolingo.forumComments(
        page: 1, // The paging is supported for this API.
        sortPattern: ForumCommentsSortPattern.hot, //  You can choose sort pattern.
        topicId: comment.topic!.id, // You can get comments on specific topics.
      );

      print(response);
    }
  }
}

1.3.22. Forum Comment API

Auth Required Method JSON
forumComment({required int commentId}) Check!

From Forum Comment API, you can get forum comment related to the language you are currently learning and comment id.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final forumCommentResponse = await duolingo.forumComment(
    commentId: 1678438,
  );

  print(forumCommentResponse);

  for (final comment in forumCommentResponse.comments) {
    // This indicates a comment on a comment.
    print(comment);

    for (final nestedComment in comment.comments) {
      print(nestedComment);
    }
  }

  for (final dictionaryPath in forumCommentResponse.dictionaryPaths) {
    print(dictionaryPath.word);
    print(dictionaryPath.url);
  }
}

1.3.23. Search Friend API

Auth Required Method JSON
searchFriend({required int page, required int perPage, required String query}) Check!

With Search Friend API, you can get search users registered on Duolingo by search word.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final response = await duolingo.searchFriend(
    page: 1,
    perPage: 20,
    query: 'test',
  );

  for (final user in response.users) {
    print(user);
  }
}

1.3.24. Recommendations API

Auth Required Method JSON
recommendations({required String userId}) Check!

With Recommendations API, you can get recommended users on Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final response = await duolingo.recommendations(userId: authResponse.userId);
  print(response);

  for (final recommendation in response.recommendations) {
    print(recommendation);
    print(recommendation.user);
  }
}

1.3.25. Search Forum API

Auth Required Method JSON
searchForum({required int page, int perPage = 10, required String query}) Check!

With Search Forum API, you can search forums on Duolingo.

void main() async {
  final duolingo = Duolingo.instance;

  final authResponse = await duolingo.authenticate(
    username: 'test_username',
    password: 'test_password',
  );

  final response = await duolingo.searchForum(
    page: 1,
    perPage: 20,
    query: 'test',
  );

  print(response);

  for (final forum in response.forums) {
    print(forum);
  }
}

1.4. License

Copyright (c) 2021, Kato Shinya. All rights reserved.
Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.

1.5. More Information

Duolingo4D was designed and implemented by Kato Shinya.

duolingo4d's People

Contributors

myconsciousness avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

nghialmt

duolingo4d's Issues

認証されたDuolingoユーザーのセッション情報を取得

アプリによっては単純にDuolingo APIを使うだけではなく、
認証されたユーザーのセッションを引き継いだまま他の処理を行う場面も考えられるため、
Duolingo から認証されたDuolingoユーザーのセッション情報を返却する機能を追加する。

また、この返却されたセッション情報はDuolingo4Dの内部処理で使用するセッションオブジェクトとは別オブジェクトとし、
呼び出し側のユーザーの意志でこの新しいオブジェクトに格納されたデータは編集できない仕様とする。

Events APIを参照できる機能の追加

以下のURLを参照できる機能を追加する。

https://events-login.duolingo.com/api/2/events?available_only=true&end_range=2022-01-15T16:14:36.942Z&fields=hosts&is_featured_only=false&language_ids=ja&must_start_within_range=false&start_range=2021-12-16T16:14:36.942Z

整形済みのWord Hintを返却する機能

現状Word Hint APIのレスポンスはオリジナルのJSONをそのままラッピングして返却しているが、
このオリジナルのデータは構造がわかりにくく扱いにくい。

そのためある程度すぐに使える形式に整形したオブジェクトを返却する機能を追加する。
既存の機能はそのまま残すこととする。

Leaderboard APIを参照する機能の追加

以下のURLを参照する機能を追加する。

https://duolingo-leaderboards-prod.duolingo.com/leaderboards/7d9f5dd1-8423-491a-91f2-2532052038ce/users/557897808?client_unlocked=true

Type string is not a subtype of type bool

In json_impl.dart is this code:
@override bool getBool({ required String key, bool defaultValue = false, }) => _resource[key] ?? defaultValue;
but if _resource[key] is not type bool, it shows error

fromLanguageやlearningLanguageはキャッシュして再利用する

fromLanguageやlearningLangugeといった認証されたユーザーに紐づく情報は
キャッシュして再利用するように全体的に修正を行う。

この修正で一部のメソッドに関してrequired指定されていた引数をオプションとして定義できるように修正する。

Forum / Forum Comment APIを参照する機能の追加

以下のURLを参照する機能を追加する。

https://forum-api.duolingo.com/comments?sort_by=new&topic_id=null

topic_id が null の場合はForumのコメントリストが返却され、
特定の topic_id が指定された場合はそのトピックのコメントリストを返却する。

sort_by は hot, new, 'followed' がある。

API通信で取得したレスポンスデータをキャッシュする機能

APIから返却されたレスポンスから特定の情報だけを抽出したい場合があり、
その際にはあらかじめAPI通信が行われ結果がキャッシュされていると毎回APIを呼び出す必要がなくなる。

そのためAPI通信で取得したレスポンスデータをキャッシュする機能を追加する。
レスポンスデータをキャッシュするかどうかは呼び出し元のオプション引数で制御する。

どのタイミングでキャッシュをクリアするかは要検討。

ユーザーIDの型を文字列で標準化

Duolingo APIから返却されるユーザーIDは文字列と数値で型が混在しているが、
Duolingo4DではユーザーIDを文字列として扱うように標準化する。

type 'Null' is not a subtype of type 'String'

Unhandled exception:
type 'Null' is not a subtype of type 'String'
#0      DuolingoImpl.user (package:duolingo4d/src/duolingo_impl.dart:107:13)
#1      DuolingoImpl.authenticate (package:duolingo4d/src/duolingo_impl.dart:82:34)
<asynchronous suspension>
#2      main (file:///home/******/Documents/duolingo/bin/duolingo.dart:12:37)
<asynchronous suspension>

Code:

import 'package:duolingo4d/duolingo4d.dart';


void main() async {
  final duolingo = Duolingo.instance;

  final AuthResponse authResponse = await duolingo.authenticate(
    username: '*************',
    password: '***********',
  );

  if (authResponse.status.isNotOk) {
    // Client or Server error or something.
    authResponse.status.reasonPhrase;
    authResponse.headers;
    return;
  }

  if (authResponse.hasError) {
    // When there is an error on authentication.
    final authError = authResponse.error!;
    print(authError.code);
    print(authError.reason);

    authError.isInvalidUser; // Returns true if user is invalid.
    authError.isInvalidPassword; // Returns true if password is invalid.
    return;
  }

  // Do something if user is authenticated.
}

ディスカッションをフォロー / アンフォローする機能の追加

以下のURLを使用してディスカッションをフォロー / アンフォローすることができる機能を追加する。
どちらもPOST送信で正常に処理される。

https://forum-api.duolingo.com/comments/{commentId (like 54867020)}/watch
https://forum-api.duolingo.com/comments/{commentId (like 54867020)}/unwatch

友達の情報を取得する機能を追加

Duolingoでフォローしている友達の情報を取得する機能を追加する。
フォローしている友達のIDは leaderboard_activity APIから取得できる。

キャッシュ機能を追加してから実装したほうがいいかもしれない。

Stories APIに参照できる機能を追加

以下のURLに参照することができる機能を追加する。

https://stories.duolingo.com/api2/stories?fromLanguage=en&learningLanguage=ja&illustrationFormat=png

illustrationFormat はsvg, png, pdfに対応している。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.