Git Product home page Git Product logo

mira's Introduction

mira

Go Report Card GoDoc PRs Welcome

For full documentation, please see the Godoc page

mira is a Reddit Api Wrapper written in beautiful Go. Featured in issue 306 of Golang Weekly 🚀

It is super simple to use the bot as we also provide you with simple but fully extensive interfaces. Currently, mira is a project that is considered more or less complete. All main functionality, such as streaming, data manipulation, data request, submissions, links, etc. are fully implemented. mira can be extended to use any Reddit API endpoint. More details at the bottom of this page.

Demo

Demo

Two quick notes: all actions should be done via Reddit struct, I thought it would make it simpler to work with. Secondly, all actions require the objects full thing_id, so you have to use GetId() to get that id. Every struct has that method implemented and it will return a string in the form of t[1-6]_[a-z0-9]{5}. Refer to the following table for the classifications of the structs.

Type Prefixes

Prefix Type
t1 Comment
t2 Redditor
t3 Submission, PostListing contents
t4 Message (NOT IMPLEMENTED)
t5 Subreddit
t6 Award (NOT IMPLEMENTED)

Config file

The config file structure is very simple:

login.conf
----------
CLIENT_ID =
CLIENT_SECRET =
USERNAME =
PASSWORD =
USER_AGENT =
r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))

Environment setup

Mira also works with environmental variables, here is an example from docker-compose

    environment:
      - BOT_CLIENT_ID=hunteoahtnhnt432
      - BOT_CLIENT_SECRET=ehoantehont4ht34hnt332
      - BOT_USER_AGENT='u/mytestbot developed by thecsw'
      - BOT_USERNAME=mytestbot
      - BOT_PASSWORD=verygoodpassword

And the login will look like this:

r, err := mira.Init(mira.ReadCredsFromEnv())

Or you can always just fill in the values directly.

Examples

Note: Error checking is omitted for brevity.

Streaming

Streaming new submissions is very simple! mira supports streaming comment replies, mentions, new subreddit's/redditor's comments, and new subreddit's/redditor's submissions.

// r is an instance of *mira.Reddit
r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))

// Start streaming my comment replies
c, err := r.StreamCommentReplies()
for {
	msg := <-c
	r.Comment(msg.GetId()).Reply("I got your message!")
}

// Start streaming my mentions
// Start streaming my comment replies
c, err := r.StreamMentions()
for {
	msg := <-c
	r.Comment(msg.GetId()).Reply("I got your mention of me!")
}

// Start streaming subreddits' submissions
c, err := r.Subreddit("tifu", "wholesomememes").StreamSubmissions()
for {
	post := <-c
	r.Submission(post.GetId()).Save("hello there")
}

// NOTE: Second value is the stop channel. Send a true value
// to the stop channel and the goroutine will return. 
// Basically, `stop <- true`

// Start streaming subreddits' comments
c, err := r.Subreddit("all").StreamComments()
for {
	msg := <-c
	r.Comment(msg.GetId()).Reply("my reply!")
}

// Start streaming redditor's submissions
c, err := r.Redditor("thecsw").StreamSubmissions()
for {
	post := <-c
	r.Submission(post.GetId()).Save("hello there")
}
	
// Start streaming redditor' comments
c, err := r.Redditor("thecsw").StreamComments()
for {
	msg := <-c
	r.Comment(msg.GetId()).Reply("my reply!")
}

Submitting, Commenting, Replying, and Editing

It is very easy to post a submission, comment on it, reply to a message, or edit a comment.

package main

import (
	"fmt"

	"github.com/thecsw/mira"
)

// Error checking is omitted for brevity
func main() {
	r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))

	// Make a submission
	post, err := r.Subreddit("mysubreddit").Submit("mytitle", "mytext")

	// Comment on our new submission
	comment, err := r.Submission(post.GetId()).Save("mycomment")

	// Reply to our own comment
	reply, err := r.Comment(comment.GetId()).Reply("myreply")

	// Delete the reply
	r.Comment(reply.GetId()).Delete()

	// Edit the first comment
	newComment, err := r.Comment(comment.GetId()).Edit("myedit")

	// Show the comment's body
	fmt.Println(newComment.GetBody())
}

Composing a message

We can also send a message to another user!

package main

import (
	"github.com/thecsw/mira"
)

func main() {
	r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))

	r.Redditor("myuser").Compose("mytitle", "mytext")
}

Going through hot, new, top, rising, controversial, and random

You can also traverse through a number of submissions using one of our methods.

package main

import (
	"fmt"

	"github.com/thecsw/mira"
)

func main() {
	r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))
	sort := "top"
	var limit int = 25
	duration := "all"
	subs, err := r.Subreddit("all").Submissions(sort, duration, limit)
	for _, v := range subs {
		fmt.Println("Submission Title: ", v.GetTitle())
	}
}

Getting reddit info

You can extract info from any reddit ID using mira. The returned value is an instance of mira.MiraInterface.

package main

import (
	"fmt"

	"github.com/thecsw/mira"
)

func main() {
	r, err := mira.Init(mira.ReadCredsFromFile("login.conf"))
	me, err := r.Me().Info()
	comment, err := r.Comment("t1_...").Info()
	redditor, err := r.Redditor("t2_...").Info()
	submission, err := r.Submission("t3_...").Info()
	subreddit, err := r.Subreddit("t5_...").Info()
}

Here is the interface:

