Created
November 14, 2022 19:58
-
-
Save harmankang/7f5b2cdf5a9ae0bffcb33853823708a5 to your computer and use it in GitHub Desktop.
Telegram API -sendMessage and -sendDocument using URLSession (Swift)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// URLSession wrapper to send messages and text files to Telegram chat. | |
final class TelegramAPI { | |
/// -sendMessage endpoint | |
private let sendMessageEndpoint: String | |
/// -sendDocument endpoint | |
private let sendDocumentEndpoint: String | |
/// Unique identifier for the target chat or username of the target channel | |
private let chatId: String | |
// MARK: Init | |
init(token: String /* = YOUR_BOT_TOKEN*/, chatId: String /* = YOUR_CHAT_ID*/) { | |
self.sendMessageEndpoint = "https://api.telegram.org/bot\(token)/sendMessage" | |
self.sendDocumentEndpoint = "https://api.telegram.org/bot\(token)/sendDocument" | |
self.chatId = chatId | |
} | |
// MARK: API | |
/// Send a message to a Telegram chat. | |
public func send(message: String) { | |
do { | |
let session = URLSession.shared | |
let request = NSMutableURLRequest(url: URL(string: sendMessageEndpoint)!) | |
request.httpMethod = "POST" | |
let encoder = JSONEncoder() | |
let payload = TelegramParameters(chat_id: chatId, text: message) | |
let encodedPayload = try encoder.encode(payload) | |
guard let parameters = String(bytes: encodedPayload, encoding: .utf8) else { return } | |
request.httpBody = parameters.data(using: .utf8) | |
request.addValue("application/json", forHTTPHeaderField: "Content-Type") | |
let task = session.dataTask(with: request as URLRequest) { (data: Data?, response: URLResponse?, error: Error?) in | |
if let data = data, let responseData = String(data: data, encoding: .utf8) { | |
print("TelegramAPI -send received data contents: ", responseData) | |
} | |
if let error = error { | |
print("TelegramAPI -send failed with error: ", error) | |
} | |
} | |
task.resume() | |
} catch let e { | |
print("TelegramAPI -send failed to make cURL request due to error: ", e) | |
} | |
} | |
/// Send a text file to a Telegram chat. | |
/// - Parameters: | |
/// - contents: Contents for text file. | |
/// - filename: Filename ending in ".txt" | |
public func sendTextFile(contents: String, filename: String) { | |
if let contentsData = contents.data(using: .utf8) { | |
let session = URLSession.shared | |
let parameters = ["chat_id": "\(chatId)"] | |
let request = NSMutableURLRequest(url: URL(string: sendDocumentEndpoint)!) | |
request.httpMethod = "POST" | |
let boundary = "Boundary-\(NSUUID().uuidString)" | |
request.httpBody = makeHTTPBody(withParameters: parameters, fileData: contentsData, boundary: boundary, filename: filename, mimeType: "text/plain") | |
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") | |
let task = session.dataTask(with: request as URLRequest) { (data: Data?, response: URLResponse?, error: Error?) in | |
if let data = data, let responseData = String(data: data, encoding: .utf8) { | |
print("TelegramAPI -sendReport received data contents: ", responseData) | |
} | |
if let error = error { | |
print("TelegramAPI -sendReport failed with error: ", error) | |
} | |
} | |
task.resume() | |
} | |
} | |
/// Create Data representation for message body of HTTP POST request to -sendDocument. | |
/// - Parameters: | |
/// - params: | |
/// - fileData: Document data that is being sent to Telegram. | |
/// - boundary: A short string used to separate key/value parameters in body when using multipart/form-data content type. | |
/// - filename: Filename for the document uploaded to Telegram. | |
/// - mimeType: MIME type for file (e.g. plain/text for text file) | |
/// - Returns: Data for HTTP message body. | |
private func makeHTTPBody(withParameters params: [String: String]?, fileData: Data, boundary: String, filename: String, mimeType: String) -> Data { | |
let lineBreak = "\r\n" | |
var body = Data() | |
if let parameters = params { | |
for (key, value) in parameters { | |
body.append("--\(boundary + lineBreak)") | |
body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak + lineBreak)") | |
body.append("\(value + lineBreak)") | |
} | |
} | |
let fieldName = "document" | |
body.append("--\(boundary + lineBreak)") | |
body.append("Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(filename)\"\(lineBreak)") | |
body.append("Content-Type: \(mimeType + lineBreak + lineBreak)") | |
body.append(fileData) | |
body.append(lineBreak) | |
body.append("--\(boundary)--\(lineBreak)") | |
return body | |
} | |
} | |
fileprivate extension Data { | |
mutating func append(_ string: String) { | |
if let data = string.data(using: .utf8) { | |
append(data) | |
} | |
} | |
} | |
fileprivate struct TelegramParameters: Codable { | |
let chat_id: String | |
let text: String | |
// ... add additional parameters as required | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage