Search code examples
twitterretrofit2okhttptwitter-streaming-api

Twitter API v2 Streaming with Retrofit or OkHttp


I am trying integrate the new Twitter API specifically the streaming tweets part in my android app, I am using Retrofit for my http calls.

When I try to make the call to get the streaming tweets it just hangs and does not return anything.

this is my retrofit call

@Streaming
@GET("tweets/search/stream")
suspend fun getFilteredStream(@Header("Authorization") token:String)

I then tried making a call with just OkHttp as shown in the documentation I get a successful response but I dont know how to stream the data.

I can make the call successfully via a curl call and see the data no problem.

How do I stream the data via retrofit or OkHttp

Update:

With OkHttp I was able to get data by doing this

val client: OkHttpClient = OkHttpClient().newBuilder()
            .build()
        val request: Request = Request.Builder()
            .url("https://api.twitter.com/2/tweets/search/stream")
            .method("GET", null)
            .build()
        val response: Response = client.newCall(request).execute()
        val source = response.body?.source()
        val buffer = Buffer()
        while(!source!!.exhausted()){
            response.body?.source()?.read(buffer, 8192)
            val data = buffer.readString(Charset.defaultCharset())
        }

data holds the string data representation of multiple tweet objects but how do I read one tweet at a time, or parse the response like this?


Solution

  • From the docs, I think you'll need to combine the two examples you have.

    https://github.com/square/retrofit/blob/108fe23964b986107aed352ba467cd2007d15208/retrofit/src/main/java/retrofit2/http/Streaming.java

    Treat the response body on methods returning {@link ResponseBody ResponseBody} as is, i.e. without converting the body to {@code byte[]}.

    And example calling code

    https://github.com/square/retrofit/blob/108fe23964b986107aed352ba467cd2007d15208/retrofit/src/test/java/retrofit2/CallTest.java#L599

    I suspect, dependending on the JSON API you use you may be able to use a Streaming API from the response body. But if not you could split on either just newline or newline followed by { on next line and parse individually. Sorry I can't help here.

    See https://en.wikipedia.org/wiki/JSON_streaming#Concatenated_JSON