Пишем Twitter-клиент для MetaTrader: Часть 2
Введение
Как я и обещал в первой статье "Пишем Twitter-клиент для MetaTrader 4 и MetaTrader 5 без использования DLL", во второй части мы попытаемся изучить возможности Twitter API для отправки твитов с картинками. Чтобы не загружать статью лишними деталями, сосредоточимся только на публикации изображений. К концу этой статьи у нас должен получиться работающий Твиттер-клиент без использования какой-либо внешней библиотеки DLL, который позволит публиковать твиты, содержащие до четырех картинок. Четыре изображения — это максимально разрешенное количество в Twitter API, согласно параметру media_ids.
Загрузка изображений
В API добавили новый метод chunked upload для загрузки мультимедиа, который позволяет более эффективно заливать большие файлы, например видео или анимированные GIF-файлы. Для наших же целей подойдет простой метод, поскольку мы будем загружать только изображения.
Перед началом работы обязательно ознакомьтесь с требованиями и ограничениями по типам и размерам медиафайлов в Twitter.
По факту загрузка фото в Твиттер это простой POST-запрос multipart/form-data с OAuth-авторизацией. Поговорим об этом в следующем параграфе. Для каждого загруженного изображения возвращается идентификатор media_id, который действителен только в течение определенного периода времени — его то и нужно включать в публикуемый твит.
При публикации четырех изображений вы просто прописываете все возвращенные идентификаторы media_id через запятую.
Для публикации сообщения с изображениями нужно выполнить следующие действия:
- Загрузите изображение и заберите возвращенный идентификатор media_id
- Повторите загрузку изображений - до 4 картинок. Всегда забирайте возвращенный media_id
- Подготовьте сообщение
- При отправке сообщения вставки изображений укажите список их идентификаторов media_id через запятую
HTTP multipart/form-data
При публикации твита изображения можно загружать как необработанные бинарные данные или строку в кодировке Base64. Все же рекомендуется использовать формат необработанных бинарных данных, поскольку Base64-строка будет примерно в три раза больше по размеру.
Метод HTTP multipart/form-data определен в RFC-2388, но может быть проще понять этот метод из отличного материала по curl. Согласно этим материалам, это "HTTP POST-запрос, отправляемый вместе с телом запроса в виде отформатированного набора частей с MIME boundaries".
POST /submit.cgi HTTP/1.1 Host: example.com User-Agent: curl/7.46.0 Accept: */* Content-Length: 313 Expect: 100-continue Content-Type: multipart/form-data; boundary=------------------------d74496d66958873e --------------------------d74496d66958873e Content-Disposition: form-data; name="person" anonymous --------------------------d74496d66958873e Content-Disposition: form-data; name="secret"; filename="file.txt" Content-Type: text/plain contents of the file --------------------------d74496d66958873e--
Реализация в классе Twitter:
void appendPhoto(string filename, string hash, uchar &data[], bool common_flag=false) { int flags=FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ; if(common_flag) flags|=FILE_COMMON; //--- int handle=FileOpen(filename,flags); if(handle==INVALID_HANDLE) return; //--- int size=(int)FileSize(handle); uchar img[]; ArrayResize(img,size); FileReadArray(handle,img,0,size); FileClose(handle); int pos = ArraySize(data); int offset = pos + size; int hlen = StringLen(hash)+6; int newlen = offset + hlen; ArrayResize(data, newlen); ArrayCopy(data, img, pos); StringToCharArray("\r\n--"+hash+"\r\n", data, offset, hlen); }
В этом коде сырой бинарный файл изображения добавляется в "части" HTTP-запроса POST multipart/form-data. Далее в коде показан конверт POST-запроса с указанием параметра Twitter Upload-API media.
string uploadPhoto(string filename) { // POST multipart/form-data string url = "https://upload.twitter.com/1.1/media/upload.json"; //string url = "https://httpbin.org/anything"; string params[][2]; string query = oauthRequest(params, url, "POST"); string o = getOauth(params); string custom_headers = "Content-Type: multipart/form-data;" " boundary="; string boundary = getNonce(); StringAdd(custom_headers, boundary); // use nonce as boundary string StringAdd(custom_headers, "\r\n"); string headers = getHeaders(o, custom_headers, "upload.twitter.com"); //string query = getQuery(params, url); //Print(query); uchar data[]; string part = "\r\n--"; StringAdd(part, boundary); StringAdd(part, "\r\nContent-Disposition: form-data;" " name=\"media\"\r\n\r\n"); StringToCharArray(part, data, 0, StringLen(part)); appendPhoto(filename, boundary, data); string resp = SendRequest("POST", url, data, headers);; if(m_verbose) { SaveToFile(filename + "_post.txt", data); Print(resp); } return (getTokenValue(resp, "media_id")); }
Чтобы проверить работу multipart/form-data HTTP, сохраним HTTP-запрос в файл в папке данных терминала MetaTrader.
Твит с картинками
Здесь я использую простейшую функцию getTokenValue() для получения media_id, возвращенного интерфейсом Twitter Upload-API. Вы можете воспользоваться отличной MQL5-библиотекой для работы с JSON-протоколом.
Далее показан простой пример использования класса Twitter. Функция Screenshots() делает скриншоты текущих открытых графиков и составляет простой твит. Выбрать можно до четырех графиков. Каждый скриншот сохраняется в файл, а название файла возвращается в строковом массиве fnames.
Скриншоты загружаются по-одному, возвращенные идентификаторы media_id собираются вместе в виде списка, разделенного запятыми. Благодаря указанию идентификаторов media_id в таком списке мы публикуем сообщение в твиттере с нашими скриншотами.
Все просто.
CTwitter tw(consumer_key, consumer_secret, access_token, access_secret, verbose); // Gather information string fnames[4]; string msg; Screenshots(fnames, msg); // Upload screenshots int n = ArraySize(fnames); int i = n - 1; // create comma separated media_ids string medias = tw.uploadPhoto(fnames[i]); for(i= n - 2; i>=0; i--) { StringAdd(medias, ","); StringAdd(medias, tw.uploadPhoto(fnames[i])); } // Send Tweet with photos' ids string resp = tw.tweet(msg, medias); Print(resp);
Класс Twitter
Класс Twitter в Twitter.mqh — это самостоятельный файл, не зависимый от других include-файлов. То есть для публикации графиков в твиттере вам нужен только один файл.
Сначала нужно инстанциировать объект Twitter, указав токен клиента и доступа, также можно указать флаг "verbose", который поможет провести отладку.
CTwitter tw(consumer_key, consumer_secret, access_token, access_secret, verbose);
Затем можете попробовать вызвать доступные public-функции:
- verifyCredentials()
Возвращает Twitter ID для вашего токена доступа.
- uploadPhoto()
Загружает картинку и возвращает ее идентификатор media_id.
- tweet()
Отправляет твит с идентификаторами media_id.
Есть несколько вспомогательных функций:
- getTokenValue()
Возвращает значение токена/параметра из строки json.Примечание: это очень простой пример, не стоит ожидать полной совместимости с json.
- unquote()
Удаляет кавычки из строки.
Публикация графиков в Твиттере
К статье прикреплен рабочий MT5-скрипт, который делает до четырех скриншотов графиков и составляет простое сообщение с названием символа и значением OHLCV.
На основе этого простого примера вы можете начать разрабатывать свои собственные скрипты и эксперты.
Примечание: в своем коде указывайте свои токены и секретные ключи.
Далее показаны примеры твитов, опубликованных скриптом.
Рис 1. Твит с картинками, отправленный из МТ5
Рис. 2. Твит с графиком из MetaTrader 5 в полном размере
Ну и конечно, можно публиковать любые картинки.
Рис. 3. Твит с кошками Далай-Ламы
Заключение
Итак, мы создали простой класс Twitter в виде отдельного подключаемого файла. Он позволяет публиковать твиты с графиками и сигналами. Надеюсь, представленные технические детали будет несложно понять.
Это далеко не полный класс, можно еще много чего добавить из других интерфейсов Twitter API. Делитесь своими идеями в комментариях.
Надеюсь, вам понравилось читать эту статью так же, как мне понравилось ее писать. Пусть твиты приносят удовольствие и прибыль.
Приятного использования!
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/8318
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования