|
5 | 5 | [](https://goreportcard.com/report/github.com/fallenstedt/twitter-stream)
|
6 | 6 | [](https://pkg.go.dev/github.com/fallenstedt/twitter-stream)
|
7 | 7 |
|
8 |
| -TwitStream is a Go library for streaming tweets with [Twitter's v2 Filtered Streaming API](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/introduction). |
| 8 | +TwitStream is a Go library for creating streaming rules and streaming tweets with [Twitter's v2 Filtered Streaming API](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/introduction). |
| 9 | +See [examples](https://github.com/fallenstedt/twitter-stream/tree/master/example) to start adding your own rules and start streaming. |
9 | 10 |
|
10 |
| - |
11 | 11 |
|
12 |
| -This project is not production ready. There are several things I need to do: |
13 |
| -- [ ] This package streams strings. I need to convert json into go structs with [these possible response fields](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream) |
| 12 | + |
14 | 13 |
|
15 | 14 |
|
16 | 15 | ## Installation
|
17 | 16 |
|
18 | 17 | `go get github.com/fallenstedt/twitter-stream`
|
19 | 18 |
|
20 | 19 |
|
| 20 | + |
| 21 | + |
21 | 22 | ## Examples
|
22 | 23 |
|
23 | 24 | #### Starting a stream
|
24 | 25 |
|
25 |
| -Once you obtain an Access Token, you can create a TwitterStream instance with `NewTwitterStream(accesToken)` |
26 |
| -Then, you can invoke `StartStream` to begin the streaming process. |
27 |
| - |
28 |
| -To read messages from your stream, start a loop with `GetMessages`. The messages that is returned could be |
29 |
| -a tweet, or an error. |
| 26 | +##### Obtain an Access Token using your Twitter Access Key and Secret. |
| 27 | +You need an access token to do any streaming. `twitterstream` provides an easy way to fetch an access token. |
| 28 | +```go |
| 29 | + tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret("key", "secret").RequestBearerToken() |
30 | 30 |
|
31 |
| -The possible errors that can be returned are |
32 |
| -* `io.EOF`: An error that you have reached the end of the stream. |
33 |
| -* `non io.EOF errors`: This could be errors that are returned from Twitter during your stream |
| 31 | + if err != nil { |
| 32 | + panic(err) |
| 33 | + } |
| 34 | +``` |
34 | 35 |
|
35 |
| -[You can learn more about processing data by reading Twitter's documentation here](https://dev.twitter.com/streaming/overview/processing) |
| 36 | +##### Create a streaming api |
| 37 | +Create a twitterstream instance with your access token from above. |
36 | 38 |
|
37 | 39 | ```go
|
38 |
| -// Starting a stream assuming you already have |
39 |
| -// stream rules set in place |
40 |
| -func startStreaming() { |
41 |
| - // Obtain an AccessToken |
42 |
| - // You can use the token generator and provide your api key and secret |
43 |
| - // or provide an access token you already have |
44 |
| - token, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret( |
45 |
| - "your_twitter_api_key", |
46 |
| - "your_twitter_api_secret", |
47 |
| - ).RequestBearerToken() |
| 40 | + api := twitterstream.NewTwitterStream(tok.AccessToken) |
| 41 | +``` |
48 | 42 |
|
49 |
| - if err != nil { |
50 |
| - panic("No token found!") |
51 |
| - } |
| 43 | +##### Start Stream |
| 44 | +Start your stream. This is a long-running HTTP GET request. |
| 45 | +You can get specific data you want by adding [query params](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream). |
| 46 | +Additionally, [view an example of query params here](https://developer.twitter.com/en/docs/twitter-api/expansions). |
| 47 | + |
| 48 | +```go |
| 49 | + err := api.Stream.StartStream("") |
52 | 50 |
|
53 |
| - // With an access token, you can create a new twitterstream and start streaming |
54 |
| - api := twitterstream.NewTwitterStream(token.AccessToken) |
55 |
| - err := api.Stream.StartStream() |
56 | 51 | if err != nil {
|
57 | 52 | panic(err)
|
58 | 53 | }
|
| 54 | +``` |
59 | 55 |
|
60 |
| - // If you do not put this in a go routine, you will stream forever |
| 56 | +4. Consume Messages from the Stream |
| 57 | +Handle any `io.EOF` and other errors that arise first, then unmarshal your bytes into your favorite struct. Below is an example with strings |
| 58 | +```go |
61 | 59 | go func() {
|
62 |
| - // Range over the messages channel to get a message, or an error. |
63 |
| - for message := range *api.Stream.GetMessages() { |
64 |
| - fmt.Println(message) |
| 60 | + for message := range api.Stream.GetMessages() { |
| 61 | + if message.Err != nil { |
| 62 | + panic(message.Err) |
| 63 | + } |
| 64 | + // Will print something like: |
| 65 | + //{"data":{"id":"1356479201000","text":"Look at this cat picture"},"matching_rules":[{"id":12345,"tag":"cat tweets with images"}]} |
| 66 | + fmt.Println(string(message.Data)) |
65 | 67 | }
|
66 | 68 | }()
|
67 | 69 |
|
68 |
| - // After 30 seconds, stop the stream |
69 | 70 | time.Sleep(time.Second * 30)
|
70 |
| - api.Stream.StopStream() |
71 |
| -} |
72 | 71 | ```
|
73 | 72 |
|
74 | 73 | #### Creating, Deleting, and Getting Rules
|
75 | 74 |
|
| 75 | +##### Obtain an Access Token using your Twitter Access Key and Secret. |
| 76 | +You need an access token to do anything. `twitterstream` provides an easy way to fetch an access token. |
76 | 77 | ```go
|
| 78 | + tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret("key", "secret").RequestBearerToken() |
| 79 | + |
| 80 | + if err != nil { |
| 81 | + panic(err) |
| 82 | + } |
| 83 | +``` |
77 | 84 |
|
| 85 | +##### Create a streaming api |
| 86 | +Create a twitterstream instance with your access token from above. |
78 | 87 |
|
79 |
| -func addRules() { |
80 |
| - // Obtain an AccessToken |
81 |
| - // You can use the token generator and provide your api key and secret |
82 |
| - // or provide an access token you already have |
83 |
| - token, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret( |
84 |
| - "your_twitter_api_key", |
85 |
| - "your_twitter_api_secret", |
86 |
| - ).RequestBearerToken() |
| 88 | +```go |
| 89 | + api := twitterstream.NewTwitterStream(tok.AccessToken) |
| 90 | +``` |
| 91 | + |
| 92 | +##### Get Rules |
| 93 | +Use the `Rules` struct to access different Rules endpoints as defined in [Twitter's API Reference](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference) |
| 94 | +```go |
| 95 | + res, err := api.Rules.GetRules() |
87 | 96 |
|
88 | 97 | if err != nil {
|
89 |
| - panic("No token found!") |
| 98 | + panic(err) |
90 | 99 | }
|
91 | 100 |
|
92 |
| - // With an access token, you can create a new twitterstream and start adding rules |
93 |
| - api := twitterstream.NewTwitterStream(token.AccessToken) |
| 101 | + if res.Errors != nil && len(res.Errors) > 0 { |
| 102 | + //https://developer.twitter.com/en/support/twitter-api/error-troubleshooting |
| 103 | + panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors)) |
| 104 | + } |
94 | 105 |
|
| 106 | + fmt.Println(res.Data) |
| 107 | +``` |
95 | 108 |
|
96 |
| - // You can add rules by passing in stringified JSON with the rules you want to add |
97 |
| - // You can learn more about building rules here: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/integrate/build-a-rule |
98 |
| - // Or here: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules |
99 |
| - // The response are the rules you created |
100 |
| - // The 2nd argument will perform a dry run if set to true. |
| 109 | +##### Add Rules |
| 110 | +```go |
101 | 111 | res, err := api.Rules.AddRules(`{
|
102 | 112 | "add": [
|
103 | 113 | {"value": "cat has:images", "tag": "cat tweets with images"}
|
104 | 114 | ]
|
105 |
| - }`, false) |
| 115 | + }`, true) // dryRun is set to true |
106 | 116 |
|
107 | 117 | if err != nil {
|
108 | 118 | panic(err)
|
109 | 119 | }
|
110 | 120 |
|
111 |
| - fmt.Println(res.Data, res.Meta) |
112 |
| -} |
113 |
| - |
114 |
| -func deleteRules() { |
115 |
| - // Obtain an AccessToken |
116 |
| - // You can use the token generator and provide your api key and secret |
117 |
| - // or provide an access token you already have |
118 |
| - token, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret( |
119 |
| - "your_twitter_api_key", |
120 |
| - "your_twitter_api_secret", |
121 |
| - ).RequestBearerToken() |
122 |
| - |
123 |
| - if err != nil { |
124 |
| - panic("No token found!") |
| 121 | + if res.Errors != nil && len(res.Errors) > 0 { |
| 122 | + //https://developer.twitter.com/en/support/twitter-api/error-troubleshooting |
| 123 | + panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors)) |
125 | 124 | }
|
126 |
| - |
127 |
| - // With an access token, you can create a new twitterstream and start deleting rules |
128 |
| - api := twitterstream.NewTwitterStream(token.AccessToken) |
129 |
| - |
130 |
| - // You can delete rules by passing in stringified JSON with the rules you want to delete |
131 |
| - // Learn more about deleting rules here: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/post-tweets-search-stream-rules |
132 |
| - // The ids are the rule's ids you want to delete. You can find out how to get your ids in the below example |
133 |
| - // The response are the rules you have. |
134 |
| - // The 2nd argument will perform a dry run if set to true. |
| 125 | +``` |
| 126 | +##### Delete Rules |
| 127 | +```go |
| 128 | +// use api.Rules.GetRules to find the ID number for an existing rule |
135 | 129 | res, err := api.Rules.AddRules(`{
|
136 | 130 | "delete": {
|
137 |
| - "ids": ["1340894899986579457"] |
| 131 | + "ids": ["1234567890"] |
138 | 132 | }
|
139 |
| - }`, false) |
| 133 | + }`, true) |
140 | 134 |
|
141 | 135 | if err != nil {
|
142 | 136 | panic(err)
|
143 | 137 | }
|
144 | 138 |
|
145 |
| - fmt.Println(res.Data, res.Meta) |
146 |
| -} |
147 |
| - |
148 |
| -func getRules() { |
149 |
| - // Obtain an AccessToken |
150 |
| - // You can use the token generator and provide your api key and secret |
151 |
| - // or provide an access token you already have |
152 |
| - token, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret( |
153 |
| - "your_twitter_api_key", |
154 |
| - "your_twitter_api_secret", |
155 |
| - ).RequestBearerToken() |
156 |
| - |
157 |
| - if err != nil { |
158 |
| - panic("No token found!") |
159 |
| - } |
160 |
| - |
161 |
| - // With an access token, you can create a new twitterstream and start getting your rules |
162 |
| - api := twitterstream.NewTwitterStream(token.AccessToken) |
163 |
| - |
164 |
| - // You can get your rules by invoking GetRules |
165 |
| - // Learn more about getting rules here: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream-rules |
166 |
| - res, err := api.Rules.GetRules() |
167 |
| - |
168 |
| - if err != nil { |
169 |
| - panic(err) |
| 139 | + if res.Errors != nil && len(res.Errors) > 0 { |
| 140 | + //https://developer.twitter.com/en/support/twitter-api/error-troubleshooting |
| 141 | + panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors)) |
170 | 142 | }
|
171 | 143 |
|
172 |
| - fmt.Println(res.Data, res.Meta) |
173 |
| -} |
174 |
| - |
175 | 144 | ```
|
176 | 145 |
|
177 | 146 |
|
178 |
| - |
179 | 147 | ## Contributing
|
180 | 148 |
|
181 | 149 | Pull requests are always welcome. Please accompany a pull request with tests.
|
|
0 commit comments