Позднее Ctrl + ↑

Отправляем поток из РСС в телеграм через Google Apps Script

Обновляем канал «Почитаем…»
Теперь новые статьи будут приходить в канал автономно, через гугл таблицы и без участия локального сервера с питоном.
Раньше работало через питон и базу данных на sqlite3

В гугл таблице нам нужны три листа: rss, rss_data, error

  • rss — будем хранить рсс потоки сайтов,
  • rss_data — будем хранить базу данных что отпарсилось и что отправлено,
  • error — будем хранить ошибки при отладке, если это потребуется
На листе rss, в первой колонке перечислены все рсс-потоки, при необходимости добавить или удалить, делаем это здесь.
На листе rss_data, первая строчка с наименованием колонок

У меня сейчас 110 источников, когда идет запись в таблицу, скрипт не успевает обработать все данные, и отваливается по тайм-ауту гугла. После нескольких запусков он все ссылки обработает и начинает укладываться в тайминг.
Возможно, в будущем, нужно скрипт делить на несколько

сообщения приходят в том же виде, что и раньше.

Парсинг потоков рсс через гугл таблицы

// Считываем базу данных РСС
function data_base_rss() {
  var app = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("rss_data")
  data_base= app.getRange(1,1, app.getLastRow(), app.getLastColumn()).getValues(); //только заполненный диапазон
  return(data_base)
}

// поиск по базе данных
function find_rss(url) {
  rezult = rss_data.findIndex(item => item[3] === url) //ищем в 4 столбце
  //console.log(rezult) //-1 если не найдено, и индекс положительный если нашлось это что нашлось лог
  return(rezult)
}


// Запись нового поста в таблицу
function data_write_rss(data) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("rss_data");
  var value = data
  sheet.getRange(sheet.getLastRow() + 1,1,1,4).setValues([value]);
  console.log(data)
}

// Запись error в таблицу
function error_log(data) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("error");
  //var sheet = spreadsheet.getActiveSheet();
  //var value = new Date(); // value you want to insert
  //var value = data
  sheet.getRange(sheet.getLastRow() + 1,1,1,3).setValues([data]);
  console.log(data)
}


//функция проверки новых постов текущего потока
function get_rss(rss_url) {
  var url =rss_url
  var date_rss =[]
  var xml = UrlFetchApp.fetch(url).getContentText()
  document = XmlService.parse(xml);
  root = document.getRootElement();
  channel = root.getChild('channel');
  items = channel.getChildren('item');
  items.forEach(item => {
    parsing_date=new Date(); // дата текущая
    title = item.getChild('title').getText();
    link = item.getChild('link').getText()
    try{
    author = item.getChild('author').getText();} //автор не у всех бывает
    catch(e){author =""}
    if (find_rss(link) == -1) {
      data_write_rss([parsing_date,title,author,link])  
    }
   });
  console.log(date_rss)
}

// Основная функция парсинга всех РСС потоков, ее нужно установить в запуск раз в 15 минут
function parse_rss() {
  var rss_data=data_base_rss()
  var app = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("rss")
  url_array = app.getRange(1,1, app.getLastRow(), 1).getValues(); //только заполненный первый столбец
  console.log(url_array);
  url_array.forEach(url => {
    console.log(url)
    try{ 
      get_rss(url)}
    catch(e){console.log("! недействительный URL", console.log(url),'Ошибка ' + e.name + ":" + e.message + "\n" + e.stack)
    //error_log([new Date(),url,'Ошибка ' + e.name + ":" + e.message + "\n" + e.stack]) //При необходимости записи ошибок снять комментарий     
    } //Обработка ошибки 
  })
}

Код отправки сообщений в телеграм:

const tokendr = "BOT_token"; 
const IDChattelegramdr = "ID_CHAT" 

