rapierorg / telegram-bot-swift

Telegram Bot SDK for Swift (unofficial)
https://github.com/rapierorg/telegram-bot-swift/wiki
Apache License 2.0
375 stars 63 forks source link

error: use of unresolved identifier 'CURLOPT_WRITEDATA' #32

Closed savelii closed 6 years ago

savelii commented 7 years ago

Hello, I try to run example on ubuntu 14.04 on IBM bluemix cloud foundry. Following error appears there and on my local ubuntu server 14.04. Maybe you can give some advice what it can be? On what environment do you test Linux build? maybe you have some ready docker container you use?

saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ swift build
warning: minimum recommended clang is version 3.6, otherwise you may encounter linker errors.
Cloning /home/saveliy/terst/telegram-bot-swift
HEAD is now at 5f2730a Update changelog
Resolved version: 0.14.0
Cloning https://github.com/zmeyc/CCurl.git
HEAD is now at 7ef2701 Include stdint.h
Resolved version: 0.0.2
Cloning https://github.com/zmeyc/SwiftyJSON.git
HEAD is now at 54c7a31 Fix warning on Linux
Resolved version: 12.1.4
Cloning https://github.com/smud/ScannerUtils.git
HEAD is now at 26015cb Comment out failing "Hello World" test function
Resolved version: 1.0.6
Compile Swift Module 'ScannerUtils' (2 sources)
Compile Swift Module 'SwiftyJSON' (2 sources)
Compile Swift Module 'TelegramBot' (134 sources)
/home/saveliy/terst/telegram-bot-swift/Examples/hello-bot/Packages/telegram-bot-swift-0.14.0/Sources/TelegramBot/TelegramBot.swift:228:40: error: use of unresolved identifier 'CURLOPT_WRITEDATA'
        curl_easy_setopt_pointer(curl, CURLOPT_WRITEDATA, &callbackData)
                                       ^~~~~~~~~~~~~~~~~
CCurl.CURLOPT_IOCTLDATA:1:12: note: did you mean 'CURLOPT_IOCTLDATA'?
public var CURLOPT_IOCTLDATA: CURLoption { get }
           ^
CCurl.CURLOPT_WRITEINFO:1:12: note: did you mean 'CURLOPT_WRITEINFO'?
public var CURLOPT_WRITEINFO: CURLoption { get }
           ^
<unknown>:0: error: build had 1 command failures
error: exit(1): /home/saveliy/swift/usr/bin/swift-build-tool -f /home/saveliy/terst/telegram-bot-swift/Examples/hello-bot/.build/debug.yaml
zmeyc commented 7 years ago

Hello! I'm using Ubuntu 16.04 LTS with latest Swift snapshot.

According to CURL docs: _This option was formerly known as CURLOPT_FILE, the name CURLOPTWRITEDATA was introduced in 7.9.7.

Could you try renaming it to CURLOPT_FILE ?

savelii commented 7 years ago

Yes I also find this info. Small investigate problem by myself. Interesting that "curl -V" gives me:

saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ curl -V
curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp 
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP 

So seems like version is fine > 7.9.7. Moreover I search for curl.h file on both system and found them in /usr/include/curl/curl.h thay contain CURLOPT_WRITEDATA.

Anyway I tried renaming it to CURLOPT_FILE for check, heres the result:

saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ swift build
warning: minimum recommended clang is version 3.6, otherwise you may encounter linker errors.
Cloning /home/saveliy/terst/telegram-bot-swift
HEAD is now at 3241e49 Your Message
Resolved version: 0.15.0
Cloning https://github.com/zmeyc/CCurl.git
HEAD is now at 7ef2701 Include stdint.h
Resolved version: 0.0.2
Cloning https://github.com/zmeyc/SwiftyJSON.git
HEAD is now at 54c7a31 Fix warning on Linux
Resolved version: 12.1.4
Cloning https://github.com/smud/ScannerUtils.git
HEAD is now at 26015cb Comment out failing "Hello World" test function
Resolved version: 1.0.6
Compile Swift Module 'SwiftyJSON' (2 sources)
Compile Swift Module 'ScannerUtils' (2 sources)
Compile Swift Module 'TelegramBot' (134 sources)
Compile Swift Module 'hello_bot' (1 sources)
Linking ./.build/debug/hello-bot
saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ ./.build/debug/hello-bot
endpoint: getMe, data: 
Unable to fetch bot information: Invalid HTTP request
saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ 

As you see then build is passing fine, but when try to run bot there is error " Invalid HTTP request"

zmeyc commented 7 years ago

Is HELLO_BOT_TOKEN environment variable set correctly? It should contain bot's token.

You can also try uncommenting CURLOPT_VERBOSE option in TelegramBot.swift: //curl_easy_setopt_int(curl, CURLOPT_VERBOSE, 1)

