elephrame 0.4.6 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c1ed54678e256a816845886696ca58289d035a7351deb2ec8180915a36f2471
4
- data.tar.gz: 15cf11fd775bf2ec0716aa524af6a35ff7996ad724b311cccac89a087039eb5f
3
+ metadata.gz: da4cb8e7330a90534de1df0dfcd992669f3406081d8b84432026961116976184
4
+ data.tar.gz: '08828035932340977b30d9db147c5df568b08d5b5dfa835967ab6940d808ac1e'
5
5
  SHA512:
6
- metadata.gz: 3664bc68bad91273c4b99084729f01f21e2a7ab77f1e98397eb4f32b7c3906522c0105b049954d64bce0e4b5d1b83af7be548bf3ad1659f597e31dfe496c418e
7
- data.tar.gz: 57063548c113a5819ad8c73a94f07082fd2071ac7acc3ffaa70b09eaf0cd9a72caf163911f03ec9cdf6358a9e478fc5b54c5d8d0e384ad055006525bc024859d
6
+ metadata.gz: 447b5a423594675b6d949ad2bb29a67d74db3cb278484c133f9213b10a622d3607a0a09ad2e55c363d7c76651fb1690091965f09e17d1534a2f9ed20b2ed017d
7
+ data.tar.gz: ed0d5bd6ee5869626d235de919b468ca768f14b8bb1b5da5dd6574edd8eccf3f10f6fa7ac6e3badf769ea6879ce5b233cb05436b0eb3fa4ece2e9be5972e7847
data/Gemfile CHANGED
@@ -4,3 +4,5 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in elephrame.gemspec
6
6
  gemspec
7
+
8
+ gem 'tzinfo-data', :platforms => [:mingw, :x64_mingw, :mswin]
data/Gemfile.lock CHANGED
@@ -1,7 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elephrame (0.4.6)
4
+ elephrame (0.5)
5
+ htmlentities (~> 4.0)
6
+ moo_ebooks (~> 1)
5
7
  moostodon (~> 0.4.0)
6
8
  rufus-scheduler
7
9
  tracery (~> 0.7)
@@ -13,13 +15,16 @@ GEM
13
15
  public_suffix (>= 2.0.2, < 4.0)
14
16
  buftok (0.2.0)
15
17
  concurrent-ruby (1.1.5)
16
- domain_name (0.5.20180417)
18
+ domain_name (0.5.20190701)
17
19
  unf (>= 0.0.5, < 1.0.0)
18
- et-orbi (1.1.7)
20
+ et-orbi (1.2.1)
19
21
  tzinfo
20
- fugit (1.1.8)
21
- et-orbi (~> 1.1, >= 1.1.7)
22
+ fugit (1.3.1)
23
+ et-orbi (~> 1.1, >= 1.1.8)
22
24
  raabro (~> 1.1)
25
+ highscore (1.2.1)
26
+ whatlanguage (>= 1.0.0)
27
+ htmlentities (4.3.4)
23
28
  http (3.3.0)
24
29
  addressable (~> 2.3)
25
30
  http-cookie (~> 1.0)
@@ -30,32 +35,40 @@ GEM
30
35
  http-form_data (2.1.1)
31
36
  http_parser.rb (0.6.0)
32
37
  minitest (5.11.3)
38
+ moo_ebooks (1.1.0)
39
+ highscore (~> 1.2)
40
+ htmlentities (~> 4.3)
33
41
  moostodon (0.4.0)
34
42
  addressable (~> 2.5)
35
43
  buftok (~> 0)
36
44
  http (~> 3.0)
37
45
  oj (~> 3.3)
38
- oj (3.7.10)
39
- public_suffix (3.0.3)
46
+ oj (3.8.1)
47
+ public_suffix (3.1.1)
40
48
  raabro (1.1.6)
41
49
  rake (10.5.0)
42
- rufus-scheduler (3.5.2)
43
- fugit (~> 1.1, >= 1.1.5)
50
+ rufus-scheduler (3.6.0)
51
+ fugit (~> 1.1, >= 1.1.6)
44
52
  tracery (0.7.7)
45
53
  tzinfo (2.0.0)
46
54
  concurrent-ruby (~> 1.0)
55
+ tzinfo-data (1.2019.2)
56
+ tzinfo (>= 1.0.0)
47
57
  unf (0.1.4)
48
58
  unf_ext
49
- unf_ext (0.0.7.5)
59
+ unf_ext (0.0.7.6)
60
+ whatlanguage (1.0.6)
50
61
 
51
62
  PLATFORMS
52
63
  ruby
64
+ x64-mingw32
53
65
 
54
66
  DEPENDENCIES
55
67
  bundler (~> 1.17)
56
68
  elephrame!
57
69
  minitest (~> 5.0)
58
70
  rake (~> 10.0)
71
+ tzinfo-data
59
72
 
60
73
  BUNDLED WITH
61
- 1.17.2
74
+ 1.17.3
data/README.md CHANGED
@@ -19,11 +19,11 @@ gem 'elephrame'
19
19
 
20
20
  And then execute:
21
21
 
22
- $ bundle
22
+ bundle
23
23
 
24
24
  Or install it yourself as:
25
25
 
26
- $ gem install elephrame
26
+ gem install elephrame
27
27
 
28
28
  ## Quickstart
29
29
 
@@ -34,15 +34,17 @@ require 'elephrame'
34
34
 
35
35
  my_bot = Elephrame::Bots::Periodic.new '3h'
36
36
 
37
- my_bot.run { |bot|
37
+ my_bot.run do |bot|
38
38
  bot.post("i'm gay")
39
- }
39
+ end
40
40
  ```
41
41
 
42
42
  $ INSTANCE="https://mastodon.social" TOKEN="your_access_token" ruby bot.rb
43
43
 
44
44
  Check the [examples](https://github.com/theZacAttacks/elephrame/tree/master/examples) directory for more example bots
45
45
 
46
+ If you're new to ruby development in general there is also a [getting started](https://github.com/theZacAttacks/elephrame/tree/master/examples/getting_started.org) document in the examples folder that I would recommend you to read. It takes a high level approach to getting started with ruby, some basic syntax, working with gems, basic project structure, and more!
47
+
46
48
  ### Bot Types
47
49
 
48
50
  So far the framework support 6 bot types: Periodic, Interact, PeroidInteract, Reply, Command, Watcher
data/elephrame.gemspec CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  lib = File.expand_path("../lib", __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require "elephrame/version"
@@ -42,5 +41,7 @@ Gem::Specification.new do |spec|
42
41
 
43
42
  spec.add_dependency 'rufus-scheduler'
44
43
  spec.add_dependency 'moostodon', '~> 0.4.0'
44
+ spec.add_dependency 'moo_ebooks', '~> 1'
45
45
  spec.add_dependency 'tracery', '~> 0.7'
46
+ spec.add_dependency 'htmlentities', '~>4.0'
46
47
  end
@@ -0,0 +1,24 @@
1
+ require 'elephrame'
2
+
3
+ # So, we want to create an ebook bot
4
+ # all of the hardwork is done in the backend by the framework!
5
+ #
6
+ # we just need to make sure the account we're posting from is set up right
7
+ # make sure that the ebooks account is following all of the accounts you
8
+ # want to generate posts from (e.g., if you just want it to be a personal
9
+ # ebooks bot then just have it follow you,
10
+ # if you want it to generate posts from everyone
11
+ # in a group then make sure it follows them all)
12
+ #
13
+ # once that's taken care of we need to tell the framework some options for our bot
14
+ # how often to post, how often to get new statuses from the accounts it's following
15
+ # what the CW should be for all of its posts (this is polite ;3 )
16
+ # what the lowest level visiblility setting we should grab to generate from
17
+ #
18
+ # thats just what ive supplied in this example, but there are more options!
19
+ # to see them all please check the documentation (see main README for link)
20
+ bot = Elephrame::Bots::EbooksBot.new '1m', update_interval: '2d',
21
+ cw: 'ebooks post', scrape_privacy: 'unlisted'
22
+
23
+ # run the bot!
24
+ bot.run
@@ -0,0 +1,484 @@
1
+ * Getting Started
2
+
3
+ ** Table of Contents
4
+
5
+ - [[#ruby][Ruby]]
6
+ + [[#installing][Installing]]
7
+ + [[#playing-around][Playing around]]
8
+ + [[#basic-syntax][Basic Syntax]]
9
+ + [[#variables][Variables]]
10
+ + [[#constants][Constants]]
11
+ + [[#methods][Methods]]
12
+ + [[#string-interpolation][String Interpolation]]
13
+ + [[#blocks][Blocks]]
14
+ + [[#more-info][More Info]]
15
+ - [[#gems][Gems]]
16
+ + [[#what-are-gems][What are Gems?]]
17
+ + [[#install-gems][Install Gems]]
18
+ + [[#bundler][Bundler]]
19
+ - [[#running-a-script][Running a Script]]
20
+ + [[#without-bundler][Without Bundler]]
21
+ + [[#with-bundler][With Bundler]]
22
+ - [[#elephrame][Elephrame]]
23
+ + [[#bot-types][Bot Types]]
24
+ + [[#putting-it-all-together][Putting It All Together]]
25
+ + [[#getting-more-advanced][Getting More Advanced]]
26
+
27
+ ** Ruby
28
+ :PROPERTIES:
29
+ :CUSTOM_ID: ruby
30
+ :END:
31
+
32
+ *** Installing
33
+ :PROPERTIES:
34
+ :CUSTOM_ID: installing
35
+ :END:
36
+ If you use Linux/BSD then use your package manager to install ruby.
37
+
38
+ If you're on Mac you should have an older version of ruby installed. If you want to install a newer version I would recommend looking into [[https://brew.sh][homebrew]] and using it to install an updated ruby version.
39
+
40
+ If you're on Windows there is [[https://rubyinstaller.org/downloads/][RubyInstaller]]. Make sure you choose the one that has the devkit! It's important uwu
41
+
42
+ Once you have ruby installed we can check and make sure!
43
+
44
+ Open up your command line (cmd on Windows, Terminal on Linux/BSD/Mac) and type in =ruby --version=
45
+
46
+ If everything has been set up properly it'll print out the version of ruby you're using!
47
+
48
+ *** Playing around
49
+ :PROPERTIES:
50
+ :CUSTOM_ID: playing-around
51
+ :END:
52
+ To play around in an interactive environment open up your command line and type in =irb= (Interactive RuBy)
53
+
54
+ This drops you into an interactive ruby shell where you are free to experiment and play around with new ideas without having to write an entirely new file.
55
+
56
+ Feel free to play around in this! Any code I have written in here can be executed in this environment.
57
+
58
+ *** Basic Syntax
59
+ :PROPERTIES:
60
+ :CUSTOM_ID: basic-syntax
61
+ :END:
62
+ There are a lot of data types in ruby:
63
+
64
+ - strings
65
+ - hash tables
66
+ - arrays
67
+ - integers
68
+ - floating point numbers
69
+ - files
70
+ - symbols
71
+ - ... and a lot more!
72
+
73
+ I'm going to go over how a few of these different data types are represented in ruby.
74
+
75
+ Strings in ruby can be written in a few different ways: 'this is a string', "So is this" (this difference will be covered later!)
76
+
77
+ Numbers (floating point or integers) are the easiest to write because it's just a number! E.g., 4, 7.5, 220, -10
78
+
79
+ Arrays are just a list of other objects and are represented like this: [1, 2, 3], ["First", "Second", "Third"]
80
+
81
+ Hash tables are basically arrays that allow you to reference bits of data out of them using words. They look very similar to arrays, so don't get confused! E.g., { first: 1, second: 2 }
82
+
83
+ *** Variables
84
+ :PROPERTIES:
85
+ :CUSTOM_ID: variables
86
+ :END:
87
+ In ruby you can store data in 'holders' called variables. Imagine it's like putting water into a jug, you're just storing it in a place you know for later!
88
+
89
+ It's as easy as this:
90
+
91
+ #+BEGIN_SRC ruby
92
+ variable = "Testing"
93
+ #+END_SRC
94
+
95
+ Variables can be named anything, so long as they don't contain certain special characters or start with a number or a capital letter.
96
+
97
+ Invalid variable names:
98
+
99
+ #+BEGIN_SRC ruby
100
+ 1variable
101
+ #+END_SRC
102
+
103
+ Valid variable names:
104
+
105
+ #+BEGIN_SRC ruby
106
+ variable1
107
+ test_variable
108
+ really_long_variable_name
109
+ #+END_SRC
110
+
111
+ Variablese can be reused as many times as you want. So if you have some code like this:
112
+
113
+ #+BEGIN_SRC ruby
114
+ my_variable = 15
115
+ my_variable = my_variable + 3
116
+ #+END_SRC
117
+
118
+ Then it would store the result of 18 back into =my_variable=!
119
+
120
+ *** Constants
121
+ :PROPERTIES:
122
+ :CUSTOM_ID: constants
123
+ :END:
124
+ Constants are like variables, but instead of being able to change them on the fly they remain the same (constant!).
125
+
126
+ How do we tell variables apart from constants? It's easy! All constants are capitalized.
127
+
128
+ This is a constant: =ImportantConstant= and this is a variable: =important_variable=
129
+
130
+ Constants can only be defined once and whatever data you put into one stays there. So be careful that you won't need to modify anything after you put it into a constant.
131
+
132
+ *** Methods
133
+ :PROPERTIES:
134
+ :CUSTOM_ID: methods
135
+ :END:
136
+
137
+ Methods are chunks of code that are grouped underneath a single name.
138
+ They allow a developer to easily reuse code across a project.
139
+
140
+ To define a method you need to do the following:
141
+
142
+ #+BEGIN_SRC ruby
143
+ def example
144
+ end
145
+ #+END_SRC
146
+
147
+ Any code that you put between the line starting with =def= and the line starting with =end= will be able to run by just writing =example=!
148
+
149
+ if you wanted to be able to pass data into methods we can do that, too!
150
+
151
+ #+BEGIN_SRC ruby
152
+ def example(param1, param2)
153
+ end
154
+ #+END_SRC
155
+
156
+ you now would call example this: =example(1,2)= and any code inside of the method would have access to =1,2= through the variables =param1, param2=!
157
+
158
+ *** String Interpolation
159
+ :PROPERTIES:
160
+ :CUSTOM_ID: string-interpolation
161
+ :END:
162
+ Okay so let's go back to strings and the differences between strings 'like this' and strings "like this".
163
+
164
+ Let's say you've got a variable named =output_data= and you wanted to print it out with some text around it.
165
+ In other programming language you'd have to do something like this:
166
+
167
+ #+BEGIN_SRC python
168
+ "Here's the data " + output_data + " that I found!"
169
+ #+END_SRC
170
+
171
+ but ruby allows for a really nifty thing called String Interpolation.
172
+ Here's how it looks:
173
+
174
+ #+BEGIN_SRC ruby
175
+ "Here's the data #{output_data} that I found!"
176
+ #+END_SRC
177
+
178
+ As you can tell, it makes it look a lot nicer and a lot easier to add variables into strings!
179
+
180
+ Not only can you put variables into strings like this, you can also put method calls! Any kind of code can go in there!
181
+
182
+ #+BEGIN_SRC ruby
183
+ "Some really cool data: #{my_cool_method()}"
184
+ #+END_SRC
185
+
186
+ *** Blocks
187
+ :PROPERTIES:
188
+ :CUSTOM_ID: blocks
189
+ :END:
190
+
191
+ Blocks are a fairly unique thing to ruby. They allow you do define code and pass them as parameters to methods. Here's an example:
192
+
193
+ #+BEGIN_SRC ruby
194
+ example_method do
195
+ puts "Hello from a block!"
196
+ end
197
+ #+END_SRC
198
+
199
+ Everything between (and including) =do= and =end= is a block! You can pass it to functions, and if they support accepting blocks they'll be able to run whatever code you include! This is useful, but it's made even more useful because data can be passed *in* to a block as well. Here's an example of how that looks:
200
+
201
+ #+BEGIN_SRC ruby
202
+ example_method2 do |data, data2|
203
+ puts "Hello from a block!"
204
+ puts "I recieved this data: #{data}"
205
+ puts "I recieved this data as well: #{data2}"
206
+ end
207
+ #+END_SRC
208
+
209
+ Think about the syntax like this: =data= and =data2= are *sliding* into the block. That's why they need the =|= s on either side of them! Otherwise how will they safely get in there? :P
210
+
211
+ *** More info
212
+ :PROPERTIES:
213
+ :CUSTOM_ID: more-info
214
+ :END:
215
+
216
+ If this quick intro to ruby has sparked your interest and you want to know more about it, i recommend this [[https://poignant.guide/book/chapter-3.html][guide]]. it can be a bit much at some points, but i found it a great introduction to ruby!
217
+
218
+ ** Gems
219
+ :PROPERTIES:
220
+ :CUSTOM_ID: gems
221
+ :END:
222
+
223
+ *** What are Gems?
224
+ :PROPERTIES:
225
+ :CUSTOM_ID: what-are-gems
226
+ :END:
227
+ In the world of ruby third-party libraries are referred to as gems. They are offered by many places, but the primary source of gems is [[https://rubygems.org][RubyGems]]. There are a *lot* of gems there. Go and check some of them out!
228
+
229
+ *** Install Gems
230
+ :PROPERTIES:
231
+ :CUSTOM_ID: install-gems
232
+ :END:
233
+ Knowing about gems is nice and all but how do you get them onto your system? Well, when you installed ruby you got a nice little utility installed, called =gem=.
234
+
235
+ So let's go back to your command line, if you're still in =irb= you can either open a new window or type =quit= to exit it. Once you're back at the main command line interface run =gem -h= to have the gem utility print out a little help text.
236
+
237
+ Let's go ahead and install a gem that we'll be using for the next section: bundler.
238
+
239
+ =gem install bundler=
240
+
241
+ *** Bundler
242
+ :PROPERTIES:
243
+ :CUSTOM_ID: bundler
244
+ :END:
245
+ Bundler is a cool utility that allows you to install gems on a per-project level, keeping the system gem cache clean! If you're following along then you should have it installed now, so lets see some of what it can do: =bundle -h=
246
+
247
+ As you can see there are a lot of subcommands! The ones that you'll primarily be using are 'install' and 'exec'. The install command, appropriately installs a gem onto your system. The exec command is a little more abstract. It takes whatever other commands after 'exec' and runs them in the context of that project.
248
+
249
+ So if you have a certain gem installed in a project and you want to play around with using it with =irb= then you would run =bundle exec irb= and then you'd be able to have an interactive playground with all the gems from that project!
250
+
251
+ **** Gemfile
252
+ :PROPERTIES:
253
+ :CUSTOM_ID: gemfile
254
+ :END:
255
+ This is neat and all, but how does bundler know what gems a specific project needs? Well, thats where the Gemfile comes into play. The Gemfile contains the source, specifications, and versions of any gems you want to use in your project. Here is an example Gemfile that tells bundler to use the elephrame gem!
256
+
257
+ #+BEGIN_SRC ruby
258
+ source 'https://rubygems.org'
259
+
260
+ gem 'elephrame'
261
+ #+END_SRC
262
+
263
+ There are a lot of extra options that you can use in a Gemfile, but at its basest this is how to use one!
264
+
265
+ **** Project Structure
266
+ :PROPERTIES:
267
+ :CUSTOM_ID: project-structure
268
+ :END:
269
+ So now that we've got a basic Gemfile, where do we put it? It belongs at the top level of your project! So, assuming we have our project in its own folder and our project's main ruby file is called =main.rb=, our file structure would look something like this:
270
+
271
+ #+BEGIN_SRC
272
+ project_folder/
273
+ project_folder/Gemfile
274
+ project_folder/main.rb
275
+ #+END_SRC
276
+
277
+ And that's it!
278
+
279
+ After you have your project setup like this, you need to tell bundler to install your gems. To do that all you have to do is have your project opened in your command line and run =bundle install= and it'll get the rest set up properly!
280
+
281
+ ** Running a script
282
+ :PROPERTIES:
283
+ :CUSTOM_ID: running-a-script
284
+ :END:
285
+ After you've put all the work into a cool app or project you'd want to be able to run it right? Since ruby is an interpreted language it doesn't need to be compiled before we execute it. However, this also means that we can't just execute our new program, we have to tell the ruby interpretor to read the file and start executing it.
286
+
287
+ Both of the following examples assume a project strutcure like the above.
288
+
289
+ *** Without Bundler
290
+ :PROPERTIES:
291
+ :CUSTOM_ID: without-bundler
292
+ :END:
293
+ If your project does not use bundler then there are a few steps you don't have to take, so we can just jump right to executing the script.
294
+
295
+ Open your command line interface, go to your project's folder and execute: =ruby main.rb=
296
+
297
+
298
+ *** With Bundler
299
+ :PROPERTIES:
300
+ :CUSTOM_ID: with-bundler
301
+ :END:
302
+ If your project does use bundler then we have to first make sure that all of your gem dependecies are up to date: =bundle install=
303
+
304
+ Once that finishes, open your command line interface, go to your project's folder and execute: =bundle exec ruby main.rb=
305
+
306
+ We use =bundle exec= because we need ruby to run in the context of the project and use the gems that the project needs.
307
+
308
+
309
+ ** Elephrame
310
+ :PROPERTIES:
311
+ :CUSTOM_ID: elephrame
312
+ :END:
313
+
314
+ elephrame is a high level framework for creating bots for mastodon/pleroma. It abstracts away a lot of the routines that a bot developer would have to write in order to get started, providing 'templates' that you can overwrite with your own custom functionality.
315
+
316
+
317
+ *** Bot Types
318
+ :PROPERTIES:
319
+ :CUSTOM_ID: bot-types
320
+ :END:
321
+
322
+ elephrame has many different types of bots, here's a list of the different types and their intended purposes:
323
+
324
+ - Periodic: posts statuses on a specific schedule or interval
325
+ - Interact: provides ways to call code when an account gets an interaction (boost, favorite, reply, follow)
326
+ - PeriodInteract: combines the above two functionalities
327
+ - Command: provides an easy way to create bots that wait for specific commands before doing anything ('!help', '!update', etc.)
328
+ - Watcher: watches a specific timeline (global, local, hashtag, home) for updates and runs code when it sees posts
329
+ - TraceryBot: very similar to PeriodInteract, except it provides shortcuts for using tracery style grammar files
330
+ - EbooksBot: scans all posts from an account or accounts and generates new posts/replies based off of that input
331
+ - Markov-bot: scans a text file and generates posts/replies based off of that input
332
+
333
+ *** Putting It All Together
334
+ :PROPERTIES:
335
+ :CUSTOM_ID: putting-it-all-together
336
+ :END:
337
+
338
+ Okay! Enough explanation, lets create a bot!
339
+
340
+ Assuming you have ruby installed and set up properly, create a folder to hold your files. I'll name mine =getting-started-example=
341
+
342
+ Once the folder is created, lets go and create our Gemfile. Open your text editor and create a new file in your folder named =Gemfile= and inside of it put the following:
343
+
344
+ #+BEGIN_SRC ruby
345
+ source 'https://rubygems.org'
346
+
347
+ gem 'elephrame'
348
+ #+END_SRC
349
+
350
+ Once you have done that, make sure you save it and open up your command line. You'll want to go to your project folder, and once there do a quick =bundle install=
351
+
352
+ That will install your gems that you've specified in your Gemfile. Your project folder should look something like this (I'm going to use my folder name, just pretend it's yours!):
353
+
354
+ #+BEGIN_SRC
355
+ getting-started-example/
356
+ getting-started-example/Gemfile
357
+ getting-started-example/Gemfile.lock
358
+ #+END_SRC
359
+
360
+ Now, back in your text editor, create a new file in your folder called =main.rb= and enter this into it (don't worry, we'll go over it line by line in a second):
361
+
362
+ #+BEGIN_SRC ruby
363
+ require 'elephrame'
364
+
365
+ ExampleBot = Elephrame::Bots::Periodic.new '10s'
366
+
367
+ ExampleBot.run do |bot|
368
+ bot.post("Hello, world!")
369
+ end
370
+ #+END_SRC
371
+
372
+ Let's break that down!
373
+
374
+ #+BEGIN_SRC ruby
375
+ require 'elephrame'
376
+ #+END_SRC
377
+
378
+ This first line loads the elephrame library. We call the process whereby ruby loads an external library =requiring= that library. When you =require= a library it gets loaded into the current ruby process and allows us to use code that is a part of it. Usually you'll want to keep any =require= statements at the top of your ruby programs, so that anyone who reads through your code knows what all is bring loaded!
379
+
380
+ #+BEGIN_SRC ruby
381
+ ExampleBot = Elephrame::Bots::Periodic.new '10s'
382
+ #+END_SRC
383
+
384
+ This second line shows us creating a new Periodic bot (=Elephrame::Bots::Periodic.new=), passing it ='10s'= and assigning it to the constant =ExampleBot=. In ruby objects can 'live' in a 'package'. 'Packages' are like folders in your filesystem, however instead of being separated with an '/' or '\' they're separated with '::'. So one way to look at this is 'use the Periodic object in the Bots folder of Elephrame'. The =.new= at the end is saying 'create a new instance of this object'. We're passing in ='10s'= because a Periodic bot needs to know how often it needs to post, this is saying 'post every 10 seconds'.
385
+
386
+ Putting all of that together: "create a new instance of the Periodic object from the Bots folder of Elephrame, tell it to post every 10 seconds, and put that bot inside of ExampleBot"
387
+
388
+ #+BEGIN_SRC ruby
389
+ ExampleBot.run do |bot|
390
+ bot.post("Hello, world!")
391
+ end
392
+ #+END_SRC
393
+
394
+ Now we're getting to the tricky parts! =ExampleBot.run= is a method that takes a block which is what elephrame does when it runs the bot. So, like explained above, we do a block (the =do ... end= parts). This block passes out a parameter which gives us access to the bot letting us post, among other things! The next line, =bot.post("Hello, world!")= is the logic that runs every time the bot is supposed to run. It tells the framework to simply post the status "Hello, world!". There are many options that the =post= method supports, but for this simple case just providing the status to post will do.
395
+
396
+ Now that we've gone over it, make sure you save it! Your project folder should now look something like this:
397
+
398
+ #+BEGIN_SRC
399
+ getting-started-example/
400
+ getting-started-example/Gemfile
401
+ getting-started-example/Gemfile.lock
402
+ getting-started-example/main.rb
403
+ #+END_SRC
404
+
405
+ Now that we've got all of the files set up, we need to get our bot's token! Without a token our bot can't make or read posts. Open Mastodon (it can be your account for now, but I would encourage you to make a separate account for your bot once it's finished), and open the settings. There will be an option on the side for 'Development' settings. Open that, and then generate a new application token. Set the name to "My Elephrame Example", leaving the homepage blank and the redirect URI set to the default. You can give the bot any permissions you want, but this example bot needs (at least) the write:status permission. Once you've filled out the necessary fields go and click 'save' at the bottom. It will take you back to the main development menu, except your newly created application will be an option to click. Go ahead and click on it and copy the access token it shows. This token is very special and is what allows your bot to connect to Mastodon!
406
+
407
+ Open up your command line, and run the following in your project folder:
408
+
409
+ Linux/MacOS: ~INSTANCE="https://your.instance" TOKEN="yourToken" bundle exec ruby main.rb~
410
+
411
+ Windows:
412
+
413
+ #+BEGIN_SRC bat
414
+ set INSTANCE=https://your.instance
415
+ set TOKEN=yourToken
416
+ bundle exec ruby main.rb
417
+ #+END_SRC
418
+
419
+
420
+ If everything worked properly then running these commands will cause your command line to appear to hang up, as though it's waiting for input. That means your bot is working!
421
+
422
+ If you have your Mastodon account open (the account you got the token from) then after 10 seconds you should see a post from your account saying "Hello, World!". Since this is the only code our bot has it will continue posting this every 10 seconds forever.
423
+
424
+ Congratulations! You've made your first Mastodon bot! :3
425
+
426
+ *** Getting More Advanced
427
+ :PROPERTIES:
428
+ :CUSTOM_ID: getting-more-advanced
429
+ :END:
430
+
431
+ Now that you've gotten your first bot under your belt, let's expand on it! Let's add in the ability for the bot to respond to replies!
432
+
433
+ To do this, we're going to change the base type of the bot to =PeriodInteract= and add in some code to handle what happens when we get a reply.
434
+
435
+ Reopen =main.rb= in your text editor if you don't still have it open and edit it until it resembles the following:
436
+
437
+ #+BEGIN_SRC ruby
438
+ require 'elephrame'
439
+
440
+ ExampleBot = Elephrame::Bots::PeriodInteract.new '10s'
441
+
442
+ ExampleBot.on_reply do |bot, post|
443
+ bot.reply("Hello, user!")
444
+ end
445
+
446
+ ExampleBot.run do |bot|
447
+ bot.post("Hello, world!")
448
+ end
449
+ #+END_SRC
450
+
451
+ Let's break those changes down a bit!
452
+
453
+ First things first: we changed what kind of bot we're using from =Periodic= to =PeriodicInteract=.
454
+
455
+ #+BEGIN_SRC ruby
456
+ ExampleBot.on_reply do |bot, post|
457
+ bot.reply("Hello, user!")
458
+ end
459
+ #+END_SRC
460
+
461
+ We also added in a new method, =on_reply=. It looks very similar to how we use =run= doesn't it? That's because we do use it the exact same way! PeriodInteract allows us to react whenever the bot's account receives any kind of interaction through =on_fave=, =on_boost=, =on_follow=, and =on_reply= methods. Each of these methods accept a block just like the =run= method does, however, these methods pass in another object besides just the main bot one like =run= does. They pass in =bot= (a reference to the main bot object) and =post= (a reference to the post that received the interaction [except in the case of =on_reply=, which receives the reply itself]). The code inside the block is also slightly different than that of the =run= method in that instead of using the =bot.post= method we use the =bot.reply= method. That method, as you may have guessed, this makes the bot reply to the new mention with ="Hello, user!"=.
462
+
463
+ Saving and running it from your command line will have your bot posting every 10 seconds and also replying to any user who replies to one of their posts!
464
+
465
+
466
+ This is good and all, but it feels so impersonal, but we can fix that!
467
+
468
+ Change the =on_reply= code to this:
469
+
470
+ #+BEGIN_SRC ruby
471
+ ExampleBot.on_reply do |bot, post|
472
+ user_name = post.account.display_name
473
+ bot.reply("Hello, #{user_name}!")
474
+ end
475
+ #+END_SRC
476
+
477
+ What we have now will respond back to a reply with their display name! To accomplish this we've combined a lot of the basics that we've covered above!
478
+
479
+ To start with, we save the display name for the account that the reply came from (=post.account.display_name=), and put it into the reply string using string interpolation (="Hello, #{user_name}!"=).
480
+
481
+ Let me explain how we got the account's display name. Each post object contains a lot of data about itself including the =account= it came from, the =content= of the post, it's =id=, it's =spoiler_text= (Content Warning), and much more! The account object is very similar, containing it's =id=, =username=, =acct= (full account handle e.g., example@test.lol), and =display_name=.
482
+
483
+ *Note: most data exposed through Mastodon objects can be found [[https://docs.joinmastodon.org/api/entities/][here]].*
484
+
@@ -0,0 +1,20 @@
1
+ require 'elephrame'
2
+
3
+ # tell the bot how often to post, and where to find it's source material,
4
+ # then we go and set options for it
5
+ marxkov = Elephrame::Bots::MarkovBot.new '3h', 'markov_files',
6
+ visibility: 'unlisted', cw: 'markov post'
7
+
8
+ # then we tell the bot to post
9
+ marxkov.run
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+