You've already forked OpenIntegrations
mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2025-11-25 22:12:29 +02:00
662 lines
36 KiB
Plaintext
662 lines
36 KiB
Plaintext
|
|
// OneScript: ./OInt/core/Modules/OPI_Twitter.os
|
||
|
|
// Lib: Twitter
|
||
|
|
// CLI: twitter
|
||
|
|
// Keywords: twitter, x
|
||
|
|
|
||
|
|
// MIT License
|
||
|
|
|
||
|
|
// Copyright (c) 2023-2025 Anton Tsitavets
|
||
|
|
|
||
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
|
// of this software and associated documentation files (the "Software"), to deal
|
||
|
|
// in the Software without restriction, including without limitation the rights
|
||
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
|
// copies of the Software, and to permit persons to whom the Software is
|
||
|
|
// furnished to do so, subject to the following conditions:
|
||
|
|
|
||
|
|
// The above copyright notice and this permission notice shall be included in all
|
||
|
|
// copies or substantial portions of the Software.
|
||
|
|
|
||
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
|
// SOFTWARE.
|
||
|
|
|
||
|
|
// https://github.com/Bayselonarrend/OpenIntegrations
|
||
|
|
// Если в не знаете с чего начать, то стоит найти метод ПолучитьСтандартныеПараметры()
|
||
|
|
// и почитать комментарии
|
||
|
|
|
||
|
|
// BSLLS:Typo-off
|
||
|
|
// BSLLS:LatinAndCyrillicSymbolInWord-off
|
||
|
|
// BSLLS:IncorrectLineBreak-off
|
||
|
|
// BSLLS:NumberOfOptionalParams-off
|
||
|
|
// BSLLS:UsingServiceTag-off
|
||
|
|
// BSLLS:LineLength-off
|
||
|
|
// BSLLS:UsingSynchronousCalls-off
|
||
|
|
|
||
|
|
//@skip-check method-too-many-params
|
||
|
|
//@skip-check module-structure-top-region
|
||
|
|
//@skip-check module-structure-method-in-regions
|
||
|
|
//@skip-check wrong-string-literal-content
|
||
|
|
|
||
|
|
#Область ПрограммныйИнтерфейс
|
||
|
|
|
||
|
|
#Область ДанныеИНастройка
|
||
|
|
|
||
|
|
// Получить ссылку для авторизации
|
||
|
|
// Формирует ссылку для авторизации через браузер
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Строка - URL для перехода в браузере
|
||
|
|
Функция ПолучитьСсылкуАвторизации(Параметры = "") Экспорт
|
||
|
|
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
|
||
|
|
ПараметрыURL = Новый Структура;
|
||
|
|
|
||
|
|
ПараметрыURL.Вставить("response_type" , "code");
|
||
|
|
ПараметрыURL.Вставить("client_id" , Параметры_["client_id"]);
|
||
|
|
ПараметрыURL.Вставить("redirect_uri" , Параметры_["redirect_uri"]);
|
||
|
|
ПараметрыURL.Вставить("scope" , Параметры_["scope"]);
|
||
|
|
ПараметрыURL.Вставить("state" , "state");
|
||
|
|
ПараметрыURL.Вставить("code_challenge" , "challenge");
|
||
|
|
ПараметрыURL.Вставить("code_challenge_method", "plain");
|
||
|
|
|
||
|
|
ПараметрыURL = OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
|
||
|
|
Линк = "https://twitter.com/i/oauth2/authorize" + ПараметрыURL;
|
||
|
|
|
||
|
|
Возврат Линк;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Получить токен
|
||
|
|
// Получает токен по коду, полученному при авторизации по ссылке из ПолучитьСсылкуАвторизации
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Код - Строка - Код, полученный из авторизации См.ПолучитьСсылкуАвторизации - code
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция ПолучитьТокен(Знач Код, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьСтроку(Код);
|
||
|
|
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
|
||
|
|
ПараметрыЗапроса = Новый Структура;
|
||
|
|
ПараметрыЗапроса.Вставить("code" , Код);
|
||
|
|
ПараметрыЗапроса.Вставить("grant_type" , "authorization_code");
|
||
|
|
ПараметрыЗапроса.Вставить("client_id" , Параметры_["client_id"]);
|
||
|
|
ПараметрыЗапроса.Вставить("redirect_uri" , Параметры_["redirect_uri"]);
|
||
|
|
ПараметрыЗапроса.Вставить("code_verifier", "challenge");
|
||
|
|
|
||
|
|
Ответ = OPI_ЗапросыHTTP.PostСТелом("https://api.twitter.com/2/oauth2/token"
|
||
|
|
, ПараметрыЗапроса
|
||
|
|
,
|
||
|
|
, Ложь);
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Обновить токен
|
||
|
|
// Обновляет v2 токен при помощи refresh_token
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция ОбновитьТокен(Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
Refresh = "refresh_token";
|
||
|
|
|
||
|
|
ПараметрыЗапроса = Новый Структура;
|
||
|
|
ПараметрыЗапроса.Вставить(Refresh , Параметры_[Refresh]);
|
||
|
|
ПараметрыЗапроса.Вставить("grant_type" , Refresh);
|
||
|
|
ПараметрыЗапроса.Вставить("client_id" , Параметры_["client_id"]);
|
||
|
|
|
||
|
|
Ответ = OPI_ЗапросыHTTP.PostСТелом("https://api.twitter.com/2/oauth2/token"
|
||
|
|
, ПараметрыЗапроса
|
||
|
|
,
|
||
|
|
, Ложь);
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Обработка входящего запроса после авторизации !NOCLI
|
||
|
|
// Метод для вставки в http-сервис, адрес которого указывается в redirect_uri
|
||
|
|
//
|
||
|
|
// Примечание:
|
||
|
|
// Вызывает метод получения токена, так как для получения токена из кода, приходящего^^
|
||
|
|
// на redirect_uri после авторизации через браузер есть всего 30 секунд
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Запрос - HTTPСервисЗапрос - Запрос, приходящий на http-сервис
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// HTTPОтвет, Произвольный, ДвоичныеДанные - Результат чтения JSON ответа сервера
|
||
|
|
Функция ОбработкаВходящегоЗапросаПослеАвторизации(Запрос) Экспорт
|
||
|
|
|
||
|
|
Код = Запрос.ПараметрыЗапроса["code"];
|
||
|
|
ОтветТокен = ПолучитьТокен(Код);
|
||
|
|
|
||
|
|
// BSLLS:CommentedCode-off
|
||
|
|
// Предпочтительное хранение токенов
|
||
|
|
// Константы.TwitterRefresh.Установить(ОтветТокен["refresh_token"]);
|
||
|
|
// Константы.TwitterToken.Установить(ОтветТокен["access_token"]);
|
||
|
|
// BSLLS:CommentedCode-on
|
||
|
|
|
||
|
|
Возврат ОтветТокен;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
#КонецОбласти
|
||
|
|
|
||
|
|
#Область Твиты
|
||
|
|
|
||
|
|
// Создать произвольный твит
|
||
|
|
// Создает твит с произвольным содержимым
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// МассивМедиа - Массив из Строка,ДвоичныеДанные - Массив двоичных данных или путей к файлам - media
|
||
|
|
// МассивВариантовОпроса - Массив из Строка - Массив вариантов опроса, если необходимо - options
|
||
|
|
// ДлительностьОпроса - Строка,Число - Длительность опроса, если необходимо (опрос без длительности не создается) - dur
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьПроизвольныйТвит(Знач Текст = ""
|
||
|
|
, Знач МассивМедиа = ""
|
||
|
|
, Знач МассивВариантовОпроса = ""
|
||
|
|
, Знач ДлительностьОпроса = ""
|
||
|
|
, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьСтроку(Текст);
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьСтроку(ДлительностьОпроса);
|
||
|
|
|
||
|
|
Если ЗначениеЗаполнено(МассивМедиа) Тогда
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(МассивМедиа);
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Если ЗначениеЗаполнено(МассивВариантовОпроса) Тогда
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(МассивВариантовОпроса);
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
URL = "https://api.twitter.com/2/tweets";
|
||
|
|
Массив = "Массив";
|
||
|
|
Поля = Новый Соответствие;
|
||
|
|
|
||
|
|
Если ЗначениеЗаполнено(Текст) Тогда
|
||
|
|
Поля.Вставить("text", Текст);
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Если ТипЗнч(МассивВариантовОпроса) = Тип(Массив) И ЗначениеЗаполнено(ДлительностьОпроса) Тогда
|
||
|
|
|
||
|
|
ДлительностьОпроса = Число(ДлительностьОпроса);
|
||
|
|
|
||
|
|
Если МассивВариантовОпроса.Количество() > 0 Тогда
|
||
|
|
|
||
|
|
СтруктураВарианта = Новый Структура("options,duration_minutes", МассивВариантовОпроса, ДлительностьОпроса);
|
||
|
|
Поля.Вставить("poll", СтруктураВарианта);
|
||
|
|
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Если ТипЗнч(МассивМедиа) = Тип(Массив) Тогда
|
||
|
|
Если МассивМедиа.Количество() > 0 Тогда
|
||
|
|
Поля.Вставить("media", Новый Структура("media_ids", МассивМедиа));
|
||
|
|
КонецЕсли;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Если ЗначениеЗаполнено(Поля["media"]) Тогда
|
||
|
|
ЭтоV2 = Ложь;
|
||
|
|
Иначе
|
||
|
|
ЭтоV2 = Истина;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Ответ = Post(URL, Поля, Параметры_, Истина, ЭтоV2);
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Создать текстовый твит
|
||
|
|
// Создает твит без вложений
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьТекстовыйТвит(Знач Текст, Знач Параметры = "") Экспорт
|
||
|
|
Возврат СоздатьПроизвольныйТвит(Текст, , , , Параметры);
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Создать твит картинки
|
||
|
|
// Создает твит с картинкой вложением
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// МассивКартинок - Массив из Строка,ДвоичныеДанные - Массив файлов картинок - pictures
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьТвитКартинки(Знач Текст, Знач МассивКартинок, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
МассивМедиа = ЗагрузитьМассивВложений(МассивКартинок, "tweet_image", Параметры);
|
||
|
|
|
||
|
|
Если ТипЗнч(МассивМедиа) = Тип("Массив") Тогда
|
||
|
|
Результат = СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
|
||
|
|
Иначе
|
||
|
|
Результат = МассивМедиа;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат Результат;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Создать твит гифки
|
||
|
|
// Создает твит с вложением-гифкой
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// МассивГифок - Массив из Строка,ДвоичныеДанные - Массив файлов гифок - gifs
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьТвитГифки(Знач Текст, Знач МассивГифок, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
МассивМедиа = ЗагрузитьМассивВложений(МассивГифок, "tweet_gif", Параметры);
|
||
|
|
|
||
|
|
Если ТипЗнч(МассивМедиа) = Тип("Массив") Тогда
|
||
|
|
Результат = СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
|
||
|
|
Иначе
|
||
|
|
Результат = МассивМедиа;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат Результат;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Создать твит видео
|
||
|
|
// Создает твит с видеовложением
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// МассивВидео - Массив из Строка,ДвоичныеДанные - Массив файлов видео - videos
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьТвитВидео(Знач Текст, Знач МассивВидео, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
МассивМедиа = ЗагрузитьМассивВложений(МассивВидео, "tweet_video", Параметры);
|
||
|
|
|
||
|
|
Если ТипЗнч(МассивМедиа) = Тип("Массив") Тогда
|
||
|
|
Результат = СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
|
||
|
|
Иначе
|
||
|
|
Результат = МассивМедиа;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат Результат;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Создать твит опрос
|
||
|
|
// Создает твит с опросом
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// Текст - Строка - Текст твита - text
|
||
|
|
// МассивВариантов - Массив из Строка - Массив вариантов опроса - options
|
||
|
|
// Длительность - Строка,Число - Длительность опроса - duration
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Twitter
|
||
|
|
Функция СоздатьТвитОпрос(Знач Текст, Знач МассивВариантов, Знач Длительность, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
Возврат СоздатьПроизвольныйТвит(Текст, , МассивВариантов, Длительность, Параметры);
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
// Загрузить массив вложений
|
||
|
|
// Загружает файлы на сервер и возвращает их ID
|
||
|
|
//
|
||
|
|
// Параметры:
|
||
|
|
// МассивФайлов - Массив из Строка, ДвоичныеДанные - Массив файлов для загрузки - files
|
||
|
|
// ТипВложений - Строка - Тип вложений: tweet_video, tweet_image, tweet_gif - type
|
||
|
|
// Параметры - Структура из Строка - Данные авторизации. См.ПолучитьСтандартныеПараметры - auth
|
||
|
|
//
|
||
|
|
// Возвращаемое значение:
|
||
|
|
// Массив Из Строка - Массив ID медиа
|
||
|
|
Функция ЗагрузитьМассивВложений(Знач МассивФайлов, Знач ТипВложений, Знач Параметры = "") Экспорт
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьСтроку(ТипВложений);
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(МассивФайлов);
|
||
|
|
|
||
|
|
МассивМедиа = Новый Массив;
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
MIS = "media_id_string";
|
||
|
|
|
||
|
|
Если ЗначениеЗаполнено(МассивФайлов) Тогда
|
||
|
|
|
||
|
|
Для Каждого ФайлОтправки Из МассивФайлов Цикл
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(ФайлОтправки);
|
||
|
|
|
||
|
|
Ответ = ЗагрузитьМедиафайл(ФайлОтправки, ТипВложений, Параметры_);
|
||
|
|
IDМедиа = Ответ[MIS];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(IDМедиа) Тогда
|
||
|
|
Возврат Ответ;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
МассивМедиа.Добавить(IDМедиа);
|
||
|
|
|
||
|
|
КонецЦикла;
|
||
|
|
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат МассивМедиа;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
#КонецОбласти
|
||
|
|
|
||
|
|
#КонецОбласти
|
||
|
|
|
||
|
|
#Область СлужебныеПроцедурыИФункции
|
||
|
|
|
||
|
|
Функция ЗагрузитьМедиафайл(Знач Файл, Знач Тип, Знач Параметры)
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Файл);
|
||
|
|
|
||
|
|
ВидЗапроса = "POST";
|
||
|
|
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
|
||
|
|
URL = "https://upload.twitter.com/1.1/media/upload.json";
|
||
|
|
|
||
|
|
Ответ = ЗагрузитьМедиаЧастями(Файл, Тип, ВидЗапроса, URL, Параметры_);
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция ЗагрузитьМедиаЧастями(Знач Файл, Знач Тип, Знач ВидЗапроса, Знач URL, Параметры)
|
||
|
|
|
||
|
|
Единица = 1024;
|
||
|
|
Количество = 4;
|
||
|
|
MID = "media_id";
|
||
|
|
MIS = "media_id_string";
|
||
|
|
Command = "command";
|
||
|
|
Размер = Файл.Размер();
|
||
|
|
|
||
|
|
РазмерЧасти = Количество * Единица * Единица;
|
||
|
|
МассивЧтения = РазделитьДвоичныеДанные(Файл, РазмерЧасти);
|
||
|
|
|
||
|
|
Поля = Новый Структура;
|
||
|
|
Поля.Вставить(Command , "INIT");
|
||
|
|
Поля.Вставить("total_bytes" , OPI_Инструменты.ЧислоВСтроку(Размер));
|
||
|
|
Поля.Вставить("media_category", Тип);
|
||
|
|
|
||
|
|
ОтветИнициализации = Post(URL, Поля, Параметры);
|
||
|
|
IDИнициализации = ОтветИнициализации[MID];
|
||
|
|
IDSИнициализации = ОтветИнициализации[MIS];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(IDSИнициализации) Или Не ЗначениеЗаполнено(IDИнициализации) Тогда
|
||
|
|
Возврат ОтветИнициализации;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Счетчик = 0;
|
||
|
|
|
||
|
|
Для Каждого Часть Из МассивЧтения Цикл
|
||
|
|
|
||
|
|
Поля = Новый Структура;
|
||
|
|
Поля.Вставить(Command , "APPEND");
|
||
|
|
Поля.Вставить(MID , IDSИнициализации);
|
||
|
|
Поля.Вставить("segment_index", OPI_Инструменты.ЧислоВСтроку(Счетчик));
|
||
|
|
Поля.Вставить("media" , Часть);
|
||
|
|
|
||
|
|
Ответ = PostMultipart(URL, Поля, Параметры);
|
||
|
|
|
||
|
|
Счетчик = Счетчик + 1;
|
||
|
|
|
||
|
|
КонецЦикла;
|
||
|
|
|
||
|
|
Поля = Новый Структура;
|
||
|
|
Поля.Вставить(Command, "FINALIZE");
|
||
|
|
Поля.Вставить(MID , IDSИнициализации);
|
||
|
|
|
||
|
|
СтатусОбработки = ПолучитьСтатусОбработки(Параметры, Поля, URL);
|
||
|
|
|
||
|
|
Если Не ТипЗнч(СтатусОбработки) = Тип("Строка") Тогда
|
||
|
|
Возврат СтатусОбработки;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Ответ = ОжидатьЗавершенияОбработки(СтатусОбработки, IDSИнициализации, URL, Параметры);
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция ОжидатьЗавершенияОбработки(Знач СтатусОбработки, Знач IDИнициализации, Знач URL, Знач Параметры)
|
||
|
|
|
||
|
|
ProcessingInfo = "processing_info";
|
||
|
|
Command = "command";
|
||
|
|
Поля = Новый Структура;
|
||
|
|
|
||
|
|
Поля.Вставить(Command , "STATUS");
|
||
|
|
Поля.Вставить("media_id", IDИнициализации);
|
||
|
|
|
||
|
|
Пока Строка(СтатусОбработки) = "pending" Или Строка(СтатусОбработки) = "in_progress" Цикл
|
||
|
|
|
||
|
|
Ответ = Get(URL, Поля, Параметры);
|
||
|
|
Информация = Ответ[ProcessingInfo];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(Информация) Тогда
|
||
|
|
Возврат Ответ;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
СтатусОбработки = Информация["state"];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(СтатусОбработки) Тогда
|
||
|
|
Возврат Ответ;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
КонецЦикла;
|
||
|
|
|
||
|
|
Если СтатусОбработки = "failed" Тогда
|
||
|
|
ВызватьИсключение "Твиттер не смог обработать загруженное вами видео";
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат Ответ;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция ПолучитьСтандартныеПараметры(Знач Параметры = "")
|
||
|
|
|
||
|
|
// Здесь собрано определение данных, необходимых для работы.
|
||
|
|
// Для Twitter это довольно значительный набор, что обсуловлено наличием сразу 2-х API,
|
||
|
|
// которые, при этом, созданы не для разныз задач, но просто являются версиями друг друга.
|
||
|
|
// Актуальной версией API является v2 и она требует получения временных токенов. Несмотря на то,
|
||
|
|
// что Twitter настаивает на использовании этой актуальной версии, они как-то умудрились не перенести
|
||
|
|
// механизм загрузки файлов и некоторые другие из старой версии - v1.1. Поэтому что-то нужно делать
|
||
|
|
// на версии 1.1, а что-то на 2: вплоть до того что они убрали возможность постить твиты из v1.1,
|
||
|
|
// но только через нее в твит можно добавить картинку. При этом способы авторизации и токены у них разные
|
||
|
|
|
||
|
|
// Мировая гигокорпорация Илона Маска, кстати, напоминаю ;)
|
||
|
|
|
||
|
|
// P.S Далее часто упоминается "страница настроек Twitter Developer" - это
|
||
|
|
// https://developer.twitter.com/en/portal/dashboard и выбор конкретного проекта из списка (значек c ключем)
|
||
|
|
|
||
|
|
Параметры_ = Новый Соответствие;
|
||
|
|
Разрешения = "tweet.read tweet.write tweet.moderate.write users.read "
|
||
|
|
+ "follows.read follows.write offline.access space.read mute.read "
|
||
|
|
+ "mute.write like.read like.write list.read list.write block.read "
|
||
|
|
+ "block.write bookmark.read bookmark.write";
|
||
|
|
|
||
|
|
// Данные для API v2
|
||
|
|
|
||
|
|
// redirect_uri - URL вашего http-сервиса (или другого обработчика запросов) для авторизации
|
||
|
|
// scope - набор разрешений для получаемого ключа. Может быть любой, но offline.access обязателен
|
||
|
|
// client_id - Из OAuth 2.0 Client ID and Client Secret страницы настроек Twitter Developer
|
||
|
|
// client_secret - Из OAuth 2.0 Client ID and Client Secret страницы настроек Twitter Developer
|
||
|
|
// access_token - ПолучитьСсылкуАвторизации() -> Браузер -> code придет на redirect_uri -> ПолучитьТокен(code)
|
||
|
|
// refresh_token - Приходит вместе с access_token и используется для его обновления (время жизни access_token - 2 ч)
|
||
|
|
// Обновление происходит методом ОбновитьТокен с новыми access_token и refresh_token.
|
||
|
|
// При следующем обновлении нужно использовать уже новый refresh_token, так что захардкодить
|
||
|
|
// не получится (access_token тоже не получится)
|
||
|
|
|
||
|
|
// |--> ОбновитьТокен() ->|access_token --> Используется в т-нии 2-х часов для запросов
|
||
|
|
// | |refresh_token --|
|
||
|
|
// |--------[через 2 ч.]-------------------|
|
||
|
|
|
||
|
|
// Данные для API v1.1
|
||
|
|
|
||
|
|
// oauth_token - Из Authentication Tokens -> Access Token and Secret страницы настроек Twitter Developer
|
||
|
|
// oauth_token_secret - Из Authentication Tokens -> Access Token and Secret страницы настроек Twitter Developer
|
||
|
|
// oauth_consumer_key - Из Consumer Keys -> Access Token and Secret страницы настроек Twitter Developer
|
||
|
|
// oauth_consumer_secret - Из Consumer Keys -> Access Token and Secret страницы настроек Twitter Developer
|
||
|
|
|
||
|
|
// Эти токены обновлять не надо
|
||
|
|
|
||
|
|
Параметры_.Вставить("redirect_uri" , "");
|
||
|
|
Параметры_.Вставить("scope" , Разрешения);
|
||
|
|
Параметры_.Вставить("client_id" , "");
|
||
|
|
Параметры_.Вставить("client_secret" , "");
|
||
|
|
Параметры_.Вставить("access_token" , ""); // Должно быть нечто вроде Константы.TwitterToken.Получить()
|
||
|
|
Параметры_.Вставить("refresh_token" , ""); // Должно быть нечто вроде Константы.TwitterRefresh.Получить()
|
||
|
|
Параметры_.Вставить("oauth_token" , "");
|
||
|
|
Параметры_.Вставить("oauth_token_secret" , "");
|
||
|
|
Параметры_.Вставить("oauth_consumer_key" , "");
|
||
|
|
Параметры_.Вставить("oauth_consumer_secret", "");
|
||
|
|
|
||
|
|
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(Параметры);
|
||
|
|
|
||
|
|
Если ТипЗнч(Параметры) = Тип("Структура") Или ТипЗнч(Параметры) = Тип("Соответствие") Тогда
|
||
|
|
Для Каждого ПереданныйПараметр Из Параметры Цикл
|
||
|
|
Параметры_.Вставить(ПереданныйПараметр.Ключ, OPI_Инструменты.ЧислоВСтроку(ПереданныйПараметр.Значение));
|
||
|
|
КонецЦикла;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат Параметры_;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция ПолучитьСтатусОбработки(Знач Параметры, Знач Поля, Знач URL)
|
||
|
|
|
||
|
|
ProcessingInfo = "processing_info";
|
||
|
|
|
||
|
|
Ответ = Post(URL, Поля, Параметры);
|
||
|
|
Информация = Ответ[ProcessingInfo];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(Информация) Тогда
|
||
|
|
Возврат Ответ;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
СтатусОбработки = Информация["state"];
|
||
|
|
|
||
|
|
Если Не ЗначениеЗаполнено(СтатусОбработки) Тогда
|
||
|
|
Возврат Ответ;
|
||
|
|
Иначе
|
||
|
|
Возврат СтатусОбработки;
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция Get(Знач URL, Знач Поля, Знач УчетныеДанные)
|
||
|
|
|
||
|
|
Токен = УчетныеДанные["oauth_token"];
|
||
|
|
Секрет = УчетныеДанные["oauth_token_secret"];
|
||
|
|
КлючПользователя = УчетныеДанные["oauth_consumer_key"];
|
||
|
|
СекретПользователя = УчетныеДанные["oauth_consumer_secret"];
|
||
|
|
Версия = "1.0";
|
||
|
|
|
||
|
|
Результат = OPI_ЗапросыHTTP.НовыйЗапрос()
|
||
|
|
.Инициализировать(URL)
|
||
|
|
.УстановитьПараметрыURL(Поля)
|
||
|
|
.ДобавитьOauthV1Авторизацию(Токен, Секрет, КлючПользователя, СекретПользователя, Версия)
|
||
|
|
.УстановитьАлгоритмOAuthV1("HMAC", "SHA1")
|
||
|
|
.ОбработатьЗапрос("GET")
|
||
|
|
.ВернутьОтветКакJSONКоллекцию(Истина, Истина);
|
||
|
|
|
||
|
|
Возврат Результат;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция Post(Знач URL, Знач Поля, Знач УчетныеДанные, Знач JSON = Ложь, Знач ЭтоV2 = Ложь)
|
||
|
|
|
||
|
|
Токен = УчетныеДанные["oauth_token"];
|
||
|
|
Секрет = УчетныеДанные["oauth_token_secret"];
|
||
|
|
КлючПользователя = УчетныеДанные["oauth_consumer_key"];
|
||
|
|
СекретПользователя = УчетныеДанные["oauth_consumer_secret"];
|
||
|
|
Версия = "1.0";
|
||
|
|
|
||
|
|
HttpКлиент = OPI_ЗапросыHTTP.НовыйЗапрос().Инициализировать(URL);
|
||
|
|
|
||
|
|
Если ЭтоV2 Тогда
|
||
|
|
|
||
|
|
HttpКлиент.ДобавитьЗаголовок("Authorization", "Bearer " + УчетныеДанные["access_token"]);
|
||
|
|
|
||
|
|
Иначе
|
||
|
|
|
||
|
|
ДействиеСВложениями = OPI_Инструменты.ПолеКоллекцииСуществует(Поля, "media");
|
||
|
|
|
||
|
|
HttpКлиент.ДобавитьOauthV1Авторизацию(Токен, Секрет, КлючПользователя, СекретПользователя, Версия)
|
||
|
|
.УстановитьАлгоритмOAuthV1("HMAC", "SHA1")
|
||
|
|
.ИспользоватьПоляТелаВOAuth(Не ДействиеСВложениями);
|
||
|
|
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Если JSON Тогда
|
||
|
|
HttpКлиент.УстановитьJsonТело(Поля);
|
||
|
|
Иначе
|
||
|
|
HttpКлиент.УстановитьFormТело(Поля);
|
||
|
|
КонецЕсли;
|
||
|
|
|
||
|
|
Возврат HttpКлиент.ОбработатьЗапрос("POST").ВернутьОтветКакJSONКоллекцию(Истина, Истина);
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
Функция PostMultipart(Знач URL, Знач Поля, Знач УчетныеДанные)
|
||
|
|
|
||
|
|
Токен = УчетныеДанные["oauth_token"];
|
||
|
|
Секрет = УчетныеДанные["oauth_token_secret"];
|
||
|
|
КлючПользователя = УчетныеДанные["oauth_consumer_key"];
|
||
|
|
СекретПользователя = УчетныеДанные["oauth_consumer_secret"];
|
||
|
|
Версия = "1.0";
|
||
|
|
|
||
|
|
HttpКлиент = OPI_ЗапросыHTTP.НовыйЗапрос()
|
||
|
|
.Инициализировать(URL)
|
||
|
|
.НачатьЗаписьТелаMultipart()
|
||
|
|
.ДобавитьOauthV1Авторизацию(Токен, Секрет, КлючПользователя, СекретПользователя, Версия)
|
||
|
|
.УстановитьАлгоритмOAuthV1("HMAC", "SHA1")
|
||
|
|
.ИспользоватьПоляТелаВOAuth(Ложь);
|
||
|
|
|
||
|
|
Для Каждого Параметр Из Поля Цикл
|
||
|
|
HttpКлиент.ДобавитьПолеMultipartFormData(Параметр.Ключ, Параметр.Значение);
|
||
|
|
КонецЦикла;
|
||
|
|
|
||
|
|
Результат = HttpКлиент.ОбработатьЗапрос("POST").ВернутьОтветКакJSONКоллекцию(Истина, Истина);
|
||
|
|
|
||
|
|
Возврат Результат;
|
||
|
|
|
||
|
|
КонецФункции
|
||
|
|
|
||
|
|
#КонецОбласти
|