savelii commented 7 years ago

I change to use token directly and of course provide right token. My main.swift like below, on macOS all works from Xcode as well as from terminal, so token and bot code seems ok.

//
// main.swift
//
// This file containing the example code is in public domain.
// Feel free to copy-paste it and edit it in any way you like.
//

import Foundation
import TelegramBot

let bot = TelegramBot(token: "...")

let router = Router(bot: bot)

router["help"] = { context in
        guard let from = context.message?.from else { return false }

        let helpText = "Usage: /greet"
    context.respondPrivatelyAsync(helpText,
        groupText: "\(from.first_name), please find usage instructions in a personal message.")
        return true
}

router["greet"] = { context in
        guard let from = context.message?.from else { return false }
    context.respondAsync("Hello, \(from.first_name)!")
        return true
}

router[.new_chat_member] = { context in
        guard let user = context.message?.new_chat_member else { return false }
        guard user.id != bot.user.id else { return false }
        context.respondAsync("Welcome, \(user.first_name)!")
        return true
}

print("Ready to accept commands")
while let update = bot.nextUpdateSync() {
        print("--- update: \(update.debugDescription)")

        try router.process(update: update)
}

fatalError("Server stopped due to error: \(bot.lastError)")

You can also try uncommenting CURLOPT_VERBOSE option in TelegramBot.swift: //curl_easy_setopt_int(curl, CURLOPT_VERBOSE, 1)

Nothing change and no additional info

saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ ./.build/debug/hello-bot
endpoint: getMe, data: 
Unable to fetch bot information: Invalid HTTP request

I also tried with this code

import Foundation
import TelegramBot

let bot = TelegramBot(token: "...token...")

while true {
}

Same result, so falling for sure on the first request, no even on "bot.nextUpdateSync()"

zmeyc commented 7 years ago

Which Swift snapshot version do you use? Mine is swift-DEVELOPMENT-SNAPSHOT-2017-02-10-a-ubuntu16.04

zmeyc commented 7 years ago

It seems it fails even before calling CURL, on request generation. Could you log the parameters being passed to .formUrlencode() and to .data()? It seems .data() returns nil.

        let contentType: String
        let requestDataOrNil: Data?
        if hasAttachments {
            let boundary = HTTPUtils.generateBoundaryString() 
            contentType = "multipart/form-data; boundary=\(boundary)"
            requestDataOrNil = HTTPUtils.createMultipartFormDataBody(with: parameters, boundary: boundary)
            //try! requestDataOrNil!.write(to: URL(fileURLWithPath: "/tmp/dump.bin"))
            logger("endpoint: \(endpoint), sending parameters as multipart/form-data")
        } else {
            contentType = "application/x-www-form-urlencoded"
            let encoded = HTTPUtils.formUrlencode(parameters) // <----------
            requestDataOrNil = encoded.data(using: .utf8) // <------------
            logger("endpoint: \(endpoint), data: \(encoded)")
        } 
        requestDataOrNil?.append(0)

        guard let requestData = requestDataOrNil else {
            completion(nil, .invalidRequest) // <---------------- It fails here
            return 
        }
savelii commented 7 years ago

swift-3.0.2-RELEASE-ubuntu14.04.tar.gz

savelii commented 7 years ago
            contentType = "application/x-www-form-urlencoded"
            print(parameters)
            let encoded = HTTPUtils.formUrlencode(parameters)
            print(encoded)
            requestDataOrNil = encoded.data(using: .utf8)
            logger("endpoint: \(endpoint), data: \(encoded)")
saveliy@ubuntu:~/terst/telegram-bot-swift/Examples/hello-bot$ ./.build/debug/hello-bot
[:]

endpoint: getMe, data: 
Unable to fetch bot information: Invalid HTTP request
zmeyc commented 7 years ago

It's very old version, please try the latest snapshot (the one I'm using or the most recent one): https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2017-03-15-a/swift-DEVELOPMENT-SNAPSHOT-2017-03-15-a-ubuntu14.04.tar.gz

savelii commented 7 years ago

Hey, sorry for long response. Just tried with this snapshot: https://swift.org/builds/swift-3.1-branch/ubuntu1404/swift-3.1-DEVELOPMENT-SNAPSHOT-2017-03-17-a/swift-3.1-DEVELOPMENT-SNAPSHOT-2017-03-17-a-ubuntu14.04.tar.gz Works fine, but with changing CURLOPT_WRITEDATA to CURLOPT_FILE.

Before close may I ask small question, is there some big reason or problem with IBM-Swift/SwiftyJSON, so you use your own repo? I plan have a try with their package, to integrate Kitura and build callback endpoint for FB msgr and Viber.

zmeyc commented 7 years ago

Thanks for following up!

Regarding SwiftyJson, as I recall it was incompatible with latest Swift snapshot at the time and IBM weren't accepting patches because they planned to update all their packages simultaneously, so I had to fork it.

There are a few more issues which need to be fixed on Linux:

1) There's a memory leak in latest TelegramBot release, curl_easy_cleanup was missing. Please use the latest version from dev branch, it's not tagged yet.

2) It occasionally freezes on Linux. The problem is in libdispatch and I haven't sent the patch to Swift repo yet. To fix it, Swift needs to be rebuilt from source. The steps below are for Ubuntu 16.04:

sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev

mkdir swift-source
cd swift-source
git clone https://github.com/apple/swift.git
cd swift
git checkout swift-DEVELOPMENT-SNAPSHOT-2017-02-15-a
cd ..
./swift/utils/update-checkout --clone

Bugfix: In swift-source/swift-corelibs-foundation/CoreFoundation/RunLoop.subproj/CFRunLoop.c

Replace

        __CFRunLoopServiceFileDescriptors(waitSet, CFPORT_NULL, TIMEOUT_INFINITY, &livePort);

with:

        __CFRunLoopServiceFileDescriptors(waitSet, CFPORT_NULL, poll ? 0 : TIMEOUT_INFINITY, &livePort);

And build Swift:

./swift/utils/build-script --preset=buildbot_linux_1604 install_destdir=/tmp/install 
installable_package=/tmp/swift.tar.gz
gmosx commented 7 years ago

Hi there, I have the same problem trying to run a telegram-bot using the ibmcom/swift-ubuntu:latest docker image.

FROM ibmcom/swift-ubuntu:latest

RUN apt-get update && apt-get install -y libpq-dev curl

WORKDIR $HOME
COPY . $HOME

# Compile the application
RUN swift build --configuration release

If I understand correctly, the verdict it that it's not possible to make this work under this specific image?

Any chance the situation will change with the imminent release of Swift 3.1?

zmeyc commented 7 years ago

@gmosx Yes, a patched version of Swift is needed. Maybe deploying a pre-built binary is easier option.

Any chance the situation will change with the imminent release of Swift 3.1?

I've not sent a patch to official repo. This issue needs to be fixed: https://bugs.swift.org/browse/SR-3300

savelii commented 7 years ago

I successfully migrated to use Kitura package (I use my own fork, just because they make fix for Swift 3.1 but doesn't add release with it yet) instead of zmeyc/CCurl and zmeyc/SwiftyJSON, here is all changes: https://github.com/savelii/telegram-bot-swift/commit/795b8570058eacbd2516edd98975e1b2e9ebabec

As I say hello-bot example works fine on mine machine Ubuntu 14.04 and swift-3.1-DEVELOPMENT-SNAPSHOT-2017-03-17-a even WITHOUT fix for https://bugs.swift.org/browse/SR-3300. I don't see any problem why this shouldn't work with ibmcom/swift-ubuntu:latest docker image, maybe just need to fork and update it to use swift-3.1-DEVELOPMENT-SNAPSHOT-2017-03-17-a.

As for me I use own fork of cloud foundry swift buildpack (https://github.com/savelii/swift-buildpack) with it I can deploy cloud foundry instance to bluemix with needed swift snapshot.

At this moment I stuck with MongoKitten not working with Swift 3.1. So I need both telegram bot and MongoKitten but they need different Swift versions :)

zmeyc commented 7 years ago

Thanks for the update!

Regarding SR-3300: it will run without the bug being fixed, but will freeze in a few hours on first CPU peak. @iyumeg did stability testing.

zmeyc commented 7 years ago

We can avoid the issue altogether by not using any synchronous functions, i.e. fetching and processing the updates asynchronously too, but it's not a trivial change.

savelii commented 7 years ago

If we think about Bluemix there is monitoring service that can be used to restart app if it's freezes, I think this workaround much more easier. Anyway I think it will be fixed soon, and it's not nice idea to rework a lot of code just for workaround, if "not using any synchronous functions" needed as future improvement anyway, then thats make sense.

savelii commented 7 years ago

@gmosx hey, got working with Swift 3.0.2, https://github.com/savelii/telegram-bot-swift tag 0.18.0 I test it with macOS and Ubuntu 14.04, will make pull request later when test with Swift 3.1 as well.

as for stuck of main queue I use this hard workaround at the beginning of main.swift, I don't think it very hard for processor workload

#if os(Linux) || os(Windows)
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
    print("Ping main thread")
}
#endif
zmeyc commented 6 years ago

@savelii new version (still not tagged, in dev branch) should work without workarounds. I'm closing the issue, please reopen if any problem occurs again. Thanks!