function timerSENDtgDR() {
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let ws = ss.getSheetByName("rss_data"); //таблица с которой берем данные
  let data = ws.getRange(2, 1, ws.getLastRow()-1, 5).getValues(); //диапазон с которого берем данные
  Logger.log ( data ); 
  for (i = 0; i < data.length; i++) {
    let dataInfo = data[i]; //строчка таблицы
    //Logger.log ( dataInfo );
    let telegram_send = dataInfo[4]; //пятая ячейка telegram_send
    Logger.log(telegram_send)
    if (telegram_send ===""){
      title = dataInfo[1];
      author = dataInfo[2];
      if (author !=''){
      author=author+"\n\n"    //если имя автора есть, добавить переносы строк
      }
      link = dataInfo[3];
      sendTextDR(IDChattelegramdr, "<b>"+title+"</b>\n\n" + author + link);
      ws.getRange(i+2 , 5, 1, 1).setValues([[new Date()]]);
      Utilities.sleep(500);// pause in the loop for 500 milliseconds
      Logger.log ("сообщение отправлено");
    }
  }
}
 
function sendTextDR(chatId, text, keyBoard) {
  let data = {
    method: 'post',
    payload: {
      method: 'sendMessage',
      chat_id: String(chatId),
      text: text,
      //parse_mode:'Markdown',
      parse_mode: 'html',
      reply_markup: JSON.stringify(keyBoard)
    }
  }
  UrlFetchApp.fetch('https://api.telegram.org/bot' + tokendr + '/', data);
}

Комментарий: Увеличение откликов на рубрику в телеграм сообществе

Николай Товеровский, разобрал решение домашки

Мое решение

Если читать решение Игоря напрямую, то оно выглядит сомнительным:

Гугл-форма кажется сложной, это особенность гугла.
Попробуем сделать форму в другом месте, например, в Яндекс формах.

Сложно поверить, что, вот у Гугля прям такие плохие формы, что если поменять их на Яндекс, то тут же всё станет зашибись. Может как-то конверсия поменяется, да, но качественного изменения не будет.

Однако, если читать не напрямую, ниже можно найти интересную мысль:

Это уже любопытно, тут придуман механизм увеличения мотивации заполнять форму. Возможно, из этого можно дальше что-то придумать.

Интересно, что у Игоря получилась классическая ошибка, когда изобретатель закопался в реализацию, не дожав сначала основные механизмы работоспособности.

Решение от Николая

Давайте теперь попробуем подумать о решение сами. Вообще любое решение начинается с понимания задачи и формулировки полезного действия.

Что мы знаем о задаче? Мы знаем, что ситуации собираются плохо.

Что это значит? Это значит, что люди не проходят по воронке отправки своей ситуации.

Как выглядит эта воронка? Примерно так:
Узнать о возможности отправить свою ситуацию

Захотеть отправить ситуацию, мотивация

Найти способ отправить ситуацию — гугль-форма

Заполнить форму

Отправить форму

Вообще мотивация это часто главный камень преткновения. Человек способен любой интерфейс побороть с достаточной мотивацией.

Победа в домашке достаётся Игорю. Он хоть и не дал готовое решение, но натолкнул на мысль, которую стоит попробовать.

Заходите почитать остальные решения:

Надя предложила закреплять ссылку в канале на форму

Анна предложила проговаривать в ролике, что можно оставить вопрос по ссылке

Роман предложил использовать аудио бота, которому наговаривать сообщения

Увеличение откликов на рубрику в телеграм сообществе

Николай Товеровский опубликовал задание:

У меня в Сообществе руководителей есть рубрика «Ситуация в проекте». Чтобы она выходила, нужен поток ситуаций на вход. Я, конечно, могу сам их вспоминать бесконечно, но так не интересно и пользы больше, когда кто-то получает ответ на свою конкретную ситуацию.

У меня есть форма для отправки новых ситуаций, ссылка на неё стоит в конце каждой Ситуации:
https://docs.google.com/forms/d/e/1FAIpQLSe846X9d5SX0W7P0y_cCdYIoM6ZOcLkr5FfPS7AgGGG5CPNlw/viewform

Пример:
https://t.me/fffworks/667

Форма не очень работает — ситуаций присылают мало.

Задача
Придумать, как наладить поток ситуаций. Интересные и удобно оформленные для меня ситуации (см. поля в форме) должны поступать регулярно и в достаточном количестве.

