Skip to content
This repository was archived by the owner on Nov 5, 2022. It is now read-only.

Commit 924bfc8

Browse files
authored
0.3.0 (#12)
* 0.3.0
2 parents f48db2b + b761de6 commit 924bfc8

File tree

13 files changed

+380
-172
lines changed

13 files changed

+380
-172
lines changed

README.md

Lines changed: 75 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -5,177 +5,145 @@
55
[![Go Report Card](https://goreportcard.com/badge/github.com/fallenstedt/twitter-stream)](https://goreportcard.com/report/github.com/fallenstedt/twitter-stream)
66
[![Go Reference](https://pkg.go.dev/badge/github.com/fallenstedt/twitter-stream.svg)](https://pkg.go.dev/github.com/fallenstedt/twitter-stream)
77

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.
910

10-
![example of twit stream](./example.gif)
1111

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+
![example of twit stream](./example.gif)
1413

1514

1615
## Installation
1716

1817
`go get github.com/fallenstedt/twitter-stream`
1918

2019

20+
21+
2122
## Examples
2223

2324
#### Starting a stream
2425

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()
3030

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+
```
3435

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.
3638

3739
```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+
```
4842

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("")
5250

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()
5651
if err != nil {
5752
panic(err)
5853
}
54+
```
5955

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
6159
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))
6567
}
6668
}()
6769

68-
// After 30 seconds, stop the stream
6970
time.Sleep(time.Second * 30)
70-
api.Stream.StopStream()
71-
}
7271
```
7372

7473
#### Creating, Deleting, and Getting Rules
7574

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.
7677
```go
78+
tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret("key", "secret").RequestBearerToken()
79+
80+
if err != nil {
81+
panic(err)
82+
}
83+
```
7784

85+
##### Create a streaming api
86+
Create a twitterstream instance with your access token from above.
7887

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()
8796

8897
if err != nil {
89-
panic("No token found!")
98+
panic(err)
9099
}
91100

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+
}
94105

106+
fmt.Println(res.Data)
107+
```
95108

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
101111
res, err := api.Rules.AddRules(`{
102112
"add": [
103113
{"value": "cat has:images", "tag": "cat tweets with images"}
104114
]
105-
}`, false)
115+
}`, true) // dryRun is set to true
106116

107117
if err != nil {
108118
panic(err)
109119
}
110120

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))
125124
}
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
135129
res, err := api.Rules.AddRules(`{
136130
"delete": {
137-
"ids": ["1340894899986579457"]
131+
"ids": ["1234567890"]
138132
}
139-
}`, false)
133+
}`, true)
140134

141135
if err != nil {
142136
panic(err)
143137
}
144138

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))
170142
}
171143

172-
fmt.Println(res.Data, res.Meta)
173-
}
174-
175144
```
176145

177146

178-
179147
## Contributing
180148

181149
Pull requests are always welcome. Please accompany a pull request with tests.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.1
1+
0.3.0

example/go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module github.com/fallenstedt/twitter-stream/example
2+
3+
replace github.com/fallenstedt/twitter-stream => /Users/alex/Projects/twitter-stream/
4+
5+
go 1.15
6+
7+
require github.com/fallenstedt/twitter-stream v0.2.1

example/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/fallenstedt/twitter-stream v0.2.1 h1:lhnQDj1R9od8ZpiHya5tgbBon1eQH4Iqwlj0hqqLnK8=
2+
github.com/fallenstedt/twitter-stream v0.2.1/go.mod h1:e3GVow5/CaCeacD7kMH7ubyKHUNVSNntzFddzmzwP/8=

example/main.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
twitterstream "github.com/fallenstedt/twitter-stream"
6+
"time"
7+
)
8+
9+
const key = "YOUR_KEY"
10+
const secret = "YOUR_SECRET"
11+
12+
13+
func main() {
14+
// Use your favorite function from below here
15+
startStream()
16+
//addRules()
17+
//getRules()
18+
//deleteRules()
19+
}
20+
21+
22+
func startStream() {
23+
tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret(key, secret).RequestBearerToken()
24+
25+
if err != nil {
26+
panic(err)
27+
}
28+
29+
api := twitterstream.NewTwitterStream(tok.AccessToken)
30+
31+
err = api.Stream.StartStream("")
32+
33+
if err != nil {
34+
panic(err)
35+
}
36+
37+
go func() {
38+
for message := range api.Stream.GetMessages() {
39+
if message.Err != nil {
40+
panic(message.Err)
41+
}
42+
fmt.Println(string(message.Data))
43+
}
44+
}()
45+
46+
time.Sleep(time.Second * 30)
47+
}
48+
49+
func addRules() {
50+
tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret(key, secret).RequestBearerToken()
51+
if err != nil {
52+
panic(err)
53+
}
54+
api := twitterstream.NewTwitterStream(tok.AccessToken)
55+
res, err := api.Rules.AddRules(`{
56+
"add": [
57+
{"value": "cat has:images", "tag": "cat tweets with images"}
58+
]
59+
}`, true) // dryRun is set to true
60+
61+
if err != nil {
62+
panic(err)
63+
}
64+
65+
if res.Errors != nil && len(res.Errors) > 0 {
66+
//https://developer.twitter.com/en/support/twitter-api/error-troubleshooting
67+
panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors))
68+
}
69+
70+
fmt.Println("I have created this many rules: ")
71+
fmt.Println(res.Meta.Summary.Created)
72+
}
73+
74+
func getRules() {
75+
tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret(key, secret).RequestBearerToken()
76+
if err != nil {
77+
panic(err)
78+
}
79+
api := twitterstream.NewTwitterStream(tok.AccessToken)
80+
res, err := api.Rules.GetRules()
81+
82+
if err != nil {
83+
panic(err)
84+
}
85+
86+
if res.Errors != nil && len(res.Errors) > 0 {
87+
//https://developer.twitter.com/en/support/twitter-api/error-troubleshooting
88+
panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors))
89+
}
90+
91+
fmt.Println(res.Data)
92+
}
93+
94+
95+
func deleteRules() {
96+
tok, err := twitterstream.NewTokenGenerator().SetApiKeyAndSecret(key, secret).RequestBearerToken()
97+
if err != nil {
98+
panic(err)
99+
}
100+
api := twitterstream.NewTwitterStream(tok.AccessToken)
101+
102+
// use api.Rules.GetRules to find the ID number for an existing rule
103+
res, err := api.Rules.AddRules(`{
104+
"delete": {
105+
"ids": ["1234567890"]
106+
}
107+
}`, true)
108+
109+
if err != nil {
110+
panic(err)
111+
}
112+
113+
if res.Errors != nil && len(res.Errors) > 0 {
114+
//https://developer.twitter.com/en/support/twitter-api/error-troubleshooting
115+
panic(fmt.Sprintf("Received an error from twiiter: %v", res.Errors))
116+
}
117+
118+
fmt.Println(res)
119+
}

0 commit comments

Comments
 (0)