type MiraInterface interface {
	GetId() string
	GetParentId() string
	GetTitle() string
	GetBody() string
	GetAuthor() string
	GetName() string
	GetKarma() float64
	GetUps() float64
	GetDowns() float64
	GetSubreddit() string
	GetCreated() float64
	GetFlair() string
	GetUrl() string
	IsRoot() bool
}

Mira Caller

Surely, Reddit API is always developing and I can't implement all endpoints. It will be a bit of a bloat. Instead, you have accessto *Reddit.MiraRequest method that will let you to do any custom reddit api calls!

Here is the signature:

func (c *Reddit) MiraRequest(method string, target string, payload map[string]string) ([]byte, error) {...}

It is pretty straight-forward. The return is a slice of bytes. Parse it yourself.

Here is an example of how Reddit.Reply() uses MiraRequest:

NOTE: checkType(...) is a quick method to pop a value from the queue and make sure it's a valid value and type. For example,

r.Comment("COMM1").Submission("SUBM1").Redditor("USER1")

will add elements to its internal queue, so that the layout is:

Enqueue->
                  redditor  submission  comment               // type
        |BACK| -> |USER1| -> |SUBM1| -> |COMM1| -> |FRONT|    // value
                                                  Dequeue->

So that when you run r.checkType("comment"), it will dequeue COMM1 and return triplet "COMM1", "comment", nil.

If you run r.checkType("redditor") (will fail because subm is at the end), you will get "", "", "errors.New("the passed type...")

Here is an example of how you check that the last element to dequeue is a type that you're expecting:

func (c *Reddit) Reply(text string) (models.CommentWrap, error) {
	ret := &models.CommentWrap{}
	// Second return is type, which is "comment"
	name, _, err := c.checkType("comment")
	if err != nil {
		return *ret, err
	}
	target := RedditOauth + "/api/comment"
	ans, err := c.MiraRequest("POST", target, map[string]string{
		"text":     text,
		"thing_id": name,
		"api_type": ApiTypeJson,
	})
	json.Unmarshal(ans, ret)
	return *ret, err
}

mira's People

Contributors

anirbanmu avatar devmedoo avatar jpadley18 avatar thecsw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mira's Issues

Streaming comments stops working...

Hi there.

When using the library's streaming comments capability:

comments, err := r.Subreddit("aww").StreamComments()
if err != nil {
	log.Println(err)
}

It will work for awhile (usually 10-20 minutes), but then just stop streaming new comments, even on very active subreddits. There are no errors being returned as far as I can tell. Has anyone else experienced this issue?

Can you go to the next page?

Hi
I can't figure out how to go to the next page, it only prints the first one. I also tried without separating the id from the identifier (eg. d7gsv instead of t3_d7gsv). I would also like to know if there's a way to sort these by newest. I only saw Submissions() having a sort argument not SubmissionsAfter(). This is my code

var lastPostId string

// Initialize a new mira instance
r, err := mira.Init(creds)
if err != nil {
	log.Fatal(err)
}	

if rippingType == "r" {
	postCount := 1
	for {
		subsAfter, err := r.Subreddit(rippingIdentifier).SubmissionsAfter(lastPostId, 100)
		if err != nil {
			log.Printf("Failed to fetch /%s/%s: %v\n", rippingType, rippingIdentifier, err)
		}

		// Define an output folder and print out a message
		rippingIdentifier = subsAfter[0].GetSubreddit()
		if !isOutputUserDefined {
			outputFolder = "rips/reddit_sub_" + rippingIdentifier + "/"
		}
		colorstring.Printf("[green]Ripping /%s/%s // Output folder: %s\n", rippingType, rippingIdentifier, outputFolder)

		// Iterate over each page
		for _, v := range subsAfter {
			fmt.Printf("[%d] [/%s/%s] %s // Downloading: %s\n", postCount, rippingType, rippingIdentifier, v.GetId(), v.GetUrl())
			lastPostId = strings.Split(v.GetId(), "_")[1]
			postCount ++
		}
	}		
}

Streaming without login

Is there a possibility to stream submissions without login credentials? Since I dont want to post and only want to stream submissions of a subreddit, which should be doable via the public API this should be doable without login credentials

Can you use Mira to view a user profile?

For example, if I wanted to automatically stream new comments made by my account to a file on local disc, is there a way to "stream" those comments, similar to how the subreddit listener serves new posts?

Panic: runtime error: invalid memory address or nil pointer dereference

Hi!

I´m getting this error running this code example.

package main

import (
	"fmt"

	"github.com/thecsw/mira"
)

func main() {
	x := mira.Credentials{ClientId: "*", ClientSecret: "*", Username: "*", Password: "*", UserAgent: "*"}
	r, _ := mira.Init(x)
	sort := "top"
	var limit int = 25
	duration := "all"
	subs, _ := r.Subreddit("all").Submissions(sort, duration, limit)
	for _, v := range subs {
		fmt.Println("Submission Title: ", v.GetTitle())
	}
}

Error:

[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0x2e358e]

goroutine 1 [running]:
github.com/thecsw/mira.(*Reddit).addQueue(...)
	/tmp/gopath892572453/pkg/mod/github.com/thecsw/[email protected]+incompatible/reddit.go:624
github.com/thecsw/mira.(*Reddit).Subreddit(...)
	/tmp/gopath892572453/pkg/mod/github.com/thecsw/[email protected]+incompatible/reddit.go:50
main.main()
	/tmp/sandbox199244126/prog.go:15 +0x10e

Sure i placed my login info right but getting the same error on 2 of my devices and on play.golang.org.
I´m definitely not an go expret so don´t know if there is an easy fix?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.