Условия
Решение должно быть простым. Я должен смочь реализовать его в одиночку за неделю. Исходите из того, что никакими специфическими знаниями я не обладаю. Запилить сайт, собрать бота — нет. Написать текст, собрать что-то в готовом сервисе, тыкая кнопки, — да.

Решение должно быть устойчивым. Если для работы решения надо будет постоянно оплачивать какой-то сервис или работу людей, постоянно что-то поддерживать — это не годится, когда-нибудь я не оплачу или не смогу починить сломавшееся и всё. Но можно воспользоваться чем-то, что у меня уже есть. У меня есть хостинг, телеграм-каналы. Всё что есть собрано тут: http://fff.works

Я не должен платить за ситуации в каком-либо виде. Нельзя обманывать присылающих ситуации, обещать им с три короба чего-то, что потом они не получат.

Решение должно быть технологичным. Если мне придётся тратить сутки на сбор ситуаций, перелопачивать какие-то данные, я забью.

Решение должно приличным. Никаких провокаций, голых тел, мата и т. д.

Идеальное решение — ничего нет, а ситуации поступают. Постарайтесь приблизиться к идеалу.

Формат
Присылайте свои решения в комментарии к этому сообщению в Телеграме. Работы принимаются до 23:59 пятницы 18 ноября. Итоги подведу на выходных 19—20 ноября.

Чтобы я смог найти ваше решение, начните текст с фразы «Решение домашки», пример: «Решение домашки. Ваш вариант...» Присылайте одно решение, в которое больше всего сами верите. До дедлайна решение можно менять, редактируя комментарий.

Приз
Автору лучшего решения, которое я смогу взять и внедрить — год подписка на книгу «Управление проектами, людьми и собой». Если подходящих решений будет несколько — победит первое по времени отправки. Если вы уже подписаны на книгу, сможете продлить подписку на год или подарить другу:
https://bureau.ru/projects/book-fff/

Решение

Гугл-форма кажется сложной, это особенность гугла.
Попробуем сделать форму в другом месте, например, в Яндекс формах.

Создаем простую форму и наполняем содержимым из гугл формы.

Форма есть, теперь нужно получать результаты отправлений формы, как можно скорее.
У гугл-форм есть преимущество, они отправляют сразу в таблицу, то что мы будем делать дальше, можно сделать и с гугл формами.

Результаты будем отправлять в телеграм канал, так мы сразу увидим что пришел запрос.
Как отправить из Яндекс формы в телеграм канал

Создаем канал в телеграме:
Канал — Ситуация в проекте

Добавляем бота в администраторы, и пишем правильный айди канала в отправке сообщений.

Все должно работать

Заполняем форму, данными из примера Николая
Результат в телеграме

Мотивация на заполнение формы

Теперь осталось мотивировать людей заполнять эту форму:
— Если ответ публикуется в телеграме, можно внизу сообщения сделать кнопку задать свой вопрос, ссылка ведет на форму.
— Если ответ публикуется на сайте, можно вставить форму на сайт, как сделано у меня ниже.

Пример кнопки, в телеграме Бюро,

Добавляем кнопку к сообщению

Кнопку может отправить только бот, для этого в строке отправки нужно дописать JSON запрос

&reply_markup={"inline_keyboard": [[ { "text": "test", "url": "ya.ru" } ]]}

Сервис для приведения запроса в url вид, рекомендовали в обсуждении на stackoverflow в теме «Постинг картинок с кнопкой в телеграм канал»

Полный текст для отправки ботом в телеграм тестовой кнопки

https://api.telegram.org/botID:KEY_BOT/sendMessage?chat_id=CHAT_ID&text=
Ответы на все вопросы&reply_markup={"inline_keyboard": [[ { "text": "test", "url": "ya.ru" } ]]}

Ниже можно заполнить форму и увидеть результат в телеграме — Ситуация в проекте

Форма отдельной страницей

https://forms.yandex.ru/u/636f6b272530c22803f20287/

Форма встроена в сайт:

Как узнать пробег камеры олимпус?

