Skip to content
This repository has been archived by the owner on Oct 15, 2023. It is now read-only.

Add Support for the v9 API #1

Merged
merged 18 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 0 additions & 20 deletions .travis.yml

This file was deleted.

56 changes: 56 additions & 0 deletions Examples/Buttons.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Sword

let bot = Sword(token: "Super secret token here")

bot.setIntents(intents: .guilds)

// Create our button(s)
bot.on(.messageCreate) { data in
let msg = data as! Message

if msg.content == "+button" {
let buttonBuilder = ButtonBuilder(message: "testing buttons with Sword!")
// Emojis are optional.
.addComponent(component: ActionRow(components: Button(customId: "test", style: .green, label: "Button with Emoji", emoji: Emoji("🎟️"))))
// To add another action row, call add component. Remember that Discord allows up to 5 action rows in 1 message
// You can have multiple buttons in 1 action row by making a `Button` struct as many times as needed.
.addComponent(component: ActionRow(components:
Button(
customId: "test_2",
style: .blurple,
label: "Blurple Button"
),
Button(
customId: "test_3",
style: .red,
lable: "Danger!"
)))

msg.reply(with: buttonBuilder)

}
}

// Now listen for the button clicks
bot.on(.buttonEvent) { data in
var button = data as! ButtonEvent

// If the command may take a while to complete, we can make the bot display the `is thinking...` text
// It returns a ResponseError in the closure which should never really be needed
event.deferReply { _ in }

// If we would like to only allow the user who invoked the command to see the output, we can set ephemeral
event.setEphemeral(isEphermeral: true)

if button.selectedButton.customId == "test" {
button.reply(message: "Test button was clicked!")
}
else if button.selectedButton.customId == "test_2" {
button.reply(message: "Blurple button was clicked!")
}
else if button.selectedButton.customId == "test_3" {
button.reply(message: "Stranger Danger!")
}
}

bot.connect()
45 changes: 45 additions & 0 deletions Examples/Select Menu.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Sword

let bot = Sword(token: "Super secret token here")

bot.setIntents(intents: .guilds, .guildMessages)

bot.on(.messageCreate) { data in
let msg = data as! Message

// You can send multiple Select Menu's by calling .addComponent again.
// customID is the ID for the entire SelectMenu object, while value is the customID for that selection.
let menu = SelectMenuBuilder(message: "Testing Select Menu's in Sword!")
.addComponent(component: ActionRow(components:
SelectMenu(
customId: "test",
placeholder: "Test 1",
options: SelectMenuOptions(
label: "Testing with Sword",
value: "test_section",
description: "We are testing a select menu with Sword"))
)
)
}

// Now we listen for the event
bot.on(.selectBoxEvent) { data in
var box = data as! SelectMenuEvent

// If the command may take a while to complete, we can make the bot display the `is thinking...` text
// It returns a ResponseError in the closure which should never really be needed
event.deferReply { _ in }

// If we would like to only allow the user who invoked the command to see the output, we can set ephemeral
event.setEphemeral(isEphermeral: true)

// First we check if the selected option is in the SelectMenu we would like to respond to
if box.selectedValue.customId == "test" {
// Now we check for the actual selected option
if box.selectedValue.value == "test_section" {
box.reply(message: "We interacted with a select menu!")
}
}
}

bot.connect()
47 changes: 47 additions & 0 deletions Examples/Slash Commands.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Sword

let bot = Sword(token: "Super secret token here")

bot.setIntents(intents: .guilds)

// Create slash command
// NOTE: This creates a guild only slash command. When we do support global slash commands, you can call the Sword instance
let command = SlashCommandBuilder(name: "test", description: "Testing slash commands in Sword")
.addOption(option: ApplicationCommandOptions(name: "user", description: "User to select", type: .user))

bot.guilds[guildId].uploadSlashCommand(commandData: slashBuilder)

// Listen for slash commands
bot.on(.slashCommandEvent) { data in
var event = data as! SlashCommandEvent

if event.name == "test" {
// If the command may take a while to complete, we can make the bot display the `is thinking...` text
// It returns a ResponseError in the closure which should never really be needed
event.deferReply { _ in }

// If we would like to only allow the user who invoked the command to see the output, we can set ephemeral
event.setEphemeral(isEphermeral: true)

// Retriving options is extremely simple!
// For Boolean: event.getOptionAsBool(optionName: "optionName") NOTE: You will need to cast the `Channel` type to the channel type you want.
// For Channels: event.getOptionAsChannel(optionName: "optionName")
// For Double: event.getOptionAsDouble(optionName: "optionName")
// For Integer: event.getOptionAsInt(optionName: "optionName")
// For Member: event.getOptionAsMember(optionName: "optionName")
// For String: event.getOptionAsString(optionName: "optionName")
// For Role: event.getOptionAsRole(optionName: "optionName")
// For User: event.getOptionAsUser(optionName: "optionName")
let selectedUser = event.getOptionAsUser(optionName: "user")!.username!

// Sending messages are simple as well!
// All InteractionEvent types have the same functions for sending, editing and deleting messages.
// For sending a normal message: event.reply(message: "message")
// For sending an embed(s): event.replyEmbeds(embeds: embedBuilderVar, embedBuilderVar2). You can also pass an `[EmbedBuilder]` type
// For sending a message with buttons: event.replyButtons(buttons: buttonBuilderVar)
// For sending a message with a select menu: event.replySelectMenu(menu: selectMenuBuilderVar)
event.reply(message: "User \(invokedUser) was selected!")
}
}

