From b7e2f1430736e165ec747a6f2353d8174366dc12 Mon Sep 17 00:00:00 2001
From: Temirkhan Myrzamadi <hirrolot@gmail.com>
Date: Sun, 28 Mar 2021 08:51:57 +0600
Subject: [PATCH 1/2] Automatically delete a webhook if it was set up

---
 CHANGELOG.md                            |  5 +++++
 src/dispatching/dispatcher.rs           |  2 +-
 src/dispatching/repls/commands_repl.rs  |  2 +-
 src/dispatching/repls/dialogues_repl.rs |  2 +-
 src/dispatching/repls/repl.rs           |  8 +++++--
 src/dispatching/update_listeners.rs     | 28 ++++++++++++++++++++++++-
 6 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4761c3d0..f53895ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [unreleased]
 
+### Changed
+
+ - Automatically delete a webhook if it was set up in `update_listeners::polling_default` (thereby making it `async`, [issue 319](https://github.com/teloxide/teloxide/issues/319)).
+
 ### Fixed
 
 - Remove `reqwest` dependency. It's not needed after the [teloxide-core] integration.
+
 ## [0.4.0] - 2021-03-22
 
 ### Added
diff --git a/src/dispatching/dispatcher.rs b/src/dispatching/dispatcher.rs
index e7635ebb..93bf8a7e 100644
--- a/src/dispatching/dispatcher.rs
+++ b/src/dispatching/dispatcher.rs
@@ -233,7 +233,7 @@ where
         <R as Requester>::GetUpdatesFaultTolerant: Send,
     {
         self.dispatch_with_listener(
-            update_listeners::polling_default(self.requester.clone()),
+            update_listeners::polling_default(self.requester.clone()).await,
             LoggingErrorHandler::with_custom_text("An error from the update listener"),
         )
         .await;
diff --git a/src/dispatching/repls/commands_repl.rs b/src/dispatching/repls/commands_repl.rs
index 249d4861..88a7c33d 100644
--- a/src/dispatching/repls/commands_repl.rs
+++ b/src/dispatching/repls/commands_repl.rs
@@ -39,7 +39,7 @@ where
         requester,
         bot_name,
         handler,
-        update_listeners::polling_default(cloned_requester),
+        update_listeners::polling_default(cloned_requester).await,
     )
     .await;
 }
diff --git a/src/dispatching/repls/dialogues_repl.rs b/src/dispatching/repls/dialogues_repl.rs
index 706d26a1..1863af8b 100644
--- a/src/dispatching/repls/dialogues_repl.rs
+++ b/src/dispatching/repls/dialogues_repl.rs
@@ -36,7 +36,7 @@ where
     dialogues_repl_with_listener(
         requester,
         handler,
-        update_listeners::polling_default(cloned_requester),
+        update_listeners::polling_default(cloned_requester).await,
     )
     .await;
 }
diff --git a/src/dispatching/repls/repl.rs b/src/dispatching/repls/repl.rs
index 31075f60..3c498696 100644
--- a/src/dispatching/repls/repl.rs
+++ b/src/dispatching/repls/repl.rs
@@ -31,8 +31,12 @@ where
     <R as Requester>::GetUpdatesFaultTolerant: Send,
 {
     let cloned_requester = requester.clone();
-    repl_with_listener(requester, handler, update_listeners::polling_default(cloned_requester))
-        .await;
+    repl_with_listener(
+        requester,
+        handler,
+        update_listeners::polling_default(cloned_requester).await,
+    )
+    .await;
 }
 
 /// Like [`repl`], but with a custom [`UpdateListener`].
diff --git a/src/dispatching/update_listeners.rs b/src/dispatching/update_listeners.rs
index a3ec5097..bdece104 100644
--- a/src/dispatching/update_listeners.rs
+++ b/src/dispatching/update_listeners.rs
@@ -120,11 +120,16 @@ impl<S, E> UpdateListener<E> for S where S: Stream<Item = Result<Update, E>> {}
 /// Returns a long polling update listener with `timeout` of 10 seconds.
 ///
 /// See also: [`polling`](polling).
-pub fn polling_default<R>(requester: R) -> impl UpdateListener<R::Err>
+///
+/// ## Notes
+///
+/// This function will automatically delete a webhook if it was set up.
+pub async fn polling_default<R>(requester: R) -> impl UpdateListener<R::Err>
 where
     R: Requester,
     <R as Requester>::GetUpdatesFaultTolerant: Send,
 {
+    delete_webhook_if_setup(&requester).await;
     polling(requester, Some(Duration::from_secs(10)), None, None)
 }
 
@@ -200,3 +205,24 @@ where
     )
     .flatten()
 }
+
+async fn delete_webhook_if_setup<R>(requester: &R)
+where
+    R: Requester,
+{
+    let webhook_info = match requester.get_webhook_info().send().await {
+        Ok(ok) => ok,
+        Err(e) => {
+            log::error!("Failed to get webhook info: {:?}", e);
+            return;
+        }
+    };
+
+    let is_webhook_setup = !webhook_info.url.is_empty();
+
+    if is_webhook_setup {
+        if let Err(e) = requester.delete_webhook().send().await {
+            log::error!("Failed to delete a webhook: {:?}", e);
+        }
+    }
+}

From 5affdf1759e1860a109d63069e5f50a1137bdc0c Mon Sep 17 00:00:00 2001
From: Hirrolot <hirrolot@gmail.com>
Date: Sun, 28 Mar 2021 09:00:36 +0600
Subject: [PATCH 2/2] Enforce writing log::<op>!(...) in CODE_STYLE.md

---
 CODE_STYLE.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CODE_STYLE.md b/CODE_STYLE.md
index 964aea8c..0fa0756b 100644
--- a/CODE_STYLE.md
+++ b/CODE_STYLE.md
@@ -124,3 +124,4 @@ C: Into<String>, { ... }
  1. Use `Into<...>` only where there exists at least one conversion **and** it will be logically to use.
  2. Always mark a function as `#[must_use]` if its return value **must** be used.
  3. `Box::pin(async [move] { ... })` instead of `async [move] { ... }.boxed()`.
+ 4. Always write `log::<op>!(...)` instead of importing `use log::<op>;` and invoking `<op>!(...)`. For example, write `log::info!("blah")`.