Решил проверить количество срабатываний затвора на камере Олимпус М10 Марк 2.
Камеры Олимпус в EXIF не прописывают счетчик камеры, счетчик можно посмотреть только на камере, для этого нужно зайти в сервисное меню.

  1. Выключить камеру.
  2. Нажать кнопку MENU. Удерживая ее нажатой, включить камеру.
  3. Отпустить кнопку MENU и снова ее нажать для входа в меню.
  4. Зайти в меню (SETUP) — меню настроек, пиктограмма гаечного ключа — настройки яркости LCD, расположен в третьем пункте.
  5. Нажать стрелку ВПРАВО для выделения ползунка регулировки яркости.
  6. Нажать последовательно кнопку INFO, затем кнопку OK. Камера покажет строку вида: OLYMPUS E-P1 01 01 01 01.
  7. Нажать последовательно кнопки ВВЕРХ → ВНИЗ → ВЛЕВО → ВПРАВО → ЗАТВОР → ВВЕРХ. Отобразится первая страница сервисного меню.
  8. Нажимать ВПРАВО, перейдет ко второй странице

Показания счетчиков пробега отображаются на второй странице:

  • R — количество срабатываний затвора
  • S — количество активаций вспышки
  • U — количество срабатываний ультразвукового фильтра очистки матрицы (т. е. количество включений камеры)
  • B — количество полных нажатий на кнопку затвора по разным причинам
Камера сделала 100 947 снимка, включалась 6 361 раз и 1 590 раз фотографировал со вспышкой, причем вспышку я всегда использую внешнюю.
  1. ВНИЗ для третьей страницы
    На странице 3 отображаются серийный номер камеры (CS) и серийный номер материнской платы (MCS).
  1. ВЛЕВО для четвертой страницы
    На странице 4 показывается лог ошибок функционирования камеры. Если ошибок не было, лог пустой.
  1. ВВЕРХ для возврата к первой странице.
  2. Для выхода из сервисного меню выключить камеру.

Что брать на пикник

У нас газовый гриль weber go anywhere с переходником под цанговые баллоны. Переходник стоит около 300 ₽. Цанговый баллон — 100 ₽.

Наш список:

Мясо

  • Какое нравится, то и берите.

Овощи

  • баклажаны маленькие, такие чтобы целиком в гриль положить, совсем маленькие,
  • помидоры длинные, грунтовые, не большие,
  • перец болгарский, обычный, небольшой, для гриля,
  • шампиньоны крупные,
  • кабачки маленькие.

Гриль

  • гриль + газ,
  • фольга,
  • щипцы,
  • лопатка металлическая,
  • щетка для решетки,
  • масло растительное,
  • силиконовую кисточку для масла,
  • салфетки,
  • термометр для мяса,
  • шпажки для овощей или мяса,
  • пакет для посуды грязной, которую забираем мыть,
  • пакет для мусора.

Посуда многоразовая

  • пластиковый контейнер,
  • тарелки,
  • стаканчики,
  • нож с желтой ручкой.

Посуда одноразовая

  • вилки,
  • ножи для мяса.

Проверить перед пикником:

  • газ, в наличии должно быть два баллона
  • масло подсолнечное, маленькая баночка, если что долить.

Если нет специального места

  • шезлонги,
  • столик.
В этот раз поместился 1,2 килограмма мяса
Овощи лучше смазать маслом

Видеонаблюдение через телеграм

На камерах Hikvision можно сделать простое видеонаблюдение через телеграм.
Когда в камере срабатывает датчик движения, камера отправляет на телеграм фотографию что произошло.

Отправляются три изображения с интервалом 2 секунды, от момента срабатывания датчика

По умолчанию, мы не можем отправлять изображения в телеграм, можем только на почту.

Настройки детектора движения: «Настройки» → «По событию» → «События» → «Детектор движения». Настраиваем зону срабатывания и событие отправки на электронную почту.

Отправлять события нужно на гугл почту. В гугле есть App Script, с помощью которого можно пересылать почту в телеграм.