bot.connect()
26 changes: 13 additions & 13 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@
"object": {
"pins": [
{
"package": "SSCommonCrypto",
"repositoryURL": "https://github.com/Azoy/common-crypto-spm.git",
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio.git",
"state": {
"branch": null,
"revision": "7e9904a0d0c0024a86ab6fe5698ffc8f7799efb4",
"version": "1.2.0"
"revision": "51c3fc2e4a0fcdf4a25089b288dd65b73df1b0ef",
"version": "2.37.0"
}
},
{
"package": "Starscream",
"repositoryURL": "https://github.com/Azoy/Starscream.git",
"package": "swift-nio-ssl",
"repositoryURL": "https://github.com/apple/swift-nio-ssl.git",
"state": {
"branch": null,
"revision": "a21fca8e9dc83cf3a88a3ba9be15ff17a7e4e8d6",
"version": "3.0.5"
"revision": "52a486ff6de9bc3e26bf634c5413c41c5fa89ca5",
"version": "2.17.2"
}
},
{
"package": "SSCZLib",
"repositoryURL": "https://github.com/Azoy/zlib-spm.git",
"package": "websocket-kit",
"repositoryURL": "https://github.com/vapor/websocket-kit",
"state": {
"branch": null,
"revision": "f92fc0658af4cd9b11f233e9c02786ecbf75f1ee",
"version": "1.2.0"
"branch": "main",
"revision": "ff8fbce837ef01a93d49c6fb49a72be0f150dac7",
"version": null
}
}
]
Expand Down
34 changes: 6 additions & 28 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
// swift-tools-version:4.0

// swift-tools-version:5.3
import PackageDescription

var dependencies: [Package.Dependency] = []

var targetDeps: [Target.Dependency] = []

#if !os(Linux)
dependencies += [
.package(
url: "https://github.com/Azoy/Starscream.git",
.upToNextMajor(from: "3.0.0")
)
]

targetDeps += ["Starscream"]
#else
dependencies += [
.package(
url: "https://github.com/vapor/engine.git",
.upToNextMajor(from: "2.0.0")
)
]

targetDeps += ["URI", "WebSockets"]
#endif

let package = Package(
name: "Sword",
platforms: [.macOS(.v10_15),],
products: [
.library(name: "Sword", targets: ["Sword"])
],
dependencies: dependencies,
dependencies: [
.package(url: "https://github.com/vapor/websocket-kit", .branch("main"))
],
targets: [
.target(
name: "Sword",
dependencies: targetDeps
dependencies: [.product(name: "WebSocketKit", package: "websocket-kit")]
)
]
)
55 changes: 15 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
# Sword - A Discord Library for Swift

[![Swift Version](https://img.shields.io/badge/Swift-4.0-orange.svg?style=flat-square)](https://swift.org) [![Build Status](https://img.shields.io/travis/Azoy/Sword/master.svg?style=flat-square)](https://travis-ci.org/Azoy/Sword) [![Tag](https://img.shields.io/github/tag/Azoy/Sword.svg?style=flat-square&label=release&colorB=)](https://github.com/Azoy/Sword/releases)
[![Swift Version](https://img.shields.io/badge/Swift-5.3-orange.svg?style=flat-square)](https://swift.org) [![Tag](https://img.shields.io/github/tag/Azoy/Sword.svg?style=flat-square&label=release&colorB=)](https://github.com/Azoy/Sword/releases)

## Requirements
1. macOS, Linux, iOS, watchOS, tvOS (no voice for iOS, watchOS, or tvOS)
2. Swift 4.0
3. libsodium (if on macOS or Linux)

## Installing libsodium
### macOS
Installing libsodium is really easy on mac as long as you have [homebrew](https://brew.sh). After that is installed, all you have to do is `brew install libsodium`. That's it!

### Linux
This depends on the version of Ubuntu you are running, so I made a nice table here:

| Ubuntu 14.04 | Ubuntu 16.04 |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------:|
| `sudo -E add-apt-repository -y ppa:chris-lea/libsodium && sudo apt-get update && sudo apt-get install -y libsodium-dev` | `sudo apt-get update && sudo apt-get install -y libsodium-dev` |

It's easier to copy and paste that command right into shell, and follow any on screen instructions if needed so.
2. At least Swift 5.3

## Adding Sword
### Swift Package Manager
In order to add Sword as a dependency, you must first create a Swift executable in a designated folder, like so `swift package init --type executable`. Then in the newly created Package.swift, open it and add Sword as a dependency

```swift
// swift-tools-version: 4.0
// swift-tools-version: 5.3

import PackageDescription

let package = Package(
name: "yourswiftexecutablehere",
dependencies: [
.package(url: "https://github.com/Azoy/Sword", .branch("master"))
.package(url: "https://github.com/SketchMaster2001/Sword", .branch("master"))
],
targets: [
.target(
Expand All @@ -50,7 +36,12 @@ import Sword

let bot = Sword(token: "Your bot token here")

bot.editStatus(to: "online", playing: "with Sword!")
// Set activity if wanted
let activity = Activities(name: "with Sword!", type: .playing)
bot.editStatus(status: .online, activity: activity)

// Set intents which are required
bot.setIntents(intents: .guildMessages)

bot.on(.messageCreate) { data in
let msg = data as! Message
Expand All @@ -62,34 +53,18 @@ bot.on(.messageCreate) { data in

bot.connect()
```
For more examples, look in the examples folder or in the Wiki.

### CocoaPods
Adding Sword to your iOS, watchOS, or tvOS application is easier than ever with CocoaPods. All you have to do is add Sword as a dependency to your Podfile, something like this:

```ruby
target 'yourappnamehere' do
use_frameworks!
pod 'Sword'
end
```

Then all you have to do is `pod install` and you're ready to go.

## Running the bot (SPM)
Build the libraries with `swift build`, then type `swift run`
First make sure you are in the directory with the `Package.swift` file. To build the executable, run `swift build`. To build the executable and run it immediately, run `swift run`

## Running the bot in Xcode (SPM)
To run the bot in Xcode, you first have to compile the libraries with `swift build`. Then to build the xcode project, type `swift package generate-xcodeproj`. Finally, type `open yourswiftexecutablehere.xcodeproj`, look at the top and follow the steps below

![Step 1](images/step1.png)

![Step 2](images/step2.png)

![Step 3](images/step3.png)
To run the bot in Xcode, all you need to do is open the directory the `Package.swift` file is located in Xcode. Click the play button at the top left corner and it will run!

Then click the play button!

## Links
[Documentation](https://azoy.github.io/Sword/) - (created with [Jazzy](https://github.com/Realm/Jazzy))
The documentation for this repo is out of date due to jazzy not working on my computer. You can still use Azoy's site below to access documentation for pretty much everything except for interactions and message components.

Join the [API Channel](https://discord.gg/99a3xNk) to ask questions!
[Pre-v9 Documentation](https://azoy.github.io/Sword/) - (created with [Jazzy](https://github.com/Realm/Jazzy))