// summary : X API tweets list // keywords : scala, zio, sttp, x-api // publish : gist // authors : David Crosson // license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) // id : 47b77580-a424-456d-a453-c57caf17ecd1 // created-on : 2025-04-07T23:28:49+02:00 // managed-by : https://github.com/dacr/code-examples-manager // run-with : scala-cli $file //> using scala 3.6.4 //> using dep dev.zio::zio:2.1.17 //> using dep com.softwaremill.sttp.client4::zio:4.0.0 //> using dep com.softwaremill.sttp.client4::zio-json:4.0.0 ////> using objectWrapper // https://developer.x.com/en // TOK="Authorization: Bearer $SOCIAL_API_X_TOKEN" // ID=$(curl -s -H $TOK "https://api.x.com/2/users/by/username/$SOCIAL_API_X_USERNAME" | jq -r .data.id) // curl -s -H $TOK "https://api.x.com/2/users/$ID/tweets?max_results=10" import zio.* import sttp.client4.* import sttp.client4.httpclient.zio.HttpClientZioBackend import sttp.client4.ziojson.* import zio.json.JsonCodec case class Tweet(id: String, text: String) derives JsonCodec case class TweetsResponse(data: List[Tweet]) derives JsonCodec case class User(id: String, name: String, username: String) derives JsonCodec case class UserResponse(data: User) derives JsonCodec val app = for { token <- System.env("SOCIAL_API_X_TOKEN").someOrFail("NO CREDENTIAL TOKEN PROVIDED") username <- System.env("SOCIAL_API_X_USERNAME").someOrFail("NO CREDENTIAL USERNAME PROVIDED") _ <- Console.printLine(s"Querying X API for user $username") backend <- HttpClientZioBackend.apply() queryUser = basicRequest .get(uri"https://api.x.com/2/users/by/username/$username") .header("Authorization", s"Bearer $token") .response(asJson[UserResponse]) responseUser <- backend.send(queryUser).map(_.body) id <- ZIO.from(responseUser).map(_.data.id) _ <- Console.printLine(s"Got user id $id") queryTweets = basicRequest .get(uri"https://api.x.com/2/users/$id/tweets?max_results=10") .header("Authorization", s"Bearer $token") .response(asJson[TweetsResponse]) _ <- Console.printLine("Querying X API") responseTweets <- backend.send(queryTweets).map(_.body) posts <- ZIO.fromEither(responseTweets).map(_.data) _ <- Console.printLine(s"Got ${posts.size} posts") } yield () Unsafe.unsafe(implicit u => Runtime.default.unsafe.run(app))