Настройки видеокамеры для отправки на электронную почту: «Настройки» → «Сеть» → «Доп. настройки» → «Email»
Если все настроено правильно, в почту гугл начнут приходить письма с фотографиями.

На гитхабе выложен пример скрипта, для отправки вложенных в письма фотографий в телеграм

Нам, остается немного его доработать, так как скрипт отправляет первое вложение в телеграм.

Присваиваем всем нашим письмам ярлык — CAMERA, скрипт проверяет или все письма или по определенным параметрам, например, ярлык.
Если правильно настроено правило, ярлыки появляются у каждого нового письма с камеры
Дальше в апп скрипте вставляем наш скрипт, запускаем, тестирует, занимаемся отладкой.
Ставим запуск скрипта раз в минуту. То есть почта будет проверяться раз в минуту и при соответвии условиям отправляться.

Мой скрипт:

// The token of your Telegram bot
var TOKEN = "token bot";

// Name of the Telegram channel which bot is added into
var CHANNEL = "id канала";

// Name of the Gmail Label which need to search for
var LABEL = "CAMERA"

function processEmails() {
  
  // Search unread emails with specified label
  var search = "label:" + LABEL + " is:unread";
  Logger.log('Search: ' + search);
  var threads = GmailApp.search(search, 0, 10);
  
  for (var i = 0; i < threads.length; i++) {
    var messages = threads[i].getMessages();
    Logger.log('Number of emails found: ' + messages.length);

    for (var j = 0; j < messages.length; j++) {
      var m = messages[j];
      if (!m.isInTrash() && m.isUnread()) {
        if (m.getAttachments().length > 0) {
          
          // Get the first attachment (image jpeg file)
          // and send to telegram bot
          sendPhoto(m.getAttachments()[0].copyBlob());
          Logger.log('фото: ' + '1');
          Utilities.sleep(500);// pause in the loop for 500 milliseconds
          sendPhoto(m.getAttachments()[1].copyBlob());
          Logger.log('фото: ' + '2');
          Utilities.sleep(500);// pause in the loop for 500 milliseconds
          sendPhoto(m.getAttachments()[2].copyBlob());
          Logger.log('фото: ' + '3');
          Utilities.sleep(500);// pause in the loop for 500 milliseconds   
        }
        m.markRead(); 
        m.moveToTrash(); // Where I would need a delete forever trigger;
      }
    }
  }
}

function sendPhoto(photo) {
  var payload = {
    'chat_id': CHANNEL,
    'photo': photo
  };
  var options = {
    'method': 'post',
    'payload': payload
  };
  UrlFetchApp.fetch("https://api.telegram.org/bot" + TOKEN + "/sendPhoto", options);
}

Из правок:

  • отправляются 1,2,3 вложения,
  • между отправкой пауза 0,5 секунды,
  • сообщение после обработки удаляется в корзину.

Отправляем новые статьи из РСС в телеграм

Удобно присылать новые ссылки на статьи моих подписок РСС в телеграм, так как вся коммуникация уже в нем, фидли почти не использую.

Евгений Гончаров, в статье «RSS фидер на Python с оправкой уведомлений в Телеграм» описал весь принцип отправки и использование базы данных для контроля что отправили. Готовый код на гитхабе Евгения

Я внес небольшие изменения в код:

  • Сообщения в телеграм отправляются с задержкой 1 секунда. Если не использовать таймаут, сервер телеграма, может отправить не все сообщения.
  • Изменил вид отправки сообщений: добавил переносы строк и автора, если он есть.
В канал телеграма приходят новые сообщения. Проверка РСС проходит с 7 утра до 11 вечера, с интервалом 30 минут.

Канал открытый, можно подписаться на «Почитаем», там 95 источников РСС: например, избранное блогов на Эгее, Илья Бирман, Максим Ильяхов, Николай Товеровский, и другие.

В примере скрипта: блоги на Эгее и мой блог.

Скрипт:

#!/usr/bin/python3
# Created by Yevgeniy Goncharov, https://sys-adm.in
# Script for reading and forwarding to Telegram, rss feeds


# Imports
import sqlite3
import requests
import feedparser
import os
import urllib
import random
import time

