|
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