<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shinya Kato</title>
    <description>The latest articles on DEV Community by Shinya Kato (@shinyakato).</description>
    <link>https://dev.to/shinyakato</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F874810%2F3bd6e607-0dd4-4509-a391-e202750f2367.jpeg</url>
      <title>DEV Community: Shinya Kato</title>
      <link>https://dev.to/shinyakato</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shinyakato"/>
    <language>en</language>
    <item>
      <title>How to Deploy Dart Functions to AWS Lambda</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Wed, 08 May 2024 07:35:25 +0000</pubDate>
      <link>https://dev.to/shinyakato/how-to-deploy-dart-functions-to-aws-lambda-4h1b</link>
      <guid>https://dev.to/shinyakato/how-to-deploy-dart-functions-to-aws-lambda-4h1b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt;, a highly popular serverless computing service, does not officially provide a &lt;a href="https://dart.dev" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; runtime, you can deploy functions created in &lt;a href="https://dart.dev" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; to &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; using the custom runtime mechanism.&lt;/p&gt;

&lt;p&gt;Deploying &lt;a href="https://dart.dev" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; functions to &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; enables you to utilize them not only within AWS Lambda but also integrate them with services like &lt;a href="https://aws.amazon.com/api-gateway/" rel="noopener noreferrer"&gt;Amazon API Gateway&lt;/a&gt;, allowing you to leverage them in &lt;a href="https://flutter.dev" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt; applications as well. This unified codebase in &lt;a href="https://dart.dev" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; offers great convenience.&lt;/p&gt;

&lt;p&gt;In this article, we will briefly introduce how to deploy &lt;a href="https://dart.dev" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; functions to &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;In this article, we will use &lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;Serverless Framework&lt;/a&gt; and &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; to deploy Dart functions to AWS Lambda. If you haven't installed them yet, please complete the installation using the following commands or links.&lt;/p&gt;

&lt;p&gt;Additionally, you'll need an AWS account and access tokens for AWS services.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Account
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com" rel="noopener noreferrer"&gt;https://aws.amazon.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Authentication Token
&lt;/h3&gt;

&lt;p&gt;Once you have generated the authentication token, set it in the environment variables as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxxxxxxxxx
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Serverless Framework
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;https://www.serverless.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Desktop
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;https://www.docker.com/products/docker-desktop/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation and Registration of Functions
&lt;/h2&gt;

&lt;p&gt;Now let's implement the Dart function to deploy it to AWS Lambda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;We'll proceed with the following structure. Details about &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;serverless.yml&lt;/code&gt; will be explained later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── Dockerfile
├── LICENSE
├── analysis_options.yaml
├── lib
│   ├── functions.dart
│   └── main.dart
├── pubspec.lock
├── pubspec.yaml
└── serverless.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installing Packages
&lt;/h3&gt;

&lt;p&gt;When deploying to AWS Lambda, you'll need to use the Dart custom runtime &lt;a href="https://pub.dev/packages/aws_lambda_dart_runtime_ns" rel="noopener noreferrer"&gt;aws_lambda_dart_runtime_ns&lt;/a&gt;. Please add it to your dependencies in &lt;code&gt;pubspec.yaml&lt;/code&gt; using the following command or manually:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/aws_lambda_dart_runtime_ns" rel="noopener noreferrer"&gt;https://pub.dev/packages/aws_lambda_dart_runtime_ns&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add aws_lambda_dart_runtime_ns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample&lt;/span&gt;

&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^3.3.4&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;aws_lambda_dart_runtime_ns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.0.13&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^3.0.0&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.24.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating a Function to Deploy to AWS Lambda
&lt;/h3&gt;

&lt;p&gt;Let's create a simple function to deploy to AWS Lambda.&lt;br&gt;
For now, let's make the function simply return the string &lt;code&gt;Hello, World!&lt;/code&gt; when called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:aws_lambda_dart_runtime_ns/aws_lambda_dart_runtime_ns.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;FunctionHandler&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;sayHelloWorld&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;FunctionHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'hello-world'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;action:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Perform various operations here such as &lt;/span&gt;
      &lt;span class="c1"&gt;// file IO, database operations, etc.&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;InvocationResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;requestId:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s"&gt;'message'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Hello, World!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To briefly explain, the &lt;code&gt;FunctionHandler&lt;/code&gt; object represents the function executed on AWS Lambda.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;name&lt;/code&gt; of &lt;code&gt;FunctionHandler&lt;/code&gt; is the required name when the function (or command) is invoked.&lt;br&gt;
Additionally, this name must be associated with the command definition in &lt;code&gt;serverless.yml&lt;/code&gt;, which will be introduced later.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;action&lt;/code&gt; of &lt;code&gt;FunctionHandler&lt;/code&gt; defines the actual behavior of the function (or command). In this example, it simply returns the message &lt;code&gt;'Hello, World!'&lt;/code&gt;, but you can perform various operations such as file operations or DB operations within &lt;code&gt;action&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;InvocationResult&lt;/code&gt; needed to be returned in &lt;code&gt;action&lt;/code&gt; represents the result of the processing. You can set any JSON data in the &lt;code&gt;body&lt;/code&gt; of &lt;code&gt;InvocationResult&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Registering the Created Function to the Custom Runtime
&lt;/h3&gt;

&lt;p&gt;Let's register the &lt;code&gt;sayHelloWorld&lt;/code&gt; function we created earlier to the custom runtime. It's very simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:aws_lambda_dart_runtime_ns/aws_lambda_dart_runtime_ns.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:sample/functions.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;invokeAwsLambdaRuntime&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sayHelloWorld&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// This is what you need to do&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When registering the created function to the custom runtime, all you need to do is call the &lt;code&gt;invokeAwsLambdaRuntime&lt;/code&gt; function and pass the functions you want to register as arguments.&lt;/p&gt;

&lt;p&gt;With this, the process of creating the function you want to register with AWS Lambda and registering it with the custom runtime is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying to AWS Lambda
&lt;/h2&gt;

&lt;p&gt;Once you've reached this point, all that's left is to deploy the program you've created to AWS Lambda.&lt;br&gt;
We'll define the &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;serverless.yml&lt;/code&gt; as follows:&lt;/p&gt;