# Bot creds
bot_token = 'bot_token'
bot_chatID = 'bot_chatID'

# Feeds
myfeeds = [
    'https://blogengine.ru/blogs/rss/',
    'http://blog.fossko.ru/rss/',

]

# User agents
uags = [
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
]

# Random User Agent (from uags list)
ua = random.choice(uags)

# Header
headers = {
  "Connection" : "close",  # another way to cover tracks
  "User-Agent" : ua
}

# Proxies
proxies = {
}

# DB
scriptDir = os.path.dirname(os.path.realpath(__file__))
db_connection = sqlite3.connect(scriptDir + '/rss.sqlite')
db = db_connection.cursor()
db.execute('CREATE TABLE IF NOT EXISTS myrss (title TEXT, date TEXT)')

# Get posts from DB and print
def get_posts():
    with db_connection:
        db.execute("SELECT * FROM myrss")
       # print(db.fetchall())

# Check post in DB
def article_is_not_db(article_title, article_date):
    db.execute("SELECT * from myrss WHERE title=? AND date=?", (article_title, article_date))
    if not db.fetchall():
        return True
    else:
        return False

# Add post to DB
def add_article_to_db(article_title, article_date):
    db.execute("INSERT INTO myrss VALUES (?,?)", (article_title, article_date))
    db_connection.commit()

# Send notify to Telegram bot
def bot_sendtext(bot_message):
    #bot_message = urllib.parse.quote(bot_message)
    bot_message = bot_message
    send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
    requests.get(send_text, proxies=proxies, headers=headers)
    print(send_text)

# Check, read articles
def read_article_feed(feed):
    """ Get articles from RSS feed """
    feedparser.USER_AGENT = ua
    feed = feedparser.parse(feed)
    print(feed)
    for article in feed['entries']:
        if article_is_not_db(article['title'], article['published']):
            add_article_to_db(article['title'], article['published'])
           # bot_sendtext('New feed found ' + article['title'] +', ' + article['link'] + ', ' + article['description'])
            try:
                rss_autor = article['author'] +'%0A%0A'
            except:
                rss_autor = ""
            MSGsend='*'+ article['title'] + '*%0A%0A' + rss_autor + article['link']
            MSGsend=MSGsend.replace("_", "\_")  # замена подчеркивания для отправки в ТГ
            bot_sendtext(MSGsend)            
            time.sleep(1)
           # print(article)

# Rotate feeds array
def spin_feds():
    for x in myfeeds:
       # print(x)
        read_article_feed(x)

# Runner :)
if __name__ == '__main__':
    spin_feds()
    # get_posts()
    db_connection.close()

Отправка из Яндекс форм в телеграм

У Яндекса есть удобный сервис — Яндекс формы, он позволяет вставлять любые формы на любые сайты.
А вот получение данных не всегда удобное: нужно зайти в форму, перейти к ответам, посмотреть результаты.

Входим в форму — интеграции
Можно отправлять на е-маил, это реализовано сразу, включаем в настройках, указываем кому отправить форму, что написать и заполняем шаблон.

Для отправки в телеграм, используется интеграция — *API Запрос заданным методом

Метод запроса POST

У меня отправляется только если весь запрос передать в УРЛ, по-хорошему нужно передавать через тело запроса, но у меня не работает.

В УРЛ подставляем следующее:

https://api.telegram.org/ИД вашего бота:Секретный ключ бота/sendMessage?chat_id=ИД кому отправлять&text=*Дзен_Яндекс*: Что из формы отправлять   &parse_mode=Markdown

https://api.telegram.org/bot111111:AABBBCCDDDFFFHJGHGHG/sendMessage?chat_id=1111111&text=&text=*Заявка_с_Дзена*%0A
Ответы на все вопросы&parse_mode=Markdown

Айди канала или пользователя можно узнать через бота

%0A — Это символ пробела

После какого-то обновления на Яндекс Формах не проходят знаки пробела, можно поставить подчеркивание и пользоваться дальше

Ответы на вопросы — что передаем в сообщении, выбирается в параметрах, там куча всего можно передавать.

