{"id":465362,"date":"2025-07-01T15:04:01","date_gmt":"2025-07-01T15:04:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=465362"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=465362","title":{"rendered":"<span>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 amoCRM \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Telegram-\u0431\u043e\u0442\u0430<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e Telegram-\u0431\u043e\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 amoCRM \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0432 CRM, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 \u0442\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u0445 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u044f\u043c: \u043e\u0442\u0434\u0435\u043b \u043f\u0440\u043e\u0434\u0430\u0436 \u0432\u0438\u0434\u0438\u0442 \u0441\u0443\u043c\u043c\u0443 \u0441\u0434\u0435\u043b\u043a\u0438 \u0438 \u0441\u0442\u0430\u0434\u0438\u044e, \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u2013 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043d\u043e\u0432\u043e\u0439 \u0441\u0434\u0435\u043b\u043a\u0435. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u043d\u043e\u0432\u044b\u0435 \u043b\u0438\u0434\u044b, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0437\u0430 \u0441\u0434\u0435\u043b\u043a\u0430\u043c\u0438 \u0438 \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 CRM-\u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<p>\u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0411\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 PostgreSQL \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0431\u043e\u0442\u0430.<\/p>\n<p>\u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043c\u044b \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u043c \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 Amvera, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0430\u0441\u0442 \u043d\u0430\u043c<\/p>\n<ul>\n<li>\n<p>\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 PostgreSQL \u0441 \u0431\u044d\u043a\u0430\u043f\u0430\u043c\u0438, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u043c \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 IDE, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f git push (\u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0438\u0432\u0430\u044f \u0444\u0430\u0439\u043b\u044b \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435), \u0447\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043c\u043e\u0431\u0430\u043b\u0430\u043d\u0441 \u0432 111 \u0440\u0443\u0431. \u0434\u043b\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u2013 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. <\/strong><\/p>\n<p>\u0417\u0430\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0441\u0430\u0439\u0442 <a href=\"https:\/\/amvera.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=amo\" rel=\"noopener noreferrer nofollow\">Amvera<\/a>, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 PostgreSQL \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0443\u043a\u0430\u0437\u0430\u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u0431\u0440\u0430\u0432 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a21\/369\/c5f\/a21369c5fdec51609cd2102295c98e97.png\" alt=\"\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0442\u0430\u0440\u0438\u0444. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.\" title=\"\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0442\u0430\u0440\u0438\u0444. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.\" width=\"1422\" height=\"768\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a21\/369\/c5f\/a21369c5fdec51609cd2102295c98e97.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a21\/369\/c5f\/a21369c5fdec51609cd2102295c98e97.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0442\u0430\u0440\u0438\u0444. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1e9\/f95\/00c\/1e9f9500c06a976045f16d96b541074a.png\" alt=\"\u0417\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u0438 \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c\" title=\"\u0417\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u0438 \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c\" width=\"1414\" height=\"1314\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/1e9\/f95\/00c\/1e9f9500c06a976045f16d96b541074a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1e9\/f95\/00c\/1e9f9500c06a976045f16d96b541074a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0417\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u0438 \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0411\u0414 \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u00ab\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u00bb \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u043e\u0442\u0430. \u0415\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2013 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 amoCRM \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 Telegram.<\/p>\n<p>\u0411\u043e\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \/start, \/sales \u0438\u043b\u0438 \/admin, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0440\u043e\u043b\u044c.  \u0411\u043e\u0442 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 amoCRM \u0447\u0435\u0440\u0435\u0437 API, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u043e\u0432\u044b\u0445 \u0441\u0434\u0435\u043b\u043e\u043a. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u043e\u0442 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u043c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044f \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0445 \u0440\u043e\u043b\u0438.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u043e\u0442 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0438 \u0441 amoCRM, \u043d\u0438 \u0441 Telegram.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<strong>Telegram Bot Token<\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 Telegram \u0431\u043e\u0442\u0430\u00a0<a href=\"https:\/\/telegram.me\/BotFather\" rel=\"noopener noreferrer nofollow\">BotFather<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u043c\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<code>\/start<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c\u00a0<code>\/newbot<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c: \u0432\u0432\u0435\u0441\u0442\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u00abusername\u00bb \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u043e\u0442\u0430 (username \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u00a0<code>bot<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>mycompany_sales_bot<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e BotFather \u0432\u044b\u0448\u043b\u0435\u0442 \u0432\u0430\u043c \u0442\u043e\u043a\u0435\u043d<\/p>\n<\/li>\n<\/ol>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f amoCRM \u0438 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u0431\u043e\u0442\u0430<\/h2>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0443\u0436\u0435\u043d\u00a0<strong>Access Token \u0434\u043b\u044f amoCRM<\/strong>. \u042d\u0442\u043e\u0442 \u0442\u043e\u043a\u0435\u043d \u0434\u0430\u0451\u0442 \u0431\u043e\u0442\u0443 \u043f\u0440\u0430\u0432\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a API amoCRM \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430. \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043d\u043e \u043e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0432\u0430:<\/p>\n<ol>\n<li>\n<p><strong>\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e<\/strong>: \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 amo\u041c\u0410\u0420\u041a\u0415\u0422, \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0442\u0440\u0438 \u0442\u043e\u0447\u043a\u0438 \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443 \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e\u00bb, \u00ab\u0412\u043d\u0435\u0448\u043d\u044f\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u00bb. \u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb.<\/p>\n<\/li>\n<li>\n<p><strong>\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e<\/strong>: \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0440\u0430\u0437\u0434\u0435\u043b \u00ab\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435\u00bb \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d<\/strong>\u00a0(Access Token). \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u043e\u043a\u0435\u043d \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0433 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b amoCRM, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u043a\u0438. \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e\u00a0<code>ACCESS_TOKEN<\/code>\u00a0\u0432 \u0432\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u0432\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0434\u0432\u0430 \u0442\u043e\u043a\u0435\u043d\u0430:<\/p>\n<ul>\n<li>\n<p><code><strong>TELEGRAM_BOT_TOKEN<\/strong><\/code>\u00a0\u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u044b\u0434\u0430\u043d\u043d\u0430\u044f BotFather, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Telegram API.<\/p>\n<\/li>\n<li>\n<p><code><strong>ACCESS_TOKEN<\/strong><\/code>\u00a0\u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0434\u0430\u044e\u0449\u0430\u044f \u043f\u0440\u0430\u0432\u043e \u0431\u043e\u0442\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b API amoCRM<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0431\u043e\u0442\u0430.<br \/>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442. \u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><strong>requests<\/strong>\u00a0\u2013 \u0434\u043b\u044f HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (Telegram, amoCRM).<\/p>\n<\/li>\n<li>\n<p><strong>psycopg2<\/strong>\u00a0\u2013 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL.<\/p>\n<\/li>\n<li>\n<p><strong>time, datetime<\/strong>\u00a0\u2013 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u0442. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0443\u043a\u0430\u0436\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: \u0434\u043e\u043c\u0435\u043d amoCRM, \u0442\u043e\u043a\u0435\u043d\u044b amoCRM \u0438 Telegram, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">import requests import time import psycopg2 from datetime import datetime  # \u0414\u043e\u043c\u0435\u043d \u0432\u0430\u0448\u0435\u0439 amoCRM AMOCRM_DOMAIN = 'name.amocrm.ru'  # \u0422\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API amoCRM ACCESS_TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGc...' #\u0412\u0430\u0436\u043d\u043e, \u0442\u043e\u043a\u0435\u043d\u044b \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u0434\u0430\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438  # Telegram Bot Token, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0443 BotFather TELEGRAM_BOT_TOKEN = '8072282519:AA...'  # \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL (DB_CONFIG) DB_CONFIG = {     'dbname': 'DB_name',     'user': 'User_Name',     'password': 'Password',     'host': 'HOST',     'port': 5432 } <\/code><\/pre>\n<p>\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043e\u043c\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/docs.amvera.ru\/databases\/postgreSQL.html\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0430\u0442\u0446\u0438\u0438<\/a> Amvera<\/p>\n<p>\u0412\u044b\u0434\u0435\u043b\u0438\u043c \u0434\u0432\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u2014\u00a0<strong>UPDATE_OFFSET<\/strong>\u00a0\u0438\u00a0<strong>STAGE_MAPPING<\/strong>.<\/p>\n<p><strong>UPDATE_OFFSET<\/strong>\u00a0\u0445\u0440\u0430\u043d\u0438\u0442 ID \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 Telegram. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u043d\u0435 \u0447\u0438\u0442\u0430\u043b \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437.<br \/><strong>STAGE_MAPPING<\/strong>\u00a0\u0437\u0430\u0434\u0430\u0451\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 ID \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0432 amoCRM \u0438 \u0438\u0445 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c. \u041a\u043e\u0433\u0434\u0430 \u0441\u0434\u0435\u043b\u043a\u0430 \u0438\u043c\u0435\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0<code>status_id = 74340918<\/code>, \u0431\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u00ab\u041f\u0435\u0440\u0435\u0433\u043e\u0432\u043e\u0440\u044b\u00bb, \u0430 \u043d\u0435 \u043d\u0430\u0431\u043e\u0440 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<pre><code class=\"python\">UPDATE_OFFSET = None  STAGE_MAPPING = {     74340914: \"\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0440\u0430\u043a\u0442\",     74340918: \"\u041f\u0435\u0440\u0435\u0433\u043e\u0432\u043e\u0440\u044b\",     74340922: \"\u041e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u044f\",     74340926: \"\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430\" }  <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0445\u0435\u043c\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043d\u0435\u0439 \u0431\u0443\u0434\u0443\u0442 \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<ul>\n<li>\n<p><strong>deals<\/strong>\u00a0\u2013 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0434\u0435\u043b\u043a\u0438 \u0438\u0437 amoCRM (\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0441\u0443\u043c\u043c\u0430, \u0434\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0441\u0442\u0430\u0442\u0443\u0441 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0438 \u0441\u0442\u0430\u0434\u0438\u044f).<\/p>\n<\/li>\n<li>\n<p><strong>users<\/strong>\u00a0\u2013 \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u0431\u043e\u0442\u0430: \u0438\u0445 chat_id \u0432 Telegram \u0438 \u0440\u043e\u043b\u044c (user, sales, admin).<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">def initialize_database():     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"\"\"         CREATE TABLE IF NOT EXISTS deals (             id SERIAL PRIMARY KEY,             deal_id INTEGER UNIQUE,             name TEXT,             price NUMERIC,             created_at TIMESTAMP,             notified BOOLEAN DEFAULT false         );         \"\"\")         cur.execute(\"\"\"         CREATE TABLE IF NOT EXISTS users (             id SERIAL PRIMARY KEY,             chat_id BIGINT UNIQUE,             role TEXT DEFAULT 'user'         );         \"\"\")         conn.commit()         cur.close()         conn.close()         print(\"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445:\", e)  <\/code><\/pre>\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0442\u0430\u0434\u0438\u044e \u0441\u0434\u0435\u043b\u043a\u0438 (<code>stage<\/code>). \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443\u00a0<strong>deals<\/strong>, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442:<\/p>\n<pre><code class=\"python\">def update_database_schema():     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"ALTER TABLE deals ADD COLUMN IF NOT EXISTS stage TEXT;\")         conn.commit()         cur.close()         conn.close()         print(\"\u0421\u0445\u0435\u043c\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0445\u0435\u043c\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445:\", e)  <\/code><\/pre>\n<p>\u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u00a0<code>\/start<\/code>,\u00a0<code>\/sales<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>\/admin<\/code>, \u043c\u044b \u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0440\u043e\u043b\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u00a0<strong>users<\/strong>.<br \/> \u0420\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u0445.<\/p>\n<pre><code class=\"python\">def update_user_role(chat_id, role):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         query = \"\"\"         INSERT INTO users (chat_id, role)         VALUES (%s, %s)         ON CONFLICT (chat_id) DO UPDATE SET role = EXCLUDED.role;         \"\"\"         cur.execute(query, (chat_id, role))         conn.commit()         cur.close()         conn.close()         print(f\"\u0420\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f {chat_id} \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 {role}.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0440\u043e\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:\", e)  def add_user(chat_id):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         query = \"INSERT INTO users (chat_id) VALUES (%s) ON CONFLICT (chat_id) DO NOTHING;\"         cur.execute(query, (chat_id,))         conn.commit()         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:\", e)  def get_all_users():     users = []     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"SELECT chat_id, role FROM users;\")         rows = cur.fetchall()         for row in rows:             users.append({'chat_id': row[0], 'role': row[1]})         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:\", e)     return users  <\/code><\/pre>\n<ul>\n<li>\n<p><strong>update_user_role<\/strong>\u00a0\u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0440\u043e\u043b\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>add_user<\/strong>\u00a0\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0440\u043e\u043b\u044c\u044e \u00abuser\u00bb \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>get_all_users<\/strong>\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u0440\u043e\u043b\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u043c\u043e\u0433 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u00a0<code>getUpdates<\/code>\u00a0\u0443 Telegram. \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0445, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438\u043b\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0431\u043e\u0442\u0430.<\/p>\n<pre><code class=\"python\">def update_chat_ids():     global UPDATE_OFFSET     url = f\"https:\/\/api.telegram.org\/bot{TELEGRAM_BOT_TOKEN}\/getUpdates\"     params = {}     if UPDATE_OFFSET is not None:         params['offset'] = UPDATE_OFFSET + 1      try:         response = requests.get(url, params=params, timeout=10)         data = response.json()         updates = data.get(\"result\", [])         if updates:             for update in updates:                 UPDATE_OFFSET = update.get(\"update_id\", UPDATE_OFFSET)                 message = update.get(\"message\", {})                 chat = message.get(\"chat\", {})                 text = message.get(\"text\", \"\").strip()                 chat_id = chat.get(\"id\")                  if chat_id:                     if text in [\"\/start\", \"\/sales\", \"\/admin\"]:                         if text == \"\/start\":                             role = \"user\"                         elif text == \"\/sales\":                             role = \"sales\"                         elif text == \"\/admin\":                             role = \"admin\"                         update_user_role(chat_id, role)                     else:                         add_user(chat_id)     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f chat_ids:\", e)  <\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0440\u0430\u0437\u043d\u044b\u043c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0440\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ol>\n<li>\n<p><strong>send_message_to_user<\/strong>\u00a0\u2013 \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e chat_id;<\/p>\n<\/li>\n<li>\n<p><strong>send_role_based_notification<\/strong>\u00a0\u2013 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430 \u043e \u043d\u043e\u0432\u043e\u0439 \u0441\u0434\u0435\u043b\u043a\u0435, \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0440\u043e\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>send_status_change_notification<\/strong>\u00a0\u2013 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 sales \u0438 admin \u043f\u0440\u0438 \u0441\u043c\u0435\u043d\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0441\u0434\u0435\u043b\u043a\u0438.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"python\">def send_message_to_user(chat_id, message):     url = f\"https:\/\/api.telegram.org\/bot{TELEGRAM_BOT_TOKEN}\/sendMessage\"     data = {'chat_id': chat_id, 'text': message}     try:         response = requests.post(url, data=data)         if response.status_code != 200:             print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f {chat_id}: {response.text}\")     except Exception as e:         print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f {chat_id}: {e}\")  def send_role_based_notification(deal):     users = get_all_users()     for user in users:         role = user['role']         chat_id = user['chat_id']         if role == 'admin':             message = (                 f\"[ADMIN] \u041d\u043e\u0432\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430!\\n\"                 f\"ID: {deal['deal_id']}\\n\"                 f\"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435: {deal['name']}\\n\"                 f\"\u0421\u0443\u043c\u043c\u0430: {deal['price']} \u0440\u0443\u0431.\\n\"                 f\"\u0421\u0442\u0430\u0434\u0438\u044f: {deal['stage']}\\n\"                 f\"\u0421\u043e\u0437\u0434\u0430\u043d\u0430: {deal['created_at'].strftime('%Y-%m-%d %H:%M:%S')}\"             )         elif role == 'sales':             message = (                 f\"[SALES] \u041d\u043e\u0432\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430!\\n\"                 f\"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435: {deal['name']}\\n\"                 f\"\u0421\u0443\u043c\u043c\u0430: {deal['price']} \u0440\u0443\u0431.\\n\"                 f\"\u0421\u0442\u0430\u0434\u0438\u044f: {deal['stage']}\"             )         else:             message = f\"\u041d\u043e\u0432\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430: {deal['name']} (\u0421\u0442\u0430\u0434\u0438\u044f: {deal['stage']})\"                  send_message_to_user(chat_id, message)  def send_status_change_notification(change_info):     deal = change_info[\"deal\"]     old_stage = deal[\"old_stage\"]     new_stage = deal[\"stage\"]     message = (         f\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0441\u0434\u0435\u043b\u043a\u0438:\\n\"         f\"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435: {deal['name']}\\n\"         f\"ID \u0441\u0434\u0435\u043b\u043a\u0438: {deal['deal_id']}\\n\"         f\"\u0421\u0442\u0430\u0440\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441: {old_stage}\\n\"         f\"\u041d\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441: {new_stage}\"     )     users = get_all_users()     for user in users:         if user[\"role\"] in [\"sales\", \"admin\"]:             send_message_to_user(user[\"chat_id\"], message)  <\/code><\/pre>\n<ul>\n<li>\n<p>\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 (<strong>admin<\/strong>) \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0430\u043c\u044b\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0434\u0435\u043b\u043a\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0430\u043c (<strong>sales<\/strong>) \u0432\u0438\u0434\u0438\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0420\u044f\u0434\u043e\u0432\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c (<strong>user<\/strong>) \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043c\u0435\u043d\u0435 \u0441\u0442\u0430\u0434\u0438\u0438 \u0441\u0434\u0435\u043b\u043a\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u00ab\u041f\u0435\u0440\u0435\u0433\u043e\u0432\u043e\u0440\u044b\u00bb \u2192 \u00ab\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430\u00bb) \u043e\u043f\u043e\u0432\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e\u00a0<strong>sales<\/strong>\u00a0\u0438\u00a0<strong>admin<\/strong>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0434\u0435\u043b\u043a\u0443 \u0438\u0437 amoCRM \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 deals. \u0415\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u043a\u0430 \u043d\u043e\u0432\u0430\u044f, \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0435\u0451; \u0435\u0441\u043b\u0438 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c \u043b\u0438 \u0441\u0442\u0430\u0434\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">def store_deal_in_db(lead):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()          deal_id = lead.get('id')         name = lead.get('name', '\u041d\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f')         price = lead.get('price', 0)         created_at_ts = lead.get('created_at', 0)         created_at = datetime.fromtimestamp(created_at_ts)          stage_id = lead.get('status_id')         new_stage = STAGE_MAPPING.get(stage_id, f\"\u0421\u0442\u0430\u0434\u0438\u044f {stage_id}\") if stage_id else \"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\"          cur.execute(\"SELECT stage FROM deals WHERE deal_id = %s;\", (deal_id,))         result = cur.fetchone()         if result is None:             query = \"\"\"             INSERT INTO deals (deal_id, name, price, created_at, stage)             VALUES (%s, %s, %s, %s, %s)             ON CONFLICT (deal_id) DO NOTHING;             \"\"\"             cur.execute(query, (deal_id, name, price, created_at, new_stage))             conn.commit()             cur.close()             conn.close()             return {\"action\": \"new\",                     \"deal\": {\"deal_id\": deal_id, \"name\": name, \"price\": price,                              \"created_at\": created_at, \"stage\": new_stage}}         else:             old_stage = result[0]             if old_stage != new_stage:                 cur.execute(\"UPDATE deals SET stage = %s WHERE deal_id = %s;\", (new_stage, deal_id))                 conn.commit()                 cur.close()                 conn.close()                 return {\"action\": \"changed\",                         \"deal\": {\"deal_id\": deal_id, \"name\": name, \"price\": price,                                  \"created_at\": created_at, \"stage\": new_stage, \"old_stage\": old_stage}}             else:                 cur.close()                 conn.close()                 return {\"action\": \"none\"}     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0441\u0434\u0435\u043b\u043a\u0438 \u0432 \u0411\u0414:\", e)         return {\"action\": \"error\"}  <\/code><\/pre>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:\u00a0<code>new<\/code>\u00a0(\u043d\u043e\u0432\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430),\u00a0<code>changed<\/code>\u00a0(\u0441\u0442\u0430\u0434\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c) \u0438\u043b\u0438\u00a0<code>none<\/code>\u00a0(\u043d\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439).<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0441\u0434\u0435\u043b\u043a\u0435 \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u043b\u0435\u00a0<code>notified<\/code>. \u0415\u0441\u043b\u0438\u00a0<code>notified = false<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u0435\u0449\u0451 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435, \u0438 \u043d\u0443\u0436\u043d\u043e \u0435\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u041f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u00a0<code>notified<\/code>\u00a0\u0432\u00a0<code>true<\/code>.<\/p>\n<pre><code class=\"python\">def get_unnotified_deals():     deals = []     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"SELECT deal_id, name, price, created_at, stage FROM deals WHERE notified = false;\")         rows = cur.fetchall()         for row in rows:             deals.append({                 'deal_id': row[0],                 'name': row[1],                 'price': row[2],                 'created_at': row[3],                 'stage': row[4]             })         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043d\u0435\u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0434\u0435\u043b\u043e\u043a:\", e)     return deals   def mark_deal_as_notified(deal_id):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"UPDATE deals SET notified = true WHERE deal_id = %s;\", (deal_id,))         conn.commit()         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0441\u0434\u0435\u043b\u043a\u0438:\", e)  <\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u0430\u044f \u043d\u043e\u0432\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430 (\u0438\u043b\u0438 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u0434\u0435\u043b\u043a\u0438) \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438.<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432\u0441\u0451: \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c amoCRM, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u0434\u0435\u043b\u043a\u0438, \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430. \u0412\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u00a0<code>check_new_deals()<\/code>:<\/p>\n<pre><code class=\"python\">def check_new_deals():     update_chat_ids()     url = f\"https:\/\/{AMOCRM_DOMAIN}\/api\/v4\/leads\"     headers = {\"Authorization\": f\"Bearer {ACCESS_TOKEN}\"}     try:         response = requests.get(url, headers=headers, timeout=10)         if response.status_code != 200:             print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 amoCRM: {response.status_code} {response.text}\")             return         data = response.json()         leads = data.get(\"_embedded\", {}).get(\"leads\", [])     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a amoCRM:\", e)         return      status_changes = []     for lead in leads:         result = store_deal_in_db(lead)         if result.get(\"action\") == \"changed\":             status_changes.append(result)      unnotified_deals = get_unnotified_deals()     for deal in unnotified_deals:         send_role_based_notification(deal)         mark_deal_as_notified(deal['deal_id'])      for change_info in status_changes:         send_status_change_notification(change_info)  <\/code><\/pre>\n<p>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c:<\/p>\n<ol>\n<li>\n<p><strong>update_chat_ids()<\/strong>\u00a0\u2013 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u043b\u0438 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0431\u043e\u0442\u0435 (\u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u043e\u043b\u0435\u0439).<\/p>\n<\/li>\n<li>\n<p><strong>GET-\u0437\u0430\u043f\u0440\u043e\u0441 \u043a amoCRM<\/strong>\u00a0\u2013 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0434\u0435\u043b\u043e\u043a (leads).<\/p>\n<\/li>\n<li>\n<p><strong>store_deal_in_db(lead)<\/strong>\u00a0\u2013 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0434\u0435\u043b\u043a\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c \u043b\u0438 \u0435\u0451 \u0441\u0442\u0430\u0434\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>get_unnotified_deals()<\/strong>\u00a0\u2013 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u043a\u0438, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0435\u0449\u0451 \u043d\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u043b\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>send_role_based_notification(deal)<\/strong>\u00a0\u2013 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0435\u043c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u043c \u0440\u043e\u043b\u044f\u043c.<\/p>\n<\/li>\n<li>\n<p><strong>mark_deal_as_notified()<\/strong>\u00a0\u2013 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c, \u0447\u0442\u043e \u0441\u0434\u0435\u043b\u043a\u0430 \u0443\u0436\u0435 \u00ab\u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0430\u00bb.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0434\u0435\u043b\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c \u0441\u0442\u0430\u0434\u0438\u044f \u2013 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0444\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0432\u00a0<code>status_changes<\/code>, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438.<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u043a\u043a\u043e\u0440\u0434: \u00ab\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u00bb \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0412 \u0431\u043b\u043e\u043a\u0435\u00a0<code>if <strong>name<\/strong> == \"__main__\":<\/code>\u00a0\u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0431\u0430\u0437\u0443, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0445\u0435\u043c\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043a\u0430\u0436\u0434\u044b\u0435 5 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u00a0<code>check_new_deals()<\/code>.<\/p>\n<pre><code class=\"python\">if __name__ == \"__main__\":     UPDATE_OFFSET = None     initialize_database()     update_database_schema()     print(\"\u0421\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u043f\u0443\u0449\u0435\u043d. \u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u0434\u0435\u043b\u043e\u043a \u0438 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u043e\u043b\u0435\u0439...\")     while True:         check_new_deals()         time.sleep(5)  <\/code><\/pre>\n<ul>\n<li>\n<p><strong>initialize_database()<\/strong>\u00a0\u0438\u00a0<strong>update_database_schema()<\/strong>\u00a0\u0433\u043e\u0442\u043e\u0432\u044f\u0442 \u043d\u0430\u0448\u0443 \u0411\u0414.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u044b\u0435 5 \u0441\u0435\u043a\u0443\u043d\u0434 (\u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b) \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u00a0<strong>check_new_deals()<\/strong>\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 amoCRM, \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0443 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0438 \u043f\u0440.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0448 \u043a\u043e\u0434 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u043d, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a\u00a0<strong>\u0434\u0435\u043f\u043b\u043e\u044e<\/strong>\u00a0\u043d\u0430 Amvera \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0431\u043e\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0430\u0439\u0442 Amvera \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u00ab\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00bb. \u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u00ab\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00bb \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u00bb, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d. \u041d\u0430 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0442\u0430\u0440\u0438\u0444, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u0430 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0442\u0430\u0440\u0438\u0444 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u2014 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e:<\/p>\n<ol>\n<li>\n<p><a href=\"http:\/\/main.py\" rel=\"noopener noreferrer nofollow\"><strong>main.py<\/strong><\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0431\u043e\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>requirements.txt<\/strong>, \u0444\u0430\u0439\u043b \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0415\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<\/li>\n<\/ol>\n<pre><code>psycopg2~=2.9.10   requests~=2.32.3   schedule~=1.2.2<\/code><\/pre>\n<p>3. <strong>amvera.yaml <\/strong>\u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0414\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043b\u0443\u0447\u0448\u0435 \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Amvera \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<pre><code>version: null meta:   environment: python   toolchain:     name: pip     version: 3.11 build:   requirementsPath: requirements.txt run:   scriptName: main.py   persistenceMount: \/data   containerPort: 80   servicePort: 80<\/code><\/pre>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Amvera, \u0432\u044b\u0431\u0440\u0430\u0432 \u043d\u0443\u0436\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435, \u043b\u0438\u0431\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439 Git.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430 Amvera \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u041a\u043e\u0433\u0434\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0443\u043a\u0430\u0436\u0438\u0442\u0435\u00a0<strong>Python<\/strong>, \u0430 \u0437\u0430\u0442\u0435\u043c, \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 \u00ab\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00bb, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435\u00a0<strong>pip<\/strong>. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u00bb, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e Amvera \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0437 \u0432\u0430\u0448\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430\u00a0<code>requirements.txt<\/code>\u00a0\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0431\u043e\u0442\u043e\u043c.<\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u0442 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 \u00ab\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e\u00bb, \u0431\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432 \u043a \u0440\u0430\u0431\u043e\u0442\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043e\u0442\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<code>\/start<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430\u0441 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 amoCRM \u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u0434\u0435\u043b\u043a\u0443.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e72\/768\/1f7\/e727681f799be6aa369acc2c8805cb3b.png\" width=\"788\" height=\"814\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e72\/768\/1f7\/e727681f799be6aa369acc2c8805cb3b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e72\/768\/1f7\/e727681f799be6aa369acc2c8805cb3b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 Telegram \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0440\u0430\u0442\u043a\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0434\u0435\u043b\u043a\u0435<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/430\/3d7\/06d\/4303d706d609eb5996e3ac590d6155b9.png\" width=\"2218\" height=\"234\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/430\/3d7\/06d\/4303d706d609eb5996e3ac590d6155b9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/430\/3d7\/06d\/4303d706d609eb5996e3ac590d6155b9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 (\u0438\u043b\u0438 \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u043e\u0439 \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e) \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u043e\u0442\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<code>\/sales<\/code>, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043b \u043d\u0430\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0440\u043e\u043b\u044c. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043d\u043e\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0434\u0435\u043b\u043a\u0443 \u0432 amoCRM. \u0412 Telegram \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/08e\/388\/b7b\/08e388b7bf8727473935dddc27dcc7b4.png\" width=\"2280\" height=\"314\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/08e\/388\/b7b\/08e388b7bf8727473935dddc27dcc7b4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/08e\/388\/b7b\/08e388b7bf8727473935dddc27dcc7b4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p> \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0441\u0434\u0435\u043b\u043a\u0443 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0430\u0434\u0438\u044e \u0432 amoCRM.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/963\/65e\/fbd\/96365efbd988cea105963d63b93947e2.png\" width=\"1370\" height=\"708\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/963\/65e\/fbd\/96365efbd988cea105963d63b93947e2.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/963\/65e\/fbd\/96365efbd988cea105963d63b93947e2.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0431\u043e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u0441\u043c\u0435\u043d\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/220\/142\/c47\/220142c473766e5fd1e279d371d7abbd.png\" width=\"808\" height=\"298\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/220\/142\/c47\/220142c473766e5fd1e279d371d7abbd.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/220\/142\/c47\/220142c473766e5fd1e279d371d7abbd.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0441\u0434\u0435\u043b\u043a\u0443, \u0431\u0443\u0434\u0443\u0447\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c (\u0442.\u0435. \u0432\u0432\u043e\u0434\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<code>\/admin<\/code>). \u0422\u0435\u043f\u0435\u0440\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0432 \u0431\u043e\u0442\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0434\u0435\u043b\u043a\u0435.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d23\/913\/d78\/d23913d7861b83b37425c48847ef8dab.png\" width=\"2272\" height=\"366\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d23\/913\/d78\/d23913d7861b83b37425c48847ef8dab.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d23\/913\/d78\/d23913d7861b83b37425c48847ef8dab.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0418\u0442\u043e\u0433\u043e \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<ul>\n<li>\n<p>main.py &#8212; \u043a\u043e\u0434 \u0431\u043e\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>amvera.yaml &#8212; \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>requirements.txt &#8212; \u0444\u0430\u0439\u043b \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u0441\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041d\u0430 \u044d\u0442\u043e\u043c \u043d\u0430\u0448\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u043d\u0430\u0434 \u0431\u043e\u0442\u043e\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. <\/strong><\/p>\n<p>\u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u043e\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0441 amoCRM \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0435\u0433\u043e \u043d\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 <a href=\"https:\/\/amvera.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=amo\" rel=\"noopener noreferrer nofollow\">Amvera<\/a>. <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/Alpetpon\/Amvera_articles\/tree\/main\/Service\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/918816\/\"> https:\/\/habr.com\/ru\/articles\/918816\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e Telegram-\u0431\u043e\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 amoCRM \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0432 CRM, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 \u0442\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u0445 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u044f\u043c: \u043e\u0442\u0434\u0435\u043b \u043f\u0440\u043e\u0434\u0430\u0436 \u0432\u0438\u0434\u0438\u0442 \u0441\u0443\u043c\u043c\u0443 \u0441\u0434\u0435\u043b\u043a\u0438 \u0438 \u0441\u0442\u0430\u0434\u0438\u044e, \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u2013 \u043a\u0440\u0430\u0442\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043d\u043e\u0432\u043e\u0439 \u0441\u0434\u0435\u043b\u043a\u0435. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u043d\u043e\u0432\u044b\u0435 \u043b\u0438\u0434\u044b, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0437\u0430 \u0441\u0434\u0435\u043b\u043a\u0430\u043c\u0438 \u0438 \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 CRM-\u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<p>\u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0411\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 PostgreSQL \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0431\u043e\u0442\u0430.<\/p>\n<p>\u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043c\u044b \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u043c \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 Amvera, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u0430\u0441\u0442 \u043d\u0430\u043c<\/p>\n<ul>\n<li>\n<p>\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 PostgreSQL \u0441 \u0431\u044d\u043a\u0430\u043f\u0430\u043c\u0438, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u043c \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 IDE, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f git push (\u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0438\u0432\u0430\u044f \u0444\u0430\u0439\u043b\u044b \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435), \u0447\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043c\u043e\u0431\u0430\u043b\u0430\u043d\u0441 \u0432 111 \u0440\u0443\u0431. \u0434\u043b\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u2013 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. <\/strong><\/p>\n<p>\u0417\u0430\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0441\u0430\u0439\u0442 <a href=\"https:\/\/amvera.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=amo\" rel=\"noopener noreferrer nofollow\">Amvera<\/a>, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 PostgreSQL \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0443\u043a\u0430\u0437\u0430\u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u0431\u0440\u0430\u0432 \u0442\u0430\u0440\u0438\u0444\u043d\u044b\u0439 \u043f\u043b\u0430\u043d.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0442\u0430\u0440\u0438\u0444. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>\u0417\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u0438 \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0411\u0414 \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u00ab\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u00bb \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u043e\u0442\u0430. \u0415\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2013 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 amoCRM \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 Telegram.<\/p>\n<p>\u0411\u043e\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \/start, \/sales \u0438\u043b\u0438 \/admin, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0440\u043e\u043b\u044c.  \u0411\u043e\u0442 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 amoCRM \u0447\u0435\u0440\u0435\u0437 API, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u043e\u0432\u044b\u0445 \u0441\u0434\u0435\u043b\u043e\u043a. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u043e\u0442 \u0440\u0430\u0441\u0441\u044b\u043b\u0430\u0435\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u043c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044f \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0438\u0445 \u0440\u043e\u043b\u0438.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u043e\u0442 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0438 \u0441 amoCRM, \u043d\u0438 \u0441 Telegram.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<strong>Telegram Bot Token<\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/p>\n<ol>\n<li>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0432 Telegram \u0431\u043e\u0442\u0430\u00a0<a href=\"https:\/\/telegram.me\/BotFather\" rel=\"noopener noreferrer nofollow\">BotFather<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u043c\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<code>\/start<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c\u00a0<code>\/newbot<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c: \u0432\u0432\u0435\u0441\u0442\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u00abusername\u00bb \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u043e\u0442\u0430 (username \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u00a0<code>bot<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>mycompany_sales_bot<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e BotFather \u0432\u044b\u0448\u043b\u0435\u0442 \u0432\u0430\u043c \u0442\u043e\u043a\u0435\u043d<\/p>\n<\/li>\n<\/ol>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f amoCRM \u0438 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u0431\u043e\u0442\u0430<\/h2>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0443\u0436\u0435\u043d\u00a0<strong>Access Token \u0434\u043b\u044f amoCRM<\/strong>. \u042d\u0442\u043e\u0442 \u0442\u043e\u043a\u0435\u043d \u0434\u0430\u0451\u0442 \u0431\u043e\u0442\u0443 \u043f\u0440\u0430\u0432\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a API amoCRM \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430. \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043d\u043e \u043e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0432\u0430:<\/p>\n<ol>\n<li>\n<p><strong>\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e<\/strong>: \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 amo\u041c\u0410\u0420\u041a\u0415\u0422, \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0442\u0440\u0438 \u0442\u043e\u0447\u043a\u0438 \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443 \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e\u00bb, \u00ab\u0412\u043d\u0435\u0448\u043d\u044f\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u00bb. \u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb.<\/p>\n<\/li>\n<li>\n<p><strong>\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0439\u0442\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e<\/strong>: \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0440\u0430\u0437\u0434\u0435\u043b \u00ab\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435\u00bb \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d<\/strong>\u00a0(Access Token). \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u043e\u043a\u0435\u043d \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0433 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b amoCRM, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u043a\u0438. \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e\u00a0<code>ACCESS_TOKEN<\/code>\u00a0\u0432 \u0432\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u0432\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0434\u0432\u0430 \u0442\u043e\u043a\u0435\u043d\u0430:<\/p>\n<ul>\n<li>\n<p><code><strong>TELEGRAM_BOT_TOKEN<\/strong><\/code>\u00a0\u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u044b\u0434\u0430\u043d\u043d\u0430\u044f BotFather, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Telegram API.<\/p>\n<\/li>\n<li>\n<p><code><strong>ACCESS_TOKEN<\/strong><\/code>\u00a0\u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0434\u0430\u044e\u0449\u0430\u044f \u043f\u0440\u0430\u0432\u043e \u0431\u043e\u0442\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b API amoCRM<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0431\u043e\u0442\u0430.<br \/>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442. \u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ul>\n<li>\n<p><strong>requests<\/strong>\u00a0\u2013 \u0434\u043b\u044f HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (Telegram, amoCRM).<\/p>\n<\/li>\n<li>\n<p><strong>psycopg2<\/strong>\u00a0\u2013 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL.<\/p>\n<\/li>\n<li>\n<p><strong>time, datetime<\/strong>\u00a0\u2013 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u0442. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0443\u043a\u0430\u0436\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: \u0434\u043e\u043c\u0435\u043d amoCRM, \u0442\u043e\u043a\u0435\u043d\u044b amoCRM \u0438 Telegram, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">import requests import time import psycopg2 from datetime import datetime  # \u0414\u043e\u043c\u0435\u043d \u0432\u0430\u0448\u0435\u0439 amoCRM AMOCRM_DOMAIN = 'name.amocrm.ru'  # \u0422\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API amoCRM ACCESS_TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGc...' #\u0412\u0430\u0436\u043d\u043e, \u0442\u043e\u043a\u0435\u043d\u044b \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u0434\u0430\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438  # Telegram Bot Token, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0443 BotFather TELEGRAM_BOT_TOKEN = '8072282519:AA...'  # \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a PostgreSQL (DB_CONFIG) DB_CONFIG = {     'dbname': 'DB_name',     'user': 'User_Name',     'password': 'Password',     'host': 'HOST',     'port': 5432 } <\/code><\/pre>\n<p>\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043e\u043c\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/docs.amvera.ru\/databases\/postgreSQL.html\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0430\u0442\u0446\u0438\u0438<\/a> Amvera<\/p>\n<p>\u0412\u044b\u0434\u0435\u043b\u0438\u043c \u0434\u0432\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u2014\u00a0<strong>UPDATE_OFFSET<\/strong>\u00a0\u0438\u00a0<strong>STAGE_MAPPING<\/strong>.<\/p>\n<p><strong>UPDATE_OFFSET<\/strong>\u00a0\u0445\u0440\u0430\u043d\u0438\u0442 ID \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 Telegram. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u043d\u0435 \u0447\u0438\u0442\u0430\u043b \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437.<br \/><strong>STAGE_MAPPING<\/strong>\u00a0\u0437\u0430\u0434\u0430\u0451\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 ID \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0432 amoCRM \u0438 \u0438\u0445 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c. \u041a\u043e\u0433\u0434\u0430 \u0441\u0434\u0435\u043b\u043a\u0430 \u0438\u043c\u0435\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440,\u00a0<code>status_id = 74340918<\/code>, \u0431\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u00ab\u041f\u0435\u0440\u0435\u0433\u043e\u0432\u043e\u0440\u044b\u00bb, \u0430 \u043d\u0435 \u043d\u0430\u0431\u043e\u0440 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<pre><code class=\"python\">UPDATE_OFFSET = None  STAGE_MAPPING = {     74340914: \"\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0440\u0430\u043a\u0442\",     74340918: \"\u041f\u0435\u0440\u0435\u0433\u043e\u0432\u043e\u0440\u044b\",     74340922: \"\u041e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u044f\",     74340926: \"\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430\" }  <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u0445\u0435\u043c\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043d\u0435\u0439 \u0431\u0443\u0434\u0443\u0442 \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<ul>\n<li>\n<p><strong>deals<\/strong>\u00a0\u2013 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0434\u0435\u043b\u043a\u0438 \u0438\u0437 amoCRM (\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0441\u0443\u043c\u043c\u0430, \u0434\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0441\u0442\u0430\u0442\u0443\u0441 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0438 \u0441\u0442\u0430\u0434\u0438\u044f).<\/p>\n<\/li>\n<li>\n<p><strong>users<\/strong>\u00a0\u2013 \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u0431\u043e\u0442\u0430: \u0438\u0445 chat_id \u0432 Telegram \u0438 \u0440\u043e\u043b\u044c (user, sales, admin).<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">def initialize_database():     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"\"\"         CREATE TABLE IF NOT EXISTS deals (             id SERIAL PRIMARY KEY,             deal_id INTEGER UNIQUE,             name TEXT,             price NUMERIC,             created_at TIMESTAMP,             notified BOOLEAN DEFAULT false         );         \"\"\")         cur.execute(\"\"\"         CREATE TABLE IF NOT EXISTS users (             id SERIAL PRIMARY KEY,             chat_id BIGINT UNIQUE,             role TEXT DEFAULT 'user'         );         \"\"\")         conn.commit()         cur.close()         conn.close()         print(\"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445:\", e)  <\/code><\/pre>\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0442\u0430\u0434\u0438\u044e \u0441\u0434\u0435\u043b\u043a\u0438 (<code>stage<\/code>). \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443\u00a0<strong>deals<\/strong>, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442:<\/p>\n<pre><code class=\"python\">def update_database_schema():     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"ALTER TABLE deals ADD COLUMN IF NOT EXISTS stage TEXT;\")         conn.commit()         cur.close()         conn.close()         print(\"\u0421\u0445\u0435\u043c\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0445\u0435\u043c\u044b \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445:\", e)  <\/code><\/pre>\n<p>\u0411\u043e\u0442 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u00a0<code>\/start<\/code>,\u00a0<code>\/sales<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>\/admin<\/code>, \u043c\u044b \u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0440\u043e\u043b\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u00a0<strong>users<\/strong>.<br \/> \u0420\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043e\u0442\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u0445.<\/p>\n<pre><code class=\"python\">def update_user_role(chat_id, role):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         query = \"\"\"         INSERT INTO users (chat_id, role)         VALUES (%s, %s)         ON CONFLICT (chat_id) DO UPDATE SET role = EXCLUDED.role;         \"\"\"         cur.execute(query, (chat_id, role))         conn.commit()         cur.close()         conn.close()         print(f\"\u0420\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f {chat_id} \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 {role}.\")     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0440\u043e\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:\", e)  def add_user(chat_id):     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         query = \"INSERT INTO users (chat_id) VALUES (%s) ON CONFLICT (chat_id) DO NOTHING;\"         cur.execute(query, (chat_id,))         conn.commit()         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:\", e)  def get_all_users():     users = []     try:         conn = psycopg2.connect(**DB_CONFIG)         cur = conn.cursor()         cur.execute(\"SELECT chat_id, role FROM users;\")         rows = cur.fetchall()         for row in rows:             users.append({'chat_id': row[0], 'role': row[1]})         cur.close()         conn.close()     except Exception as e:         print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:\", e)     return users  <\/code><\/pre>\n<ul>\n<li>\n<p><strong>update_user_role<\/strong>\u00a0\u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0440\u043e\u043b\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>add_user<\/strong>\u00a0\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0440\u043e\u043b\u044c\u044e \u00abuser\u00bb \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p><strong>get_all_users<\/strong>\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u0440\u043e\u043b\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u043c\u043e\u0433 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u00a0<code>getUpdates<\/code>\u00a0\u0443 Telegram. \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0445, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438\u043b\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0431\u043e\u0442\u0430.<\/p>\n<pre><code class=\"python\">def update_chat_ids():     global UPDATE_OFFSET     url = f\"https:\/\/api.telegram.org\/bot{TELEGRAM_BOT_TOKEN}\/getUpdates\"     params = {}     if UPDATE_OFFSET is not None:         params['offset'] = UPDATE_OFFSET + 1      try:         response = requests.get(url, params=params, timeout=10)         data = response.json()         updates = data.get(\"result\", [])         if updates:             for update in updates:                 UPDATE_OFFSET = update.get(\"update_id\", UPDATE_OFFSET)                 message = update.get(\"message\", {})                 chat = message.get(\"chat\", {})                 text = message.get(\"text\", \"\").strip()                 chat_id = chat.get(\"id\")                  if chat_id:                     if text in [\"\/start\", \"\/sales\", \"\/admin\"]:                         if text == \"\/start\":                             role = \"user\"                         elif text == \"\/sales\":                             role = \"sales\"                         elif text == \"\/admin\":                             role = \"admin\"                         update_user_role(chat_id, role)                     else:          <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-465362","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/465362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=465362"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/465362\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=465362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=465362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=465362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}