&lt;p&gt;I'm not very knowledgeable about hardware, but it seems that using ARM-based &lt;a href="https://aws.amazon.com/blogs/aws/aws-lambda-functions-powered-by-aws-graviton2-processor-run-your-functions-on-arm-and-get-up-to-34-better-price-performance/" rel="noopener noreferrer"&gt;AWS Graviton&lt;/a&gt; makes you happy, so we'll proceed with an architecture based on arm64.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;arm64v8/dart:latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-image&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /work&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./ ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;dart pub get
&lt;span class="k"&gt;RUN &lt;/span&gt;dart compile exe ./lib/main.dart &lt;span class="nt"&gt;-o&lt;/span&gt; ./bootstrap
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x bootstrap

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; --platform=linux/arm64 public.ecr.aws/lambda/provided:latest&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-image /work/bootstrap /var/runtime/&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["dummyHandler"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the folder structure where the Dart program is located is different, please modify the &lt;code&gt;./lib/main.dart&lt;/code&gt; part accordingly.&lt;/p&gt;
&lt;h3&gt;
  
  
  serverless.yml
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample-app&lt;/span&gt;

&lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
  &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;provided&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ap-northeast-1&lt;/span&gt;
  &lt;span class="na"&gt;architecture&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arm64&lt;/span&gt;
  &lt;span class="na"&gt;ecr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;appImage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/arm64&lt;/span&gt;

&lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hello-world&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appImage&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hello-world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since there is no specific preference for the region, let's use &lt;code&gt;ap-northeast-1 (Tokyo)&lt;/code&gt; for now.&lt;/p&gt;

&lt;p&gt;When defining &lt;code&gt;functions&lt;/code&gt;, please pay attention to ensuring that the name of the &lt;code&gt;command&lt;/code&gt; matches the &lt;code&gt;name&lt;/code&gt; defined earlier for &lt;code&gt;FunctionHandler&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;Once you have configured everything, you can deploy the function you created to AWS Lambda using the following Serverless Framework command:&lt;/p&gt;

&lt;p&gt;Please make sure Docker Desktop is running before executing the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sls deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sls deploy
Running &lt;span class="s2"&gt;"serverless"&lt;/span&gt; from node_modules
&lt;span class="o"&gt;(&lt;/span&gt;node:6460&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;DEP0040] DeprecationWarning: The &lt;span class="sb"&gt;`&lt;/span&gt;punycode&lt;span class="sb"&gt;`&lt;/span&gt; module is deprecated. Please use a userland alternative instead.
&lt;span class="o"&gt;(&lt;/span&gt;Use &lt;span class="sb"&gt;`&lt;/span&gt;node &lt;span class="nt"&gt;--trace-deprecation&lt;/span&gt; ...&lt;span class="sb"&gt;`&lt;/span&gt; to show where the warning was created&lt;span class="o"&gt;)&lt;/span&gt;

Deploying sample-app to stage dev &lt;span class="o"&gt;(&lt;/span&gt;ap-northeast-1&lt;span class="o"&gt;)&lt;/span&gt;

✔ Service deployed to stack sample-app-dev &lt;span class="o"&gt;(&lt;/span&gt;32s&lt;span class="o"&gt;)&lt;/span&gt;

functions:
  hello-world: sample-app-dev-hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;The project created in this article is publicly available in the following repository. If you'd like to quickly try it out, feel free to clone or fork it and deploy it to AWS Lambda to play around with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/myConsciousness/sample-aws-lambda-with-dart-runtime" rel="noopener noreferrer"&gt;https://github.com/myConsciousness/sample-aws-lambda-with-dart-runtime&lt;/a&gt;&lt;/p&gt;

</description>
      <category>awslambda</category>
      <category>aws</category>
      <category>dart</category>
      <category>flutter</category>
    </item>
    <item>
      <title>How to Create Bluesky BOT using Dart and Firehose</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Sat, 09 Sep 2023 12:50:06 +0000</pubDate>
      <link>https://dev.to/shinyakato/how-to-create-bluesky-bot-using-dart-and-firehose-bll</link>
      <guid>https://dev.to/shinyakato/how-to-create-bluesky-bot-using-dart-and-firehose-bll</guid>
      <description>&lt;p&gt;This article shows how to create a BOT with real-time data using the &lt;strong&gt;Dart language&lt;/strong&gt; and Bluesky's &lt;strong&gt;Firehose API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From the Firehose API, you can retrieve Bluesky events that occur on a particular server in real time, allowing you to develop &lt;strong&gt;very interactive BOTs&lt;/strong&gt;. For example, a reply can be returned in real time to data that has been mentions to a specific account.&lt;/p&gt;

&lt;p&gt;After reading this article you will surely be able to create a BOT using the Firehose API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;BOTs intended to spam will be subject to account suspension.&lt;br&gt;
I will not be liable for any account suspension as a result of spamming or otherwise. Please execute with care when testing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using Package
&lt;/h2&gt;

&lt;p&gt;To easily handle the Bluesky API in Dart/Flutter, use the following package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Fstatic%2Fhash-qgm0u739%2Fimg%2Fpub-dev-icon-cover-image.png" height="400" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer" class="c-link"&gt;
          bluesky | Dart package
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The most famous and powerful Dart/Flutter library for Bluesky Social.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Ffavicon.ico%3Fhash%3Dnk4nss8c7444fg0chird9erqef2vkhb8" width="800" height="400"&gt;
        pub.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;
&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you want to learn more about &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, see following &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="noopener noreferrer"&gt;official website&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://atprotodart.com/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Fsocial_card.png" height="328" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://atprotodart.com/" rel="noopener noreferrer" class="c-link"&gt;
          AT Protocol and Bluesky Social Things for Dart and Flutter | atproto.dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Powerful suite of AT Protocol and Bluesky-related packages for Dart/Flutter
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Ffavicon.ico" width="800" height="800"&gt;
        atprotodart.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Let's install &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; with the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Import
&lt;/h2&gt;

&lt;p&gt;Basically, when you use features of the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, just add the following import.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Basic
&lt;/h2&gt;

&lt;p&gt;Let's begin with the most basic implementation for using the Firehose API with &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package. You can implement it as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anonymous&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To start with the most basic point, almost all events (likes and postings and etc) that occur on a particular server in Bluesky are &lt;strong&gt;public data&lt;/strong&gt;. In other words, the Firehose API &lt;strong&gt;does not&lt;/strong&gt; require user authentication.&lt;/p&gt;

&lt;p&gt;With the above code, Bluesky's Firehose works perfectly, &lt;strong&gt;&lt;em&gt;but&lt;/em&gt;&lt;/strong&gt; user authentication is &lt;strong&gt;always required&lt;/strong&gt; with a specific account to develop a BOT like the one we will cover in this article. This is because the BOT must be logged in with a specific account in order to respond with a reply or other action when a specific event is detected.&lt;/p&gt;

&lt;p&gt;So, we need following implementations.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//  This session is active for 120 minutes.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'username or email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Refreshed session is active for 90 days.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;refreshedSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;refreshJwt:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshJwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create an instance from authenticated session.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshedSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Comparing with the previous code, you will notice that the &lt;code&gt;.createSession&lt;/code&gt; function adds a process to authenticate the user. By passing username and password credentials to the &lt;code&gt;.createSession&lt;/code&gt; function, a Bluesky session is created and you are logged in with a specific account.&lt;/p&gt;

&lt;p&gt;But it's important to note, however, that sessions created with the &lt;code&gt;.createSession&lt;/code&gt; function are &lt;strong&gt;only valid for 120 minutes&lt;/strong&gt;. This is a somewhat unreliable time limit when using the Firehose API for long-time connections. &lt;/p&gt;

&lt;p&gt;So, let's use the &lt;code&gt;.refreshSession&lt;/code&gt; function. By passing &lt;code&gt;refreshJwt&lt;/code&gt; in the session object created by the &lt;code&gt;.createSession&lt;/code&gt; function as an argument, you can issue a session that is &lt;strong&gt;valid for 90 days&lt;/strong&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  Advanced
&lt;/h2&gt;

&lt;p&gt;Move on to the main issue! &lt;/p&gt;

&lt;p&gt;Let's create a BOT that replies with &lt;code&gt;Hello!&lt;/code&gt; if it detects a post "Say hello &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;.shinyakato.dev".&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//  This session is active for 120 minutes.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'username or email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Refreshed session is active for 90 days.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;refreshedSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;refreshJwt:&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshJwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create an instance from authenticated session.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshedSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// This is a very useful adaptor.&lt;/span&gt;
  &lt;span class="c1"&gt;// You can filter only specific events from Firehose.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;adaptor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RepoCommitAdaptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Triggered only when post is created.&lt;/span&gt;
    &lt;span class="nl"&gt;onCreatePost:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Say hello @test.shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Post a reply&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

          &lt;span class="c1"&gt;// Reply setting&lt;/span&gt;
          &lt;span class="nl"&gt;reply:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ReplyRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;root:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toStrongRef&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="nl"&gt;parent:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toStrongRef&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'said hello to &lt;/span&gt;&lt;span class="si"&gt;${data.author}&lt;/span&gt;&lt;span class="s"&gt;!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Firehose events are union type.&lt;/span&gt;
      &lt;span class="c1"&gt;// Use `USubscribedRepoCommit` to filter only commit events.&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;USubscribedRepoCommit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// Execute adaptor like this.&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;adaptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Well done, if you run this code and post "Say hello &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;.shinyakato.dev", you will instantly receive a reply saying "Hello!".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Oh no, this seems very difficult to implement!"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't worry. The implementation has increased but it's very simple.&lt;/p&gt;

&lt;p&gt;First, I describe the &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; class. The &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; class is a solution that allows troublesome commit data records to be filtered and treated as a specific type.&lt;/p&gt;

&lt;p&gt;The commit data returned from Firehose contains almost all the record data generated by Bluesky. This means that the implementer must check as to whether the content of the record is a post or a like and so on. But, this is a fairly burdensome task for implementors using Firehose... Well, &lt;strong&gt;let &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; take care of all that tedious work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;RepoCommitAdaptor&lt;/code&gt;, you can define processing directly in callbacks for specific events such as &lt;code&gt;onCreatePost&lt;/code&gt; as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// This is a very useful adaptor.&lt;/span&gt;
  &lt;span class="c1"&gt;// You can filter only specific events from Firehose.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;adaptor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RepoCommitAdaptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Triggered only when post is created.&lt;/span&gt;
    &lt;span class="nl"&gt;onCreatePost:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Do something for post data.&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In other words, this callback is executed only for events for which a post was created upon receipt of the Firehose results.&lt;/p&gt;

&lt;p&gt;The code for Firehose is then as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Firehose events are union type.&lt;/span&gt;
      &lt;span class="c1"&gt;// Use `USubscribedRepoCommit` to filter only commit events.&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;USubscribedRepoCommit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// Execute adaptor like this.&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;adaptor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As noted in the comments to the above code, the data returned from Firehose is union. But, it can be easily handled using pattern matching in Dart3.&lt;/p&gt;

&lt;p&gt;Union type names in &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package is always prefixed with &lt;strong&gt;&lt;code&gt;U&lt;/code&gt;&lt;/strong&gt;, so in this case we specify the &lt;code&gt;USubscribedRepoCommit&lt;/code&gt; class in &lt;code&gt;case&lt;/code&gt;, which represents Firehose's repo commit event.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; defined earlier is executed in a case statement. This will all be easily resolved.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;After reading this article you now understand how to use Dart and Bluesky's Firehose to create a realtime oriented BOT. Although we created a very simple BOT in this article, it's possible to create a more serviceable BOT by incorporating more complex rules. Try various things with the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package!&lt;/p&gt;

&lt;p&gt;If you are still not sure how to implement it after reading this article, please mention me on Bluesky.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://bsky.app/profile/shinyakato.dev" rel="noopener noreferrer"&gt;@shinyakato.dev&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, if you found this article useful, please give a star on GitHub repository. This is very helpful to activate the development community for &lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;

&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>bluesky</category>
      <category>atproto</category>
      <category>bot</category>
    </item>
    <item>
      <title>How to Update Your Profile from Dart/Flutter App using Bluesky API</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Tue, 15 Aug 2023 07:24:15 +0000</pubDate>
      <link>https://dev.to/shinyakato/how-to-update-your-profile-from-dartflutter-app-using-bluesky-api-5cag</link>
      <guid>https://dev.to/shinyakato/how-to-update-your-profile-from-dartflutter-app-using-bluesky-api-5cag</guid>
      <description>&lt;p&gt;This article will show you how to update your profile from a Dart/Flutter application using the &lt;strong&gt;Bluesky API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By reading this article, you will be able to easily update your Bluesky profile in your Dart/Flutter app from the Bluesky API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Package
&lt;/h2&gt;

&lt;p&gt;To easily handle the Bluesky API in Dart/Flutter, use the following package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Fstatic%2Fhash-qgm0u739%2Fimg%2Fpub-dev-icon-cover-image.png" height="400" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer" class="c-link"&gt;
          bluesky | Dart package
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The most famous and powerful Dart/Flutter library for Bluesky Social.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Ffavicon.ico%3Fhash%3Dnk4nss8c7444fg0chird9erqef2vkhb8" width="800" height="400"&gt;
        pub.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;
&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you want to learn more about &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, see following &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="noopener noreferrer"&gt;official website&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://atprotodart.com/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Fsocial_card.png" height="328" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://atprotodart.com/" rel="noopener noreferrer" class="c-link"&gt;
          AT Protocol and Bluesky Social Things for Dart and Flutter | atproto.dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Powerful suite of AT Protocol and Bluesky-related packages for Dart/Flutter
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Ffavicon.ico" width="800" height="800"&gt;
        atprotodart.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Let's install &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; with the following commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Dart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;With Flutter:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Import
&lt;/h2&gt;

&lt;p&gt;Basically, when you use features of the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, just add the following import.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Implement
&lt;/h2&gt;

&lt;p&gt;We will implement, but let's start with a very simple step. The following example shows the process for updating the &lt;code&gt;displayName&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; of an authenticated user.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to update a Bluesky profile, you must of course be authorized to update the information for the account you are updating, so be sure to authenticate using the &lt;code&gt;createSession&lt;/code&gt; function. You can see more details about authentication on &lt;strong&gt;&lt;a href="https://atprotodart.com/docs/packages/bluesky#instantiate-bluesky" rel="noopener noreferrer"&gt;official document&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;actors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;displayName:&lt;/span&gt; &lt;span class="s"&gt;'Alf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="s"&gt;'This is my new profile.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As shown in the code above, to update the Bluesky profile of an authenticated user using the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, use the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html" rel="noopener noreferrer"&gt;&lt;code&gt;.updateProfile&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method of the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService-class.html" rel="noopener noreferrer"&gt;ActorsService&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, all you have to do to update your Bluesky profile using the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package is call the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html" rel="noopener noreferrer"&gt;&lt;code&gt;.updateProfile&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method.&lt;/p&gt;

&lt;p&gt;The above example only updates the &lt;code&gt;displayName&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;, but the following items can be updated.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;displayName&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A logical name for the profile.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;descriotion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A description of the account that will be set up in the profile.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;avatar&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An image that symbolizes the account that is set in the profile.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;banner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A banner image to be set in the profile.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;labels&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An optional tag set for the account.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Setting up a profile picture and label is a bit more difficult than setting up a &lt;code&gt;displayName&lt;/code&gt; or &lt;code&gt;description&lt;/code&gt;, so we will look at that in the next section.&lt;/p&gt;
&lt;h2&gt;
  
  
  Update Avatar and Banner
&lt;/h2&gt;

&lt;p&gt;To update your &lt;code&gt;avatar&lt;/code&gt; or &lt;code&gt;banner&lt;/code&gt;, you must first upload the binary data of the image you wish to set to the server. To upload binary data of images to the server, implement the following.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:io'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Get image file to be uploaded.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'./funny_photo.png'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Upload here.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;uploaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadBlob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAsBytesSync&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As shown in the code above, the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/RepositoriesService/uploadBlob.html" rel="noopener noreferrer"&gt;&lt;code&gt;.uploadBlob&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method of the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/RepositoriesService-class.html" rel="noopener noreferrer"&gt;RepositoriesService&lt;/a&gt;&lt;/strong&gt; is used to upload the binary data. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bluesky Social only supports static images at the time of this writing, but the AT Protocol allows for the upload of binary data in any format.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a successful upload, you will get a &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/Blob-class.html" rel="noopener noreferrer"&gt;&lt;code&gt;Blob&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; object to pass to the &lt;code&gt;avatar&lt;/code&gt; parameter when updating your profile image. All that remains is to pass a &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/Blob-class.html" rel="noopener noreferrer"&gt;&lt;code&gt;Blob&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; object to the &lt;code&gt;avatar&lt;/code&gt; parameter as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:io'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'./funny_photo.png'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;uploaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadBlob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAsBytesSync&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;actors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;displayName:&lt;/span&gt; &lt;span class="s"&gt;'Alf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="s"&gt;'This is my new profile.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// Pass like this.&lt;/span&gt;
    &lt;span class="nl"&gt;avatar:&lt;/span&gt; &lt;span class="n"&gt;uploaded&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;banner&lt;/code&gt; parameter can also be implemented in exactly the same way as above.&lt;/p&gt;
&lt;h2&gt;
  
  
  Set Labels
&lt;/h2&gt;

&lt;p&gt;You can set any tags, called a &lt;strong&gt;label&lt;/strong&gt;, to your profile in Bluesky. It is up to you to decide what kind of tags you want to set in your profile, and you can set any string of characters.&lt;/p&gt;

&lt;p&gt;And setting up a label for your profile is easier than uploading an image. It can be implemented as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;actors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;displayName:&lt;/span&gt; &lt;span class="s"&gt;'Alf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="s"&gt;'This is my new profile.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// Add like this.&lt;/span&gt;
    &lt;span class="nl"&gt;labels:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Labels&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;selfLabels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SelfLabels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;values:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SelfLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="s"&gt;'developer'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SelfLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="s"&gt;'flutterdev'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The structure of the objects passed to the &lt;code&gt;labels&lt;/code&gt; parameter is somewhat complex, but not as laborious as the upload process. As you can see in the code above, you can set any number of strings as labels.&lt;/p&gt;

&lt;p&gt;But well, let's make the implementation just a little more generic.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;/// Labels to be set.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;[&lt;/span&gt;
  &lt;span class="s"&gt;'developer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;'flutterdev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;actors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;displayName:&lt;/span&gt; &lt;span class="s"&gt;'Alf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="s"&gt;'This is my new profile.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nl"&gt;labels:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Labels&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;selfLabels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SelfLabels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c1"&gt;// Fix like this.&lt;/span&gt;
        &lt;span class="nl"&gt;values:&lt;/span&gt; &lt;span class="n"&gt;_labels&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SelfLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Advanced
&lt;/h2&gt;

&lt;p&gt;So far you have learned how to update your Bluesky profile using the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, but there is one more thing to consider in order to actually use the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html" rel="noopener noreferrer"&gt;&lt;code&gt;.updateProfile&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method in your Dart/ Flutter app.&lt;/p&gt;

&lt;p&gt;Although it is not explicitly shown even in the &lt;a href="https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/actor/profile.json" rel="noopener noreferrer"&gt;official Lexicon&lt;/a&gt;, a parameter set as &lt;code&gt;null&lt;/code&gt; using the &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html" rel="noopener noreferrer"&gt;&lt;code&gt;.updateProfile&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; method sets the authenticated user's profile data as &lt;code&gt;null&lt;/code&gt;. In other words, if you try to update only a specific item and pass the other parameters as &lt;code&gt;null&lt;/code&gt;, the profile data for the item associated with the parameter passed as &lt;code&gt;null&lt;/code&gt; will be deleted.&lt;/p&gt;

&lt;p&gt;So, you must &lt;strong&gt;&lt;em&gt;always&lt;/em&gt;&lt;/strong&gt; pass specific values to &lt;strong&gt;&lt;a href="https://pub.dev/documentation/bluesky/latest/bluesky/ActorsService/updateProfile.html" rel="noopener noreferrer"&gt;&lt;code&gt;.updateProfile&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; for parameters other than the item to be deleted, unless the user explicitly takes action to delete a specific item.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt;, the problem here is that it is somewhat difficult to find a way to retrieve the uploaded &lt;code&gt;avatar&lt;/code&gt; and &lt;code&gt;banner&lt;/code&gt; binary data again. You can implement it as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// The AT Uri for authenticated user's profile.&lt;/span&gt;
  &lt;span class="c1"&gt;// The format can be used as is.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;profileUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AtUri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;did&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'app.bsky.actor.profile'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'self'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Get profile record.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;uri:&lt;/span&gt; &lt;span class="n"&gt;profileUri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// And parse value to `ProfileRecord`.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ProfileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Very safe update.&lt;/span&gt;
  &lt;span class="c1"&gt;// Replace the item you wish to update with a specific variable.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;actors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;displayName:&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;avatar:&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;banner:&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;banner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;labels:&lt;/span&gt; &lt;span class="n"&gt;profileRecord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using the above code as a base, you can update your profile very safely. &lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now that you have somewhat understood how to update your Bluesky profile from the Dart/Flutter app using the &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package, you can use it to update your Bluesky profile from the Dart/Flutter app. You have also learned that updating your profile using the Bluesky API may seem easy, but in reality it requires some technique.&lt;/p&gt;

&lt;p&gt;If you are still not sure how to implement it after reading this article, please mention me at Bluesky.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://bsky.app/profile/shinyakato.dev" rel="noopener noreferrer"&gt;@shinyakato.dev&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, if you found this article useful, please star the following repositories where &lt;strong&gt;&lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/strong&gt; package are developed. This is very helpful to activate the development community.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgrjw519mio133trbbta.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgrjw519mio133trbbta.gif" alt="github_star" width="1080" height="281"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;

&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>bluesky</category>
      <category>api</category>
    </item>
    <item>
      <title>Let's Post to Bluesky Social easily with Dart and Flutter</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Thu, 15 Jun 2023 00:54:00 +0000</pubDate>
      <link>https://dev.to/shinyakato/lets-post-to-bluesky-social-easily-with-dart-and-flutter-dj5</link>
      <guid>https://dev.to/shinyakato/lets-post-to-bluesky-social-easily-with-dart-and-flutter-dj5</guid>
      <description>&lt;p&gt;As already noted by many media articles, &lt;strong&gt;Bluesky Social&lt;/strong&gt; is a decentralized social networking service with a Twitter-like UI. Bluesky Social is built on a next-generation common infrastructure called the &lt;strong&gt;AT Protocol&lt;/strong&gt;, and the road ahead is very ambitious and full of unknown possibilities.&lt;/p&gt;

&lt;p&gt;This article mainly shows how to post to Bluesky Social from the API in &lt;strong&gt;Dart language&lt;/strong&gt;. I will not actively present the implementation in &lt;strong&gt;Flutter&lt;/strong&gt;, but you can apply the same procedure in &lt;strong&gt;Flutter&lt;/strong&gt; by reading this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Dart?
&lt;/h2&gt;

&lt;p&gt;For those who are not familiar with the Dart language, Dart is a relatively new programming language developed by Google. Dart has a syntax similar to Java and C, but with modern language specifications such as null safety. Above all, &lt;strong&gt;Flutter&lt;/strong&gt; is probably the reason Dart is getting the most attention.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://dart.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdart.dev%2Fassets%2Fimg%2Flogo%2Fdart-logo-for-shares.png%3F2" height="449" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://dart.dev/" rel="noopener noreferrer" class="c-link"&gt;
          Dart programming language | Dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Dart is an approachable, portable, and productive language for high-quality apps on any platform.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdart.dev%2Fassets%2Fimg%2Flogo%2Fdart-64.png" width="64" height="64"&gt;
        dart.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://flutter.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fcms-storage-bucket%2F70760bf1e88b184bb1bc.png" height="393" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://flutter.dev/" rel="noopener noreferrer" class="c-link"&gt;
          
      
        
          
        
      
      
        Flutter - Build apps for any screen
      
    
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Flutter transforms the entire app development process. Build, test, and deploy beautiful mobile, web, desktop, and embedded apps from a single codebase.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fcms-storage-bucket%2F4fd0db61df0567c0f352.png" width="64" height="64"&gt;
        flutter.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;There is already a powerful package that makes it easy to use Bluesky Social's API with Dart and Flutter, and this article will present sample code using that package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Package
&lt;/h2&gt;

&lt;p&gt;To easily use Bluesky Social's API in Dart or Flutter, use the package &lt;code&gt;bluesky&lt;/code&gt;. I develop and maintain this package and it already &lt;strong&gt;supports almost all endpoints&lt;/strong&gt;, is &lt;strong&gt;well tested&lt;/strong&gt; and &lt;strong&gt;very stable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is already being used in several third-party apps, and I highly recommend this package for your Bluesky Social-related apps in Dart or Flutter.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Fstatic%2Fhash-qgm0u739%2Fimg%2Fpub-dev-icon-cover-image.png" height="400" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer" class="c-link"&gt;
          bluesky | Dart package
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The most famous and powerful Dart/Flutter library for Bluesky Social.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Ffavicon.ico%3Fhash%3Dnk4nss8c7444fg0chird9erqef2vkhb8" width="800" height="400"&gt;
        pub.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Or you can see more details in in following official page.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://atprotodart.com/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Fsocial_card.png" height="328" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://atprotodart.com/" rel="noopener noreferrer" class="c-link"&gt;
          AT Protocol and Bluesky Social Things for Dart and Flutter | atproto.dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Powerful suite of AT Protocol and Bluesky-related packages for Dart/Flutter
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Ffavicon.ico" width="800" height="800"&gt;
        atprotodart.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Well, let's install this package with following commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Dart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;With Flutter:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And let's check your &lt;code&gt;pubspec.yaml&lt;/code&gt; in your Dart or Flutter app. It is successful if it looks like this and this article uses &lt;code&gt;bluesky v0.6.0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bluesky_post&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A sample command-line application.&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^3.0.0&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bluesky&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.6.0&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.0.0&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.21.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's Post!
&lt;/h2&gt;

&lt;p&gt;The easiest way to post to Bluesky Social using the &lt;code&gt;bluesky&lt;/code&gt; package is as follows. The following example simply posts any text.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//! You need to be authenticated by credentials.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Create Bluesky from session data.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! StrongRef&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I previously wrote &lt;a href="https://dev.to/shinyakato/easily-use-firehose-api-on-bluesky-social-with-dart-and-flutter-mdk"&gt;an article about using the Firehose API&lt;/a&gt; with the &lt;code&gt;bluesky&lt;/code&gt; package, which did not require credentials. However, the endpoint you will be using to post to Bluesky Social &lt;strong&gt;will always require&lt;/strong&gt; your credentials.&lt;/p&gt;

&lt;p&gt;For example, the above example uses the &lt;code&gt;createSession&lt;/code&gt; method to authenticate with the &lt;code&gt;bsky.social&lt;/code&gt; server using your credentials. If the authentication fails, an error is returned by &lt;code&gt;bsky.social&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As a side note, if you have an account on a server other than &lt;code&gt;bsky.social&lt;/code&gt;, you can specify any server as follows:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;service:&lt;/span&gt; &lt;span class="s"&gt;'stem.social'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, an instance of the &lt;code&gt;Bluesky&lt;/code&gt; object, which is required to use the &lt;code&gt;bluesky&lt;/code&gt; package, is created using the &lt;code&gt;.fromSession&lt;/code&gt; constructor. The &lt;code&gt;.fromSession&lt;/code&gt; constructor can be used to create a &lt;code&gt;Bluesky&lt;/code&gt; object from a &lt;code&gt;Session&lt;/code&gt; object without over or under creating it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Okay now, if you could get session and &lt;code&gt;Bluesky&lt;/code&gt; object from session, all you need to do is post any text with the following code.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With just this, you can send any post to Bluesky Social! The data returned from the &lt;code&gt;createPost&lt;/code&gt; method is a reference to the actual data generated. It is represented on the &lt;strong&gt;AT Protocol&lt;/strong&gt; as &lt;code&gt;StrongRef&lt;/code&gt; and consists of an &lt;strong&gt;AT URI&lt;/strong&gt; and &lt;strong&gt;CID link&lt;/strong&gt; to the generated data.&lt;/p&gt;

&lt;p&gt;Also, although not in the above code, you can delete a generated Post or other record from the &lt;strong&gt;AT URI&lt;/strong&gt; as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;//! Delete any records.&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;uri:&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Post with Images
&lt;/h2&gt;

&lt;p&gt;Now that you know how to use the &lt;code&gt;bluesky&lt;/code&gt; package to post arbitrary text to Bluesky Social, it would be useful to be able to attach images and such when actually using it.&lt;/p&gt;

&lt;p&gt;Basically, in order to attach an image to a particular piece of content, you must first upload that image data and then POST the uploaded data in Multipart format. However, with the &lt;code&gt;bluesky&lt;/code&gt; package, you don't have to be aware of these difficult processes at all.&lt;/p&gt;

&lt;p&gt;Well, you can send a post with an image by doing the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:io'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Upload photo!&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;uploaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadBlob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'./funny_photo.jpg'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readAsBytesSync&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// File bytes&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//! Add it.&lt;/span&gt;
    &lt;span class="nl"&gt;embed:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EmbedImages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;images:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;alt:&lt;/span&gt; &lt;span class="s"&gt;'This is my funny photo!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;image:&lt;/span&gt; &lt;span class="n"&gt;uploaded&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The above example shows that it is very easy to send a post with an image.&lt;/p&gt;

&lt;p&gt;All you have to do is upload an arbitrary image file using the &lt;code&gt;uploadBlob&lt;/code&gt; method, and pass the uploaded Blob data to the &lt;code&gt;embed&lt;/code&gt; parameter of &lt;code&gt;createPost&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quote the Post
&lt;/h2&gt;

&lt;p&gt;You can also quote a post that has already been submitted easily as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Let's use this post as quote.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'This will be quoted.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//! Add it.&lt;/span&gt;
    &lt;span class="nl"&gt;embed:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EmbedRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;ref:&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Attach a Link Card to an External Site
&lt;/h2&gt;

&lt;p&gt;When using Bluesky's API to embed a post with a link card from an external site, you will need to configure that link card yourself. The &lt;code&gt;bluesky&lt;/code&gt; package makes it easy to set up.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//! Add it.&lt;/span&gt;
    &lt;span class="nl"&gt;embed:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Embed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EmbedExternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;external&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EmbedExternalThumbnail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;uri:&lt;/span&gt; &lt;span class="s"&gt;'https://shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'Shinya Kato'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;description:&lt;/span&gt; &lt;span class="s"&gt;'This is my site!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Reply to a Specific Post
&lt;/h2&gt;

&lt;p&gt;Replying to a specific post is a basic feature. Using the &lt;code&gt;bluesky&lt;/code&gt; package, you can reply as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Let's reply to this post.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Reply to me'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Hello, Bluesky!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//! Add this.&lt;/span&gt;
    &lt;span class="nl"&gt;reply:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ReplyRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;root:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;parent:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With the above codes, you can easily reply to a specific post!&lt;/p&gt;

&lt;p&gt;And you may have noticed that the &lt;code&gt;ReplyRef&lt;/code&gt; object has two arguments, &lt;code&gt;root&lt;/code&gt; and &lt;code&gt;parent&lt;/code&gt;. With these arguments, you can create a thread, but if you simply want to create a series of threads, the &lt;code&gt;bluesky&lt;/code&gt; package provides an easier way.&lt;/p&gt;

&lt;p&gt;Let's use &lt;code&gt;createThread&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Let's reply to this post.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createThread&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ThreadParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'First post'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ThreadParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Second post'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ThreadParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'Third post'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;//! This is the root ref from first post.&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using &lt;code&gt;createThread&lt;/code&gt;, it is very easy to create a series of threads.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mentions and Links
&lt;/h2&gt;

&lt;p&gt;In services similar to &lt;strong&gt;Bluesky&lt;/strong&gt;, such as Twitter and Mastodon, &lt;strong&gt;mentions&lt;/strong&gt; and &lt;strong&gt;hyperlinks&lt;/strong&gt; in the text are automatically set up without any special attention. However, &lt;strong&gt;this is not the case at Bluesky&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, how would the status of this post appear on Bluesky's UI if the previous code were modified as follows?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'I am @shinyakato.dev! Check https://shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The answer is, it will post the raw &lt;code&gt;I am @shinyakato.dev! Check https://shinyakato.dev&lt;/code&gt; text with no link set in the mentions and hyperlinks.&lt;/p&gt;

&lt;p&gt;So, if you are asking if you can't set up links in the Bluesky API, of course you can! You just need to set a special parameter called &lt;strong&gt;facet&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Modify the &lt;code&gt;createPost&lt;/code&gt; method in the previous example as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="s"&gt;'I am @shinyakato.dev! Check https://shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;//! Set Facets.&lt;/span&gt;
  &lt;span class="nl"&gt;facets:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;//! Facet for mention like "@shinyakato.dev"&lt;/span&gt;
    &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Facet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;index:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ByteSlice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;byteStart:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;byteEnd:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;features:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FacetFeature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FacetMention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;did:&lt;/span&gt; &lt;span class="s"&gt;'did:plc:iijrtk7ocored6zuziwmqq3c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="c1"&gt;//! Facet for link like "https://shinyakato.dev"&lt;/span&gt;
    &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Facet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;index:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ByteSlice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;byteStart:&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;byteEnd:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;features:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FacetFeature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FacetLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;uri:&lt;/span&gt; &lt;span class="s"&gt;'https://shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Setting up this &lt;strong&gt;facet&lt;/strong&gt; is one of the most difficult operations to enable &lt;strong&gt;mentions&lt;/strong&gt; and &lt;strong&gt;hyperlinks&lt;/strong&gt; using the Bluesky API.&lt;/p&gt;

&lt;p&gt;The mechanics are simple, but you need to define the &lt;strong&gt;ByteSlice&lt;/strong&gt; as the start and end position of the specific token you want to link to, such as a &lt;strong&gt;mentions&lt;/strong&gt; or &lt;strong&gt;hyperlinks&lt;/strong&gt; in the text, and even how you want the link to be placed as &lt;code&gt;features&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In other words, &lt;strong&gt;this mechanism can be used to create a link that is completely different from the mentions or hyperlinks contained in the text&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;However, I feel many people simply want mentions and hyperlinks like those offered by Twitter and Mastodon. Is there an easier solution to this complicated &lt;strong&gt;facet&lt;/strong&gt;? Of course there is! But use the &lt;code&gt;bluesky_text&lt;/code&gt; package, which is different from the &lt;code&gt;bluesky&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;Let's check how to use &lt;code&gt;bluesky_text&lt;/code&gt; in the next section!&lt;/p&gt;
&lt;h2&gt;
  
  
  Use &lt;code&gt;bluesky_text&lt;/code&gt; for Easy &lt;code&gt;facet&lt;/code&gt; Resolution
&lt;/h2&gt;

&lt;p&gt;As mentioned in the previous section, activating links in text using the Bluesky API requires a &lt;strong&gt;facet&lt;/strong&gt; setting, which is a somewhat difficult operation. If you need simple mentions and hyperlinks like Twitter or Mastodon, use &lt;code&gt;bluesky_text&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;bluesky_text&lt;/code&gt; is another package I am developing, designed to integrate very easily with the &lt;code&gt;bluesky&lt;/code&gt; package.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pub.dev/packages/bluesky_text" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Fstatic%2Fhash-qgm0u739%2Fimg%2Fpub-dev-icon-cover-image.png" height="400" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pub.dev/packages/bluesky_text" rel="noopener noreferrer" class="c-link"&gt;
          bluesky_text | Dart package
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Provides the easiest and most powerful way to analyze the text for Bluesky Social.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Ffavicon.ico%3Fhash%3Dnk4nss8c7444fg0chird9erqef2vkhb8" width="800" height="400"&gt;
        pub.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;And install it like &lt;code&gt;bluesky&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Dart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add bluesky_text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;With Flutter:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub add bluesky_text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It is successful if it looks like this in your &lt;code&gt;pubspec.yaml&lt;/code&gt; and this article uses &lt;code&gt;bluesky_text v0.2.2&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bluesky_post&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A sample command-line application.&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^3.0.0&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bluesky&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.6.0&lt;/span&gt;
  &lt;span class="na"&gt;bluesky_text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.2.2&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.0.0&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.21.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Okay let's modify the complex &lt;strong&gt;facet&lt;/strong&gt; setup process described earlier as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky_text/bluesky_text.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;identifier:&lt;/span&gt; &lt;span class="s"&gt;'HANDLE_OR_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="s"&gt;'PASSWORD_OR_APP_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Just pass text to BlueskyText.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BlueskyText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'I am @shinyakato.dev! Check https://shinyakato.dev'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//! Extract all the mentions and hyperlinks in the text&lt;/span&gt;
  &lt;span class="c1"&gt;//! and get the facet as JSON.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;facets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toFacets&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;feeds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;//! This is the text you passed to BlueskyText.&lt;/span&gt;
    &lt;span class="nl"&gt;text:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;//! Convert to Facet objects.&lt;/span&gt;
    &lt;span class="nl"&gt;facets:&lt;/span&gt; &lt;span class="n"&gt;facets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Facet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Where the heck did the difficult &lt;strong&gt;facet&lt;/strong&gt; process of a few minutes ago disappear to?! This is &lt;code&gt;bluesky_text&lt;/code&gt; magic, all you have to do is just pass the text you want to post to the constructor when you create an instance of the &lt;strong&gt;BlueskyText&lt;/strong&gt; object and call &lt;code&gt;.entities.toFacet()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With just this, you can retrieve facet data contained in the text. Then, to post using the &lt;code&gt;bluesky&lt;/code&gt; package, convert the JSON retrieved from &lt;code&gt;toFacet()&lt;/code&gt; into a &lt;code&gt;Facet&lt;/code&gt; object with &lt;code&gt;facets.map(bsky.Facet.fromJson).toList()&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is how to post to Bluesky Social using the &lt;code&gt;bluesky&lt;/code&gt; package. I also introduced a simple solution for &lt;code&gt;facet&lt;/code&gt;, which is difficult to configure when using the Bluesky API, using the &lt;code&gt;bluesky_text&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;This article mainly touches on the Dart implementation and omits the Flutter implementation, but the &lt;code&gt;bluesky&lt;/code&gt; and &lt;code&gt;bluesky_text&lt;/code&gt; packages can also be used in Flutter apps. The implementation method is the same as described in this article and will be easily integrated into your Flutter app!&lt;/p&gt;

&lt;p&gt;In addition to the &lt;code&gt;bluesky&lt;/code&gt; package and &lt;code&gt;bluesky_text&lt;/code&gt; I have presented here, I have also developed many AT Protocol related packages for Dart/Flutter in the following monorepo. If you are interested in AT Protocol related packages for Dart/Flutter, please check it out!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;

&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Suggestions for improvements and pull requests are also very welcome. Or you can contact me on Bluesky :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bsky.app/profile/shinyakato.dev" rel="noopener noreferrer"&gt;https://bsky.app/profile/shinyakato.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>bluesky</category>
      <category>api</category>
    </item>
    <item>
      <title>Easily use Firehose API on Bluesky Social with Dart and Flutter</title>
      <dc:creator>Shinya Kato</dc:creator>
      <pubDate>Tue, 06 Jun 2023 13:25:55 +0000</pubDate>
      <link>https://dev.to/shinyakato/easily-use-firehose-api-on-bluesky-social-with-dart-and-flutter-mdk</link>
      <guid>https://dev.to/shinyakato/easily-use-firehose-api-on-bluesky-social-with-dart-and-flutter-mdk</guid>
      <description>&lt;p&gt;As already noted by many media articles, &lt;strong&gt;Bluesky Social&lt;/strong&gt; is a decentralized social networking service with a Twitter-like UI. Bluesky Social is built on a next-generation common infrastructure called the &lt;strong&gt;AT Protocol&lt;/strong&gt;, and the road ahead is very ambitious and full of unknown possibilities.&lt;/p&gt;

&lt;p&gt;Now, I will introduce the &lt;strong&gt;Firehose API&lt;/strong&gt;, one of the APIs related to Bluesky Social, and how to use it easily with the &lt;strong&gt;Dart language&lt;/strong&gt;. Bluesky Social's Firehose API is a very powerful Stream API that allows you to retrieve almost any event occurring on a particular server in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Dart?
&lt;/h2&gt;

&lt;p&gt;For those who are not familiar with the Dart language, Dart is a relatively new programming language developed by Google. Dart has a syntax similar to Java and C, but with modern language specifications such as null safety. Above all, &lt;strong&gt;Flutter&lt;/strong&gt; is probably the reason Dart is getting the most attention.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://dart.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdart.dev%2Fassets%2Fimg%2Flogo%2Fdart-logo-for-shares.png%3F2" height="449" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://dart.dev/" rel="noopener noreferrer" class="c-link"&gt;
          Dart programming language | Dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Dart is an approachable, portable, and productive language for high-quality apps on any platform.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdart.dev%2Fassets%2Fimg%2Flogo%2Fdart-64.png" width="64" height="64"&gt;
        dart.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://flutter.dev/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fcms-storage-bucket%2F70760bf1e88b184bb1bc.png" height="393" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://flutter.dev/" rel="noopener noreferrer" class="c-link"&gt;
          
      
        
          
        
      
      
        Flutter - Build apps for any screen
      
    
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Flutter transforms the entire app development process. Build, test, and deploy beautiful mobile, web, desktop, and embedded apps from a single codebase.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fcms-storage-bucket%2F4fd0db61df0567c0f352.png" width="64" height="64"&gt;
        flutter.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Well, there is already a powerful package that makes it easy to use Bluesky Social's API with Dart and Flutter, and this article will present sample code using that package!&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Package
&lt;/h2&gt;

&lt;p&gt;To easily use Bluesky Social's API in Dart or Flutter, use the package &lt;code&gt;bluesky&lt;/code&gt;. I develop and maintain this package and it already &lt;strong&gt;supports almost all endpoints&lt;/strong&gt;, is &lt;strong&gt;well tested&lt;/strong&gt; and &lt;strong&gt;very stable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is already being used in several third-party apps, and I highly recommend this package for your Bluesky Social-related apps in Dart or Flutter.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Fstatic%2Fhash-qgm0u739%2Fimg%2Fpub-dev-icon-cover-image.png" height="400" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pub.dev/packages/bluesky" rel="noopener noreferrer" class="c-link"&gt;
          bluesky | Dart package
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The most famous and powerful Dart/Flutter library for Bluesky Social.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpub.dev%2Ffavicon.ico%3Fhash%3Dnk4nss8c7444fg0chird9erqef2vkhb8" width="800" height="400"&gt;
        pub.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Or you can see more details in in following official page.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://atprotodart.com/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Fsocial_card.png" height="328" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://atprotodart.com/" rel="noopener noreferrer" class="c-link"&gt;
          AT Protocol and Bluesky Social Things for Dart and Flutter | atproto.dart
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Powerful suite of AT Protocol and Bluesky-related packages for Dart/Flutter
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fatprotodart.com%2Fimg%2Ffavicon.ico" width="800" height="800"&gt;
        atprotodart.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Well, let's install this package with following commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Dart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;With Flutter:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub add bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And let's check your &lt;code&gt;pubspec.yaml&lt;/code&gt; in your Dart or Flutter app. It is successful if it looks like this and this article uses &lt;code&gt;bluesky v0.5.7&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bluesky_firehose&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A sample command-line application.&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^3.0.0&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bluesky&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.5.7&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.0.0&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.21.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's Use Firehose API
&lt;/h2&gt;

&lt;p&gt;Now all that is left is to actually use the Firehose API with the &lt;code&gt;bluesky&lt;/code&gt; package! The &lt;code&gt;bluesky&lt;/code&gt; package makes it easy to connect to Bluesky Social's Firehose API as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anonymous&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;commit:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nl"&gt;handle:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;migrate:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;tombstone:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;info:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;unknown:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Very simple, right?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you &lt;code&gt;dart run&lt;/code&gt; the above Dart program, you will see the events occurring in &lt;code&gt;bsky.social&lt;/code&gt; streaming in real time like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;at://did:plc:cojuqgrp6syogwzytq3p5zdq/app.bsky.graph.follow/3jxsejsfjas2n
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.graph.follow, subject: did:plc:pwm3nal7z4sht4id6wniiahv, createdAt: 2023-06-10T08:53:45.050Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:vopt5zssk6uotcsgnimyuiy3/app.bsky.feed.like/3jxsejsgnev2t
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.feed.like, subject: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreihoge573pwtux4dgedovmtitnwdnibvekrr7nvqs3qjbnrplnsvxq, uri: at://did:plc:awnhnq23opcufc2rnqbggjnp/app.bsky.feed.post/3jxsdpbessq2s&lt;span class="o"&gt;}&lt;/span&gt;, createdAt: 2023-06-10T08:53:44.841Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:njyxpfp2rzb7addisbq74epa/app.bsky.graph.follow/3jxsejskzz72r
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.graph.follow, subject: did:plc:uo2g6reoqnrudyoeotwveuc2, createdAt: 2023-06-10T08:53:45.453Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:b4td4mpmhj76dwdqrds72p4p/app.bsky.feed.like/3jxsejsnh5q2h
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.feed.like, subject: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreienlb76pav7d4gvdpy5opmllldhjongwnmmkkrjof5cg4olawe4he, uri: at://did:plc:sho65umi6t4ohqyaijutbdcr/app.bsky.feed.post/3jxs56p2ost2l&lt;span class="o"&gt;}&lt;/span&gt;, createdAt: 2023-06-10T08:53:45.491Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:64kdoplv62s6veonqincpgod/app.bsky.feed.post/3jxsejsib5h2r
&lt;span class="o"&gt;{&lt;/span&gt;text: How long was this &lt;span class="k"&gt;in &lt;/span&gt;here &lt;span class="k"&gt;for &lt;/span&gt;that this happened?, &lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.feed.post, embed: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.embed.recordWithMedia, media: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.embed.images, images: &lt;span class="o"&gt;[{&lt;/span&gt;alt: , image: &lt;span class="o"&gt;{&lt;/span&gt;ref: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$link&lt;/span&gt;: bafkreiddranx4ph7m53cdpiwme5g4zjuo4djaapdychlc6nm46ogyod2zi&lt;span class="o"&gt;}&lt;/span&gt;, size: 876186, &lt;span class="nv"&gt;$type&lt;/span&gt;: blob, mimeType: image/jpeg&lt;span class="o"&gt;}}]}&lt;/span&gt;, record: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.embed.record, record: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreifbe7p5fozzx4ualnrspqqfsfs2xoas4r2ambxjstcdkji3i7tq4e, uri: at://did:plc:64kdoplv62s6veonqincpgod/app.bsky.feed.post/3jxsdq3tgma2h&lt;span class="o"&gt;}}}&lt;/span&gt;, createdAt: 2023-06-10T08:53:45.372Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:xopjsprtk24yvyfyfzfifxki/app.bsky.graph.follow/3jxsejt2nz72r
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.graph.follow, subject: did:plc:cpogq3zcrybwsibq4hzjnbxa, createdAt: 2023-06-10T08:53:45.495Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:hgb7kmelvhfdhlc777diyokk/app.bsky.feed.like/3jxsejunxmh2r
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.feed.like, subject: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreiayanec5xmjfs3a2ey5bu3onrwbuz53i6w5sd3k55bmnh4444iuiq, uri: at://did:plc:5fwxaoha4lvtoseohazxr5uh/app.bsky.feed.post/3jxs7uqur2n2u&lt;span class="o"&gt;}&lt;/span&gt;, createdAt: 2023-06-10T08:53:47.609Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:djarlkihrgk7uvwcf4umikno/app.bsky.graph.follow/3jxsejuudpi2h
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.graph.follow, subject: did:plc:dqvv2jev7pm4a66iozhzqehq, createdAt: 2023-06-10T08:53:48.522Z&lt;span class="o"&gt;}&lt;/span&gt;
at://did:plc:oqbijttmayqui2xv3e2xwcdz/app.bsky.feed.post/3jxsejvcwj32l
&lt;span class="o"&gt;{&lt;/span&gt;text: I’m just warming them up &lt;span class="k"&gt;for &lt;/span&gt;you fam, &lt;span class="nv"&gt;$type&lt;/span&gt;: app.bsky.feed.post, reply: &lt;span class="o"&gt;{&lt;/span&gt;root: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreibhc74rccmajeddna5xkps4iqwamwngf5ihlzeimaxbw7mzoj45ya, uri: at://did:plc:rlfsrnc4kvcgatjaykqvxfql/app.bsky.feed.post/3jxs3ehmevb2n&lt;span class="o"&gt;}&lt;/span&gt;, parent: &lt;span class="o"&gt;{&lt;/span&gt;cid: bafyreibhc74rccmajeddna5xkps4iqwamwngf5ihlzeimaxbw7mzoj45ya, uri: at://did:plc:rlfsrnc4kvcgatjaykqvxfql/app.bsky.feed.post/3jxs3ehmevb2n&lt;span class="o"&gt;}}&lt;/span&gt;, createdAt: 2023-06-10T08:53:48.176Z&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;However, for those who are not familiar with Bluesky's API or Dart, this code may seem complicated, so I will explain the main points.&lt;/p&gt;

&lt;p&gt;First, to access Bluesky Social's API using the &lt;code&gt;bluesky&lt;/code&gt; package, import &lt;code&gt;package:bluesky/bluesky.dart&lt;/code&gt; and instantiate the &lt;code&gt;Bluesky&lt;/code&gt; object as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:bluesky/bluesky.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;anonymous&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since the Firehose API used this time does not require user authentication to access it, now we created an instance of the &lt;code&gt;Bluesky&lt;/code&gt; object using the &lt;code&gt;.anonymous()&lt;/code&gt; constructor, which does not require authentication. The &lt;code&gt;.fromSession()&lt;/code&gt; constructor must always be used when using endpoints that require user authentication, but is not used in this article.&lt;/p&gt;

&lt;p&gt;The next thing we have to do is to get the Firehose API Stream from an instance of the &lt;code&gt;Bluesky&lt;/code&gt; object as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With just this one simple line you can get a Stream of Bluesky Social's Firehose API. This Stream is a long-lived connection and is communicated via WebSocket. But you need not be aware of these difficult communications at all, just write one line above and you will be fine.&lt;/p&gt;

&lt;p&gt;Returned from &lt;code&gt;subscribeRepoUpdates()&lt;/code&gt; is a subscription data representing the connection to the Firehose API. You can retrieve the data flowing from stream in the following way.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Like above, you can get events that occur in &lt;code&gt;bsky.social&lt;/code&gt; from stream. But, the structure of &lt;code&gt;event&lt;/code&gt; that can be obtained from this stream is not simple. This &lt;code&gt;event&lt;/code&gt; object is of type Union, which simply means that there are multiple structures of objects flowing from the stream.&lt;/p&gt;

&lt;p&gt;Do you have to handle those complex structures yourself? No, that is not necessary. The &lt;code&gt;bluesky&lt;/code&gt; package provides easy handling of objects of type Union.&lt;/p&gt;

&lt;p&gt;Not only in this example, but any object of type Union in the &lt;code&gt;bluesky&lt;/code&gt; package can easily handle any structure that may flow as a Union using &lt;code&gt;.when()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;commit:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;handle:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;migrate:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;tombstone:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;info:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;unknown:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For example, using &lt;code&gt;event.when()&lt;/code&gt; in the above example, you can safely handle objects with the different structures &lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;handle&lt;/code&gt;, &lt;code&gt;migrate&lt;/code&gt;, &lt;code&gt;tombstone&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt; and &lt;code&gt;unknown&lt;/code&gt;. The &lt;code&gt;unknown&lt;/code&gt; is called when there is a Union structure not supported by the &lt;code&gt;bluesky&lt;/code&gt; package, and is passed JSON (Map) that is not parsed to a specific object.&lt;/p&gt;

&lt;p&gt;But, only the &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;handle&lt;/code&gt; patterns are mainly used at this time, and the other structures are not implemented or used in the official Bluesky API. So, let's focus on &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;handle&lt;/code&gt; now.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;commit&lt;/code&gt; event is fired when a post is posted on Bluesky, or when a specific post is liked and etc. A &lt;code&gt;commit&lt;/code&gt; event consists of one or more &lt;code&gt;ops&lt;/code&gt;, each &lt;code&gt;op&lt;/code&gt; having an &lt;code&gt;action&lt;/code&gt; that triggered the event to occur as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;create&lt;/strong&gt;: When a specific &lt;strong&gt;record is created&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;update&lt;/strong&gt;: When a specific &lt;strong&gt;record is updated&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;delete&lt;/strong&gt;: When a specific &lt;strong&gt;record is deleted&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Dart program allows you to do the following.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;commit:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;RepoAction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;RepoAction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;RepoAction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nl"&gt;handle:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;migrate:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;tombstone:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;info:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;unknown:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For example, in the above case, from &lt;code&gt;op.uri&lt;/code&gt; you can get the AT URI of a specific record, and from &lt;code&gt;op.record&lt;/code&gt; you can get a specific record according to the AT URI and &lt;code&gt;action&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, the &lt;code&gt;handle&lt;/code&gt; event is fired when a particular user changes the handle on an account. The &lt;code&gt;handle&lt;/code&gt; event is not as difficult as the &lt;code&gt;commit&lt;/code&gt; event introduced earlier, you just can get the modified contents of the handle as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;commit:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;handle:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;did&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nl"&gt;migrate:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;tombstone:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;info:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;unknown:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's Handle Commit More Easily
&lt;/h2&gt;

&lt;p&gt;I have shown you how to use Bluesky Social's Firehose API using the &lt;code&gt;bluesky&lt;/code&gt; package, but there is actually an easier way to handle the &lt;code&gt;commit&lt;/code&gt; event. It is to use &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; for the &lt;code&gt;commit&lt;/code&gt; event as follows.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bluesky&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribeRepoUpdates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Add this&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;repoCommit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RepoCommitAdaptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;onCreatePost:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nl"&gt;onUpdateProfile:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nl"&gt;onDeleteFollow:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;commit:&lt;/span&gt; &lt;span class="n"&gt;repoCommit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// And execute like this&lt;/span&gt;
    &lt;span class="nl"&gt;handle:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;migrate:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;tombstone:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;info:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;unknown:&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can see at a glance that the &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; can be used to process each event in a very concise manner compared to handling each event individually using &lt;code&gt;ops&lt;/code&gt; to &lt;code&gt;action&lt;/code&gt;, etc., as in the previous example.&lt;/p&gt;

&lt;p&gt;The above example specifies &lt;code&gt;onCreatePost&lt;/code&gt;, &lt;code&gt;onUpdateProfile&lt;/code&gt;, and &lt;code&gt;onDeleteFollow&lt;/code&gt; when creating an instance of &lt;code&gt;RepoCommitAdaptor&lt;/code&gt;, which means that only the following events can be filtered and retrieved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;onCreatePost&lt;/strong&gt;: When the &lt;strong&gt;Post is created&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;onUpdateProfile&lt;/strong&gt;: When the &lt;strong&gt;Profile is updated&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;onDeleteFollow&lt;/strong&gt;: When the &lt;strong&gt;Follow is deleted&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, the above examples are only some of the events supported by &lt;code&gt;RepoCommitAdaptor&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;RepoCommitAdaptor&lt;/code&gt; provides very powerful and secure handling when using Bluesky Social's Firehose API with the &lt;code&gt;bluesky&lt;/code&gt; package. When using &lt;code&gt;subscribeRepoUpdates()&lt;/code&gt; to handle &lt;code&gt;commit&lt;/code&gt; events, it would be best to use the &lt;code&gt;RepoCommitAdaptor&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is how to easily use Bluesky Social's Firehose API with Dart and Flutter using the &lt;code&gt;bluesky&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;This article is basically an example with a Dart program, but the &lt;code&gt;bluesky&lt;/code&gt; package also works with Flutter, so similar code can be used to make the Firehose API work in a Flutter app. You can use the &lt;code&gt;StreamBuilder&lt;/code&gt; widget when working with Firehose API Streams in Flutter.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, the &lt;code&gt;bluesky&lt;/code&gt; package also supports many endpoints other than the Firehose API presented here. This is a very powerful package that will surely be useful in the Dart/Flutter apps you develop!&lt;/p&gt;

&lt;p&gt;In addition to the &lt;code&gt;bluesky&lt;/code&gt; package I have presented here, I have also developed many AT Protocol related packages for Dart/Flutter in the following monorepo. If you are interested in AT Protocol related packages for Dart/Flutter, please check it out!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;
        myConsciousness
      &lt;/a&gt; / &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
        atproto.dart
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦋 AT Protocol and Bluesky things for Dart and Flutter.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;
    &lt;img alt="bluesky" width="600px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FmyConsciousness%2Fatproto.dart%2Fmain%2Fresources%2Fbrands%2Fatproto.001.png"&gt;
  &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;b&gt;AT Protocol and Bluesky Social Things for Dart/Flutter 🦋&lt;/b&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sponsors/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bce35a573e0dc8c4a75c3017272a722a11a2e4a45dcaa08510a42f47bbfb1d07/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d53706f6e736f72266d6573736167653d254532253944254134266c6f676f3d47697448756226636f6c6f723d666636396234" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6cfcc79877d089f7090ceb757c4c555c7a697305845838e51d586a125cecd777/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f6c6162656c3d4d61696e7461696e6572266d6573736167653d6d79436f6e7363696f75736e657373266c6f676f3d47697448756226636f6c6f723d303061636565" alt="GitHub Sponsor"&gt;&lt;/a&gt;
&lt;a href="https://github.com/invertase/melos" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f96d3c87e74f1adfb32fe6e99e1fb5c216beeee6b0d4aaa276bec8957f963ca9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61696e7461696e6564253230776974682d6d656c6f732d6637303066662e7376673f7374796c653d666c61742d737175617265" alt="melos"&gt;&lt;/a&gt;
&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22f10dfacac74f0e62e783455b9004afc99f9278860d5283ffb4d7096b40a37f/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f66303838623033332d363637302d343535652d626161322d3163626239353737656261612f6465706c6f792d737461747573" alt="Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/myConsciousness/atproto.dart/actions/workflows/cicd.yml/badge.svg" alt="Test/Analyzer"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/myConsciousness/atproto.dart" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/624116e859211622e8c3863e57ade69a125d6f139c0cd7fdfbe94d601f131648/68747470733a2f2f636f6465636f762e696f2f67682f6d79436f6e7363696f75736e6573732f617470726f746f2e646172742f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4a354754315046395933" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/issues" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/76a19c89b1524ec951bd572a2d30e3c51ca2475c29d168ed67782f619a8007e5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Issues"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/pulls" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5775b1161428f82bf47f894d7bec594abf8e5725973fc0ba11fb65bd9f284d04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Pull Requests"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0dbd61a0688aa90676d527219e3deb5d0f0cbb4645a0f99f5640c77e4788f97b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Stars"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8164e211ac136494b06e8f20ebad611574b7e4800379c914f22341324d20d3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6d79436f6e7363696f75736e6573732f617470726f746f2e64617274" alt="Contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d298808764b1d270e7e2df59fb15d39deb1d2723ac0f23a606c0de61cd471df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c616e6775616765732f636f64652d73697a652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="Code size"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/commits/main" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f6917dcd9dc6d4ff8c3e85581d53cb27f90ae9c0a5db269668ebc0e05823be83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d676974266c6f676f436f6c6f723d7768697465" alt="Last Commits"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b5e2f4af5488128fb6ef4d8c21e83b88c052747aae7ebf472d5ef10133bfcab/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d79436f6e7363696f75736e6573732f617470726f746f2e646172743f6c6f676f3d6f70656e2d736f757263652d696e6974696174697665266c6f676f436f6c6f723d677265656e" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71217453f48cd1f12ba5a720412bb92743010653a5cc69654e627fd99e2e9104/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d322e312d3462616161612e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#1-motivation-" rel="noopener noreferrer"&gt;1. Motivation 💪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#2-packages--tools-%EF%B8%8F" rel="noopener noreferrer"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#21-dart-packages" rel="noopener noreferrer"&gt;2.1. Dart Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#22-cli-tool" rel="noopener noreferrer"&gt;2.2. CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#23-github-actions-workflow" rel="noopener noreferrer"&gt;2.3. GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/myConsciousness/atproto.dart#3-developer-quickstart-%EF%B8%8F" rel="noopener noreferrer"&gt;3. Developer Quickstart 🏎️&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#31-clone-project" rel="noopener noreferrer"&gt;3.1. Clone Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#32-install-melos" rel="noopener noreferrer"&gt;3.2. Install Melos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#33-setup-project" rel="noopener noreferrer"&gt;3.3. Setup Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#34-useful-commands" rel="noopener noreferrer"&gt;3.4. Useful Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#4-who-is-using-atprotodart-" rel="noopener noreferrer"&gt;4. Who is using atproto.dart? 👀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#5-contribution-" rel="noopener noreferrer"&gt;5. Contribution 🏆&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#6-contributors-" rel="noopener noreferrer"&gt;6. Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#7-support-%EF%B8%8F" rel="noopener noreferrer"&gt;7. Support ❤️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#8-license-" rel="noopener noreferrer"&gt;8. License 🔑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart#9-more-information-" rel="noopener noreferrer"&gt;9. More Information 🧐&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Welcome to &lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; 🦋&lt;/p&gt;
&lt;p&gt;This project will &lt;strong&gt;&lt;em&gt;maximize your development productivity&lt;/em&gt;&lt;/strong&gt; about &lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Give a ⭐ on &lt;a href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and follow &lt;a href="https://bsky.app/profile/shinyakato.dev" rel="nofollow noopener noreferrer"&gt;shinyakato.dev&lt;/a&gt; on Bluesky!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Motivation 💪&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://atproto.com" rel="nofollow noopener noreferrer"&gt;AT Protocol&lt;/a&gt; and &lt;a href="https://blueskyweb.xyz" rel="nofollow noopener noreferrer"&gt;Bluesky&lt;/a&gt; are awesome.&lt;/p&gt;

&lt;p&gt;This wonderful platform needs a standard and highly integrated SDK
&lt;strong&gt;&lt;a href="https://atprotodart.com" rel="nofollow noopener noreferrer"&gt;atproto.dart&lt;/a&gt;&lt;/strong&gt; provides the best development experience in such matters for Dart/Flutter devs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;2. Packages &amp;amp; Tools ⚒️&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2.1. Dart Packages&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;pub.dev&lt;/th&gt;
&lt;th&gt;Docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier" rel="noopener noreferrer"&gt;at_identifier&lt;/a&gt;&lt;/strong&gt;: core library for the syntax in the AT Protocol standard&lt;/td&gt;
&lt;td&gt;&lt;a href="https://pub.dartlang.org/packages/at_identifier" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4bc958983f547dd43496745fde8164b9ec6ab1fce0167ead4a1c6336847c3be6/68747470733a2f2f696d672e736869656c64732e696f2f7075622f762f61745f6964656e7469666965722e7376673f6c6f676f3d64617274266c6f676f436f6c6f723d303062396663" alt="pub package"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/at_identifier/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;&lt;a href="https://github.com/myConsciousness/atproto.dart/tree/main/packages/nsid" rel="noopener noreferrer"&gt;nsid&lt;/a&gt;&lt;/strong&gt;:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/myConsciousness/atproto.dart" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Suggestions for improvements and pull requests are also very welcome. Or you can contact me on Bluesky :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bsky.app/profile/shinyakato.dev" rel="noopener noreferrer"&gt;https://bsky.app/profile/shinyakato.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>bluesky</category>
      <category>api</category>
    </item>
  </channel>
</rss>