Варианты, что можно отправить из формы в телеграм
Заполняем форму и получаем ответ в телеграм

Удаление старых резервных копий в Windows Server

Иногда нужно удалить резервные копии, которые делает стандартная программа архивирования wbadmin

Удалить последнюю резервную копию хранящуюся на диске G:

wbadmin delete backup -backupTarget:g: -deleteOldest -quiet

Оставить 150 новых резервных копий хранящихся на диске G:

wbadmin delete backup -backupTarget:g: -keepVersions:150 -quiet
Удаление старых копий идет долго. Например, общий объем резервирования 150 Гб, удаление одной копии около минуты. 150 копий — 2—3 часа.

Простое резервное копирование через повершел

Потребовалось на повершеле написать скрипт резервного копирования файлов которые сделаны сегодня и вчера.

Для копирования есть функция — Copy-Item

Copy-Item "Что-то" -Destination "Куда-то" -force

Вместо «куда-то» можно использовать переменную с папкой, например:

$path_new = "F:\backup\" #папка в которую копируем
$path = "\\FileServer\backup\" # папка из которой копируют, лежит на файл сервере

тогда скрипт будет как-то так:

Copy-Item "Что-то" -Destination $path_new  -force #Копируем что-то в папку $path_new

например, всё содержимое папки $path в папку $path_new

Copy-Item $path -Destination $path_new  -force #Копируем всё содержимое папки $path в папку $path_new

«Что-то» это файлы в определенной папке, созданные вчера. То есть файлы у которых дата создания отличается от сегодня на один день.
Определим дату с которой мы будем считать файлы

$date = (Get-Date).AddDays(-1) #определение в переменную даты минус сколько-то от текущей, в наем случае минус 1

Теперь получим список всех файлов, в папке дата и время которых больше вчерашней даты.
есть особенность, что до версии powershell3, нужно писать так

$file_copy = Get-ChildItem -Path $path | Where-Object {$_.CreationTime -gT $date2} #определяем все файлы которые нужно скопировать

После версии powershell3, нужно писать так

$file_copy = Get-ChildItem -Path $path | Where-Object -Property CreationTime -gT $date #определяем все файлы которые нужно скопировать

У меня установлена старая версия, поэтому я пишу скрипт по-старому

Get-ChildItem -Path $path | Where-Object {$_.CreationTime -gT $date} | Copy-Item -Destination $path_new -force #Копируем все файлы которые старше даты и времени $date из папки $path в папку $path_new

Еще не хватает записи логов, чтобы понимать что и когда копировалось.
В статье «Используем лог-файлы в скриптах powershell» приводится скрипт который можно использовать:

$Logfile = $path_new+"log.txt" # определяем где лог-файл

function WriteLog                #функиця записи в лог-файл
{
Param ([string]$LogString)
$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
$LogMessage = "$Stamp $LogString"
Add-content $LogFile -value $LogMessage
}

Функция WriteLog — дописывает лог-файл, тем что в нее передали, например список файлов.

Соберем скрипт полностью:

$path_new = "F:\backup\" #папка в которую копируем

$Logfile = $path_new+"log.txt" # определяем где лог-файл
function WriteLog                #функиця записи в лог-файл
{
Param ([string]$LogString)

$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
$LogMessage = "$Stamp $LogString"
Add-content $LogFile -value $LogMessage
}

$path = "\\FileServer\backup\" # папка из которой копируют
WriteLog "$path копирование начато"
$date = (Get-Date).AddDays(-1) #определение в переменную даты минус сколько-то от текущей
$file_copy = Get-ChildItem -Path $path | Where-Object {$_.CreationTime -gT $date} #определяем список файлов, для копирования и записи в лог-файл
WriteLog "$file_copy"
Get-ChildItem -Path $path | Where-Object {$_.CreationTime -gT $date} | Copy-Item -Destination $path_new -force #копирование файлов с текущей датой и временем старше -1
WriteLog "$path копирование закончено"
По логу можно посмотреть дату и время начала каждой операции. Это полезно, если скрипт запускается по расписанию.
Ранее Ctrl + ↓