Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat sendmessage swift #167

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update package.swift and move all code to Sources to work with the sw…
…ift openruntime
  • Loading branch information
zachspang committed Jul 28, 2023
commit 5aa62a123f2839e6e7487690019c81f162215084
20 changes: 10 additions & 10 deletions swift/send-message/Package.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
// swift-tools-version:5.8
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription


let package = Package(
name: "twitter",
platforms: [.macOS(.v12)],
name: "send-message",
dependencies: [
.package(url: "https://github.com/swift-server/async-http-client", from: "1.18.0"),
.package(url: "https://github.com/apple/swift-crypto.git", from: "2.0.3")
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0"),
.package(url: "https://github.com/apple/swift-crypto.git", from: "2.0.3"),
],
targets: [
.executableTarget(
name: "twitter",
name: "send-message",
dependencies: [
.product(name: "AsyncHTTPClient", package: "async-http-client"),
.product(name: "Crypto", package: "swift-crypto")
])
.product(name: "Crypto", package: "swift-crypto"),
],
path: "Sources"
),
]
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ import NIOFoundationCompat
let createDMURL = "https://discord.com/api/v10/users/@me/channels"

class DiscordMessenger: Messenger{
private let botToken: String
private let guildID: String
private let discordBotToken: String
private let discordGuildID: String
private let httpClient: HTTPClient

init(_ env_vars: [String: String]) throws {
guard let botToken = env_vars["BOT_TOKEN"],
let guildID = env_vars["GUILD_ID"] else {
init(_ env_vars: [String: String], httpClient: HTTPClient) throws {
guard let discordBotToken = env_vars["DISCORD_BOT_TOKEN"],
let discordGuildID = env_vars["DISCORD_GUILD_ID"] else {
throw MessengerError.misconfigurationError(error: "Missing environment variables.")
}
self.botToken = botToken
self.guildID = guildID
httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
self.discordBotToken = discordBotToken
self.discordGuildID = discordGuildID
self.httpClient = httpClient
}
public func searchUsersByUsername(json: [[String:Any]], username: String) throws -> String{

private func getIDFromUsername(json: [[String:Any]], username: String) throws -> String{
for user in json{
let currentUsername = ((user["user"]) as! [String: Any])["username"] as! String

Expand All @@ -32,11 +33,11 @@ class DiscordMessenger: Messenger{

//Returns a recipient id given their username
private func getRecipientID(username: String) async throws -> String{
let targetURL = "https://discord.com/api/v10/guilds/\(guildID)/members/search?query=\(username)&limit=1000"
let targetURL = "https://discord.com/api/v10/guilds/\(discordGuildID)/members/search?query=\(username)&limit=1000"
var request = HTTPClientRequest(url: targetURL)

request.method = .GET
request.headers.add(name: "Authorization", value: botToken)
request.headers.add(name: "Authorization", value: discordBotToken)

let response:HTTPClientResponse
do{
Expand All @@ -53,7 +54,7 @@ class DiscordMessenger: Messenger{
throw MessengerError.validationError(error: "Unable to get recipient id, API Status Code: \(response.status), API Error Message: \((responseBodyJson as! [String: Any])["message"] ?? "none")")
}

return try searchUsersByUsername(json: responseBodyJson as! Array<[String: Any]>, username: username)
return try getIDFromUsername(json: responseBodyJson as! Array<[String: Any]>, username: username)
}

//Returns dm channel ID. If there isn't already a dm channel with a user one is made.
Expand All @@ -63,7 +64,7 @@ class DiscordMessenger: Messenger{

request.method = .POST
request.headers.add(name: "Content-Type", value: "application/json")
request.headers.add(name: "Authorization", value: botToken)
request.headers.add(name: "Authorization", value: discordBotToken)
request.body = .bytes(ByteBuffer(data: (try JSONSerialization.data(withJSONObject: jsonRecipientID))))

let response:HTTPClientResponse
Expand Down Expand Up @@ -99,7 +100,7 @@ class DiscordMessenger: Messenger{

request.method = .POST
request.headers.add(name: "Content-Type", value: "application/json")
request.headers.add(name: "Authorization", value: botToken)
request.headers.add(name: "Authorization", value: discordBotToken)

do{
request.body = .bytes(ByteBuffer(data: (try JSONSerialization.data(withJSONObject: jsonMessage))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class EmailMessenger: Messenger{
private let fromEmailAddress: String
private let httpClient: HTTPClient

init(_ env_vars: [String: String]) throws{
init(_ env_vars: [String: String], httpClient: HTTPClient) throws{
guard let mailgunAPIKey = env_vars["MAILGUN_API_KEY"],
let mailgunDomain = env_vars["MAILGUN_DOMAIN"] else {
throw MessengerError.misconfigurationError(error: "Missing environment variables.")
Expand All @@ -21,7 +21,7 @@ class EmailMessenger: Messenger{
//sender of the message's email and optionally their name. Can be a non-existent email as long as it is formatted correctly.
//for example “Bob <[email protected]>” or "[email protected]" or "[email protected]".
fromEmailAddress = env_vars["MAILGUN_FROM_EMAIL_ADDRESS"] ?? "[email protected]"
httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
self.httpClient = httpClient
}

public func sendMessage(messageRequest: Message) async -> Error? {
Expand Down
13 changes: 8 additions & 5 deletions swift/send-message/Sources/Messenger.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import AsyncHTTPClient
//an enum of the implementations we provide, anything else is rejected
enum MessageType: String {
case sms = "sms"
Expand Down Expand Up @@ -41,18 +42,19 @@ func main(req: RequestValue, res: RequestResponse) async throws -> RequestRespon

let type:MessageType = MessageType(rawValue: typeString) ?? .none
let messenger: Messenger
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)

//initialize messenger with environment variables
//initialize messenger with environment variables and httpClient
do{
switch type{
case .sms:
messenger = try SMSMessenger(req.variables)
messenger = try SMSMessenger(req.variables, httpClient: httpClient)
case .email:
messenger = try EmailMessenger(req.variables)
messenger = try EmailMessenger(req.variables, httpClient: httpClient)
case .twitter:
messenger = try TwitterMessenger(req.variables)
messenger = try TwitterMessenger(req.variables, httpClient: httpClient)
case .discord:
messenger = try DiscordMessenger(req.variables)
messenger = try DiscordMessenger(req.variables, httpClient: httpClient)
default:
return res.json(data: ["success": false, "message" :"Misconfigurtion Error: Invalid Type"])
}
Expand All @@ -64,6 +66,7 @@ func main(req: RequestValue, res: RequestResponse) async throws -> RequestRespon
let messageRequest = Message(type: type, recipient: recipient, content: content, subject: subject)

let result = await messenger.sendMessage(messageRequest: messageRequest)
try await httpClient.shutdown()

if result == nil{
return res.json(data: ["success": true])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class SMSMessenger: Messenger{
private let twilioNumber: String
private let httpClient: HTTPClient

init(_ env_vars: [String: String]) throws{
init(_ env_vars: [String: String], httpClient: HTTPClient) throws{
guard let accountSid = env_vars["TWILIO_ACCOUNT_SID"],
let authToken = env_vars["TWILIO_AUTH_TOKEN"],
let twilioNumber = env_vars["TWILIO_SENDER"] else {
Expand All @@ -18,7 +18,7 @@ class SMSMessenger: Messenger{
self.authToken = authToken
self.accountSid = accountSid
self.twilioNumber = twilioNumber
self.httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
self.httpClient = httpClient

}
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class TwitterMessenger : Messenger{
private let oauth_token_secret:String
private let httpClient: HTTPClient

init(_ env_vars: [String: String]) throws {
init(_ env_vars: [String: String], httpClient: HTTPClient) throws {
guard let oauth_consumer_key = env_vars["TWITTER_API_KEY"],
let oauth_consumer_secret = env_vars["TWITTER_API_KEY_SECRET"],
let oauth_token = env_vars["TWITTER_ACCESS_TOKEN"],
Expand All @@ -22,7 +22,7 @@ class TwitterMessenger : Messenger{
self.oauth_consumer_secret = oauth_consumer_secret
self.oauth_token = oauth_token
self.oauth_token_secret = oauth_token_secret
httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
self.httpClient = httpClient
}

func sendMessage(messageRequest:Message) async -> Error? {
Expand All @@ -47,7 +47,6 @@ class TwitterMessenger : Messenger{
do {
request.body = .bytes(ByteBuffer(data: (try JSONSerialization.data(withJSONObject: jsonText))))
let response = try await httpClient.execute(request, timeout: .seconds(30))
try await httpClient.shutdown()

if response.status.code != 201 {
var errorMessage:String = ""
Expand Down