<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aurelia Specker</title>
    <description>The latest articles on DEV Community by Aurelia Specker (@aureliaspecker).</description>
    <link>https://dev.to/aureliaspecker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F132620%2F9796e1dd-15c9-44b7-90a3-bf1174d79935.jpg</url>
      <title>DEV Community: Aurelia Specker</title>
      <link>https://dev.to/aureliaspecker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aureliaspecker"/>
    <language>en</language>
    <item>
      <title>Retrieve a list of user mentions from a thread of Tweet replies</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Tue, 25 Jan 2022 17:10:07 +0000</pubDate>
      <link>https://dev.to/xdevs/retrieve-a-list-of-user-mentions-from-a-thread-of-tweet-replies-4ib6</link>
      <guid>https://dev.to/xdevs/retrieve-a-list-of-user-mentions-from-a-thread-of-tweet-replies-4ib6</guid>
      <description>&lt;p&gt;&lt;em&gt;The code for this tutorial is available on &lt;a href="https://github.com/twitterdev/extract-usernames-from-tweet-replies" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have you ever wanted a quick way to retrieve all usernames mentioned in a thread of &lt;a href="https://help.twitter.com/en/using-twitter/mentions-and-replies" rel="noopener noreferrer"&gt;replies&lt;/a&gt; on Twitter? This &lt;a href="https://github.com/twitterdev/extract-usernames-from-tweet-replies" rel="noopener noreferrer"&gt;Python script&lt;/a&gt; does just that using the Twitter API.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Set up
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clone the repository &lt;a href="https://github.com/twitterdev/extract-usernames-from-tweet-replies" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure you have a Twitter developer account with access to &lt;a href="https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all" rel="noopener noreferrer"&gt;GET /2/tweets/search/all&lt;/a&gt;. If you don't have access to this endpoint, follow the instructions below to use the recent search endpoint instead. More information on getting access to the API is available &lt;a href="https://developer.twitter.com/en/docs/twitter-api/getting-started/getting-access-to-the-twitter-api" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the root directory, rename &lt;code&gt;.env_example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; and add the credentials for your developer App in between the &lt;code&gt;""&lt;/code&gt;. Remember to add &lt;code&gt;.env&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; file to keep your credentials secure.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Running the code
&lt;/h2&gt;

&lt;p&gt;Use the following command to run the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 replies.py -t &amp;lt;TWEET-ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following flags are available to use:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flags&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tweet ID&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;td&gt;ID of the Tweet for which you want to pull data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-h&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Help&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;View a list of available flags and a description for each of these.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start time&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;The oldest UTC timestamp from which the replies will be provided. Format: YYYY-MM-DDTHH:mm:ssZ; for example: 2021-12-04T01:30:00Z. If unspecified, will default to returning replies from up to 30 days ago.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;End time&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;The newest, most recent UTC timestamp to which the replies will be provided. Format: YYYY-MM-DDTHH:mm:ssZ; for example: 2021-12-04T01:30:00Z. If unspecified, will default to [now - 30 seconds].&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Returned in the command life interface
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ordered dictionary containing a list of all usernames present in the replies and the number of times each username was mentioned. Note: the user who authored the original Tweet is not included.&lt;/li&gt;
&lt;li&gt;Number of replies to the Tweet.&lt;/li&gt;
&lt;li&gt;Number of usernames mentioned in these replies.&lt;/li&gt;
&lt;li&gt;Number of requests made to the Search Tweets endpoint to pull all replies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Returned in a new file
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A new file, &lt;code&gt;replies.txt&lt;/code&gt;, will be created. This file will contain a list of Tweet IDs for the replies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What if I don't have access to Twitter's full-archive search endpoint?
&lt;/h2&gt;

&lt;p&gt;If you only have access to the recent search endpoint, you can still use this script. Simply make the following two modifications to &lt;code&gt;replies.py&lt;/code&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On line 63, change the endpoint to:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;search_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twitter.com/2/tweets/search/recent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;On line 49, make sure the &lt;code&gt;max_results&lt;/code&gt; parameter is set to:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When you run the code, if you specify a start time and/or end time using the &lt;code&gt;-s&lt;/code&gt; and &lt;code&gt;-e&lt;/code&gt; flags, these must be within the last seven days, otherwise you will get back a &lt;code&gt;400 Bad Request&lt;/code&gt; error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more about Search Tweets and the difference between the recent search and full-archive search endpoints here: &lt;a href="https://developer.twitter.com/en/docs/twitter-api/tweets/search/introduction" rel="noopener noreferrer"&gt;https://developer.twitter.com/en/docs/twitter-api/tweets/search/introduction&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case examples
&lt;/h2&gt;

&lt;p&gt;The above can be helpful in the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You've asked a question on Twitter and want to quickly retrieve a list of all accounts mentioned in the replies. &lt;/li&gt;
&lt;li&gt;Identify a list of influencers, as mentioned in a conversation thread.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>twitter</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Migrate to Twitter’s newly released Labs recent search endpoint</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Tue, 04 Feb 2020 14:51:24 +0000</pubDate>
      <link>https://dev.to/xdevs/migrate-to-twitter-s-newly-released-labs-recent-search-endpoint-3npe</link>
      <guid>https://dev.to/xdevs/migrate-to-twitter-s-newly-released-labs-recent-search-endpoint-3npe</guid>
      <description>&lt;p&gt;In January, Twitter &lt;a href="https://twittercommunity.com/t/new-recent-search-endpoint-available-in-labs/133076" rel="noopener noreferrer"&gt;announced&lt;/a&gt; the launch of a new search endpoint. This endpoint is available in &lt;a href="https://developer.twitter.com/en/labs" rel="noopener noreferrer"&gt;Twitter Developer Labs&lt;/a&gt; and is meant to preview what the Tweet search endpoints will look like in the future.&lt;/p&gt;

&lt;p&gt;The framework of the Labs recent search endpoint is very similar to how Twitter will eventually structure other historical search endpoints available in the next generation of the Twitter API. This search endpoint returns the same, new, and modernized version of Tweet and user JSON objects as other endpoints available in &lt;a href="https://developer.twitter.com/en/labs" rel="noopener noreferrer"&gt;Twitter Developer Labs&lt;/a&gt;. It also includes &lt;a href="https://developer.twitter.com/en/docs/labs/overview/whats-new/expansions" rel="noopener noreferrer"&gt;expansions&lt;/a&gt; and selectable response &lt;a href="https://developer.twitter.com/en/docs/labs/overview/whats-new/formats" rel="noopener noreferrer"&gt;formats&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In an attempt to test this new endpoint, I refactored my London commute app and replaced the &lt;a href="https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search" rel="noopener noreferrer"&gt;Premium 30-Day Search API&lt;/a&gt; with the new &lt;a href="https://developer.twitter.com/en/docs/labs/recent-search/overview" rel="noopener noreferrer"&gt;Labs search endpoint&lt;/a&gt;. This article highlights the migration changes required to do this. &lt;strong&gt;Please refer to the &lt;a href="https://dev.to/twitterdev/using-the-twitter-api-to-make-your-commute-easier-3od0"&gt;original blog post&lt;/a&gt; that walks you through the steps required to build the initial London commute app when reading this migration article.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can find the refactored code that uses the new endpoint on &lt;a href="https://github.com/aureliaspecker/met-line-alerts/tree/labs-1-tweets-search" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. Make sure to select the &lt;a href="https://github.com/aureliaspecker/met-line-alerts/tree/labs-1-tweets-search" rel="noopener noreferrer"&gt;labs-1-tweets-search branch&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can find the original code using the &lt;a href="https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search" rel="noopener noreferrer"&gt;Premium 30-Day Search API&lt;/a&gt; on &lt;a href="https://github.com/aureliaspecker/met-line-alerts" rel="noopener noreferrer"&gt;GitHub on the master branch&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A full comparison of the changes required to migrate from using the Premium 30-Day Search API to using the new Labs search endpoint can be found on &lt;a href="https://github.com/aureliaspecker/met-line-alerts/compare/labs-1-tweets-search" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;If you already have code written for the standard, premium, or enterprise versions of the &lt;a href="https://developer.twitter.com/en/docs/tweets/search/overview" rel="noopener noreferrer"&gt;Search API&lt;/a&gt;, you can also check out the &lt;a href="https://developer.twitter.com/en/docs/labs/recent-search/compare" rel="noopener noreferrer"&gt;"Compare" section&lt;/a&gt; of the Twitter developer docs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Set up
&lt;/h1&gt;

&lt;p&gt;Follow these steps to gain access to the new Labs search endpoint: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Head over to the &lt;a href="https://developer.twitter.com/en/account/labs" rel="noopener noreferrer"&gt;Labs section&lt;/a&gt; of the Twitter developer portal and click "Join Labs"&lt;/li&gt;
&lt;li&gt;Select "Activate" next to Recent search, then select a &lt;a href="https://developer.twitter.com/en/apps" rel="noopener noreferrer"&gt;Twitter developer app&lt;/a&gt; (your app should be linked to the Twitter account of the notification sender, &lt;a href="https://dev.to/twitterdev/using-the-twitter-api-to-make-your-commute-easier-3od0"&gt;in this example&lt;/a&gt; the Twitter account &lt;a href="https://twitter.com/maddie_testing" rel="noopener noreferrer"&gt;@maddie_testing&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/twitterdev/using-the-twitter-api-to-make-your-commute-easier-3od0"&gt;previous version&lt;/a&gt; of this app, we use the Python wrapper &lt;a href="https://github.com/twitterdev/search-tweets-python" rel="noopener noreferrer"&gt;searchtweets&lt;/a&gt; to access the premium search API. We no longer require this. Remove the following lines from &lt;code&gt;alerts.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;searchtweets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ResultStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gen_rule_payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collect_results&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, insert the following lines at the top of &lt;code&gt;alerts.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests.auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AuthBase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new version looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests_oauthlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OAuth1Session&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests.auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AuthBase&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Handling credentials
&lt;/h1&gt;

&lt;p&gt;Open your &lt;code&gt;credentials.yaml&lt;/code&gt; file and replace the previous version of your credentials with the new one: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Previous version&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;search_tweets_api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;account_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;premium&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.twitter.com/1.1/tweets/search/30day/{ENV}.json&lt;/span&gt;
    &lt;span class="na"&gt;consumer_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;consumer_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;access_token_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;New version&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;labs_search_tweets_api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;consumer_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;consumer_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
    &lt;span class="na"&gt;access_token_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXXX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;consumer_key&lt;/code&gt; and &lt;code&gt;consumer_secret&lt;/code&gt; will be used to generate a &lt;code&gt;bearer_token&lt;/code&gt; to access the &lt;a href="https://developer.twitter.com/en/docs/labs/recent-search/overview" rel="noopener noreferrer"&gt;Labs search endpoint&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;consumer_key&lt;/code&gt;, &lt;code&gt;consumer_secret&lt;/code&gt;, &lt;code&gt;access_token&lt;/code&gt;, and &lt;code&gt;access_token_secret&lt;/code&gt; are required to access the &lt;a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update" rel="noopener noreferrer"&gt;POST statuses/update endpoint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Remember to always add the &lt;code&gt;credentials.yaml&lt;/code&gt; file to your &lt;code&gt;.gitignore&lt;/code&gt; file, to avoid accidentally pushing your private credentials to GitHub.&lt;/p&gt;

&lt;h1&gt;
  
  
  Handling authentication
&lt;/h1&gt;

&lt;p&gt;In &lt;code&gt;alerts.py&lt;/code&gt;, remove the following lines of code that refer to the Python wrapper &lt;a href="https://github.com/twitterdev/search-tweets-python" rel="noopener noreferrer"&gt;searchtweets&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./credentials.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;yaml_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;env_overwrite&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to replace the four references to "search_tweets_api" with "labs_search_tweets_api" to reflect the changes made in your &lt;code&gt;credentials.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Keep the section that uses &lt;a href="https://requests-oauthlib.readthedocs.io/en/latest/oauth1_workflow.html" rel="noopener noreferrer"&gt;OAuth1Session&lt;/a&gt; to manage credentials for the &lt;a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update" rel="noopener noreferrer"&gt;POST statuses/update endpoint&lt;/a&gt; (as described in the &lt;a href="https://dev.to/twitterdev/using-the-twitter-api-to-make-your-commute-easier-3od0"&gt;original blog post&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In order to authenticate with the Labs search endpoint, we will use &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/oauth-2-0/application-only" rel="noopener noreferrer"&gt;OAuth 2.0 Bearer Token authentication&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is what the authentication section of your code should look like in this newer version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Authentication
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./credentials.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;consumer_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;labs_search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consumer_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;consumer_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;labs_search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consumer_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;labs_search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;access_token_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;labs_search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;oauth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OAuth1Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;consumer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;consumer_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;resource_owner_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;resource_owner_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;access_token_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Generate bearer token with consumer key and consumer secret via https://api.twitter.com/oauth2/token
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BearerTokenAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthBase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumer_secret&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bearer_token_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twitter.com/oauth2/token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumer_key&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumer_secret&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bearer_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_bearer_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_bearer_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bearer_token_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumer_secret&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grant_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_credentials&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LabsMetTutorialPython&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cannot get a Bearer token (HTTP %d): %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bearer_token&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LabsMetTutorialPython&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="c1"&gt;# Create Bearer Token for authenticating
&lt;/span&gt;&lt;span class="n"&gt;bearer_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BearerTokenAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumer_secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Request parameters
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Timestamps
&lt;/h3&gt;

&lt;p&gt;The new Labs search endpoint offers two optional &lt;a href="https://developer.twitter.com/en/docs/labs/recent-search/api-reference/get-recent-search-v1" rel="noopener noreferrer"&gt;timestamp parameters&lt;/a&gt; (&lt;code&gt;start_time&lt;/code&gt; and &lt;code&gt;end_time&lt;/code&gt;) in the ISO 8601/RFC 3339 date format: YYYY-MM-DDTHH:mm:ssZ &lt;/p&gt;

&lt;p&gt;As this format is different to the format required with the Premium Search API, you will have to edit the output format of &lt;code&gt;datetime&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Generate start_time and end_time parameters
&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;utc_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%dT%H:%M:%SZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_time:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;two_hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;two_hours_prior&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;two_hours&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%dT%H:%M:%SZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;two_hours_prior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Generating a query
&lt;/h1&gt;

&lt;p&gt;As we’re no longer using the &lt;a href="https://github.com/twitterdev/search-tweets-python" rel="noopener noreferrer"&gt;searchtweets Python wrapper&lt;/a&gt;, we can delete the following lines of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;gen_rule_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from:metline -has:mentions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;from_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;two_hours_prior&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;to_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;results_per_call&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rule:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tweets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collect_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;result_stream_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at_datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, we’re going to use the &lt;a href="https://docs.python.org/3/library/urllib.html" rel="noopener noreferrer"&gt;Python library urllibe&lt;/a&gt; to encode non-ASCII text and make the parameters safe for use as a URL component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Generate query and other parameters
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from:metline -has:mentions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;two_hours_prior&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tweet_format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;compact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the use of &lt;a href="https://realpython.com/python-f-strings/" rel="noopener noreferrer"&gt;Python 3’s f-Strings formatting syntax&lt;/a&gt; to pass in the timestamp variables. We are going to use this syntax for all instances of string formatting in this version of the tutorial.&lt;/p&gt;

&lt;p&gt;The request URL is generated by appending the different encoded parameters to the endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Request URL
&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twitter.com/labs/1/tweets/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;?query=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;start_time=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;end_time=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;format=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tweet_format&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define headers. This tells your client that it is able to parse gzip requests and decompress them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Request headers
&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gzip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Getting a response
&lt;/h1&gt;

&lt;p&gt;Store the response in a variable called &lt;code&gt;response&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bearer_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request returned an error:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then convert the response to JSON. This will enable you to pull out the Tweet text and store it in a  new variable called &lt;code&gt;combined_tweet_text&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Convert response to JSON &amp;amp; pull out Tweet text
&lt;/span&gt;&lt;span class="n"&gt;parsed_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parsed_response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined_tweet_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete the previous version of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;tweet_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
   &lt;span class="n"&gt;tweet_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;tweet_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at_datetime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Analyse Tweets
&lt;/h1&gt;

&lt;p&gt;The Tweet analysis section that determines if the commuter has to be notified of a delay remains similar to the &lt;a href="https://dev.to/twitterdev/using-the-twitter-api-to-make-your-commute-easier-3od0"&gt;first version&lt;/a&gt; of this application. This is where you can input details specific to your use case.&lt;/p&gt;

&lt;p&gt;In order to provide greater flexibility, we can pull out the Twitter @handles of the commuters into two variables (&lt;code&gt;commuter_1&lt;/code&gt; and &lt;code&gt;commuter_2&lt;/code&gt;). However, this change is not mandatory.&lt;/p&gt;

&lt;p&gt;If a notification is required, we use the &lt;a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update" rel="noopener noreferrer"&gt;POST statuses/update endpoint&lt;/a&gt; to send a Tweet to the commuter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Analyse Tweets &amp;amp; notify commuter (details specific to use case)
&lt;/span&gt;&lt;span class="n"&gt;all_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;closure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wembley&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;delays&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;disruption&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cancelled&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sorry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stadium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;david_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hillingdon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;harrow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;aurelia_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;baker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;tweet_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined_tweet_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;commuter_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@AureliaSpecker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;commuter_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@dormrod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;commuter_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;commuter_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 👋 check https://twitter.com/metline for possible delays, [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;david_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;commuter_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 👋 check https://twitter.com/metline for possible delays, [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aurelia_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;commuter_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 👋 check https://twitter.com/metline for possible delays, [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;There are no delays&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Message:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;oauth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twitter.com/1.1/statuses/update.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I used several libraries and services beyond the Twitter API to make this tutorial, but you may have different needs and requirements and should evaluate whether those tools are right for you.&lt;/p&gt;

&lt;p&gt;Let us know if this inspires you to build anything on the &lt;a href="https://twittercommunity.com/" rel="noopener noreferrer"&gt;Twitter community forums&lt;/a&gt; or by Tweeting us at &lt;a href="https://twitter.com/TwitterDev" rel="noopener noreferrer"&gt;@TwitterDev&lt;/a&gt;. You can also give us feedback on our &lt;a href="https://twitterdevfeedback.uservoice.com/" rel="noopener noreferrer"&gt;feedback platform&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>migrate</category>
      <category>python</category>
      <category>twitter</category>
    </item>
    <item>
      <title>Using the Twitter API to make your commute easier</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Thu, 14 Nov 2019 14:41:40 +0000</pubDate>
      <link>https://dev.to/xdevs/using-the-twitter-api-to-make-your-commute-easier-3od0</link>
      <guid>https://dev.to/xdevs/using-the-twitter-api-to-make-your-commute-easier-3od0</guid>
      <description>&lt;p&gt;&lt;em&gt;The code for this tutorial is &lt;a href="https://github.com/aureliaspecker/met-line-alerts" rel="noopener noreferrer"&gt;available on GitHub&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I use London’s &lt;a href="https://tfl.gov.uk/tube/route/metropolitan/" rel="noopener noreferrer"&gt;TfL Metropolitan line&lt;/a&gt; on a daily basis to commute to and from work. Being aware of disruptions as they occur helps me save time on a daily basis. Luckily, the official Twitter account of the Metropolitan line (&lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt;) sends accurate information about the status of the line. &lt;/p&gt;

&lt;p&gt;I had originally enabled notifications for the &lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt; account, so that each time &lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt; sent a new Tweet, I would receive a push notification on my phone. But I ended up receiving too many notifications and many weren’t relevant to me. &lt;/p&gt;

&lt;p&gt;I needed a way to filter Tweets of interest and only receive notifications for information that is relevant to my personal commuting pattern.&lt;/p&gt;

&lt;p&gt;Enter... 🥁🥁🥁 the Twitter API!&lt;/p&gt;

&lt;p&gt;We’ll be using two different endpoints: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search" rel="noopener noreferrer"&gt;Premium 30-Day Search API&lt;/a&gt; (you can use the Sandbox version for free) to find the Tweets that we’re interested in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update" rel="noopener noreferrer"&gt;POST statuses/update&lt;/a&gt; endpoint to create a new Tweet that will notify you of potential disruptions. This endpoint is available for free.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Set up
&lt;/h1&gt;

&lt;p&gt;In order to reproduce this application, you will need the following: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Choose a Twitter account that Tweets information of interest. &lt;br&gt;
In this example, we will use &lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt; for Tube line information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Twitter account(s) of the notification recipient(s), in other words the commuter(s). For this, I used my primary Twitter account (&lt;a href="https://twitter.com/AureliaSpecker" rel="noopener noreferrer"&gt;@AureliaSpecker&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Twitter account of the notification sender. For this, I used a secondary Twitter account (&lt;a href="https://twitter.com/maddie_testing" rel="noopener noreferrer"&gt;@maddie_testing&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Twitter Developer account: if you don’t have one already, you can &lt;a href="https://developer.twitter.com/en/apply-for-access.html" rel="noopener noreferrer"&gt;apply for one&lt;/a&gt;. The developer account should be linked to the Twitter account of the notification sender (in this example: &lt;a href="https://twitter.com/maddie_testing" rel="noopener noreferrer"&gt;@maddie_testing&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;a href="https://developer.twitter.com/en/apps" rel="noopener noreferrer"&gt;Twitter Developer app&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.twitter.com/en/docs/basics/authentication/guides/access-tokens" rel="noopener noreferrer"&gt;Access keys and tokens&lt;/a&gt; for the app you created in the step above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up your &lt;a href="https://developer.twitter.com/en/account/environments" rel="noopener noreferrer"&gt;dev environment&lt;/a&gt; for "Search Tweets: 30-Days Sandbox" to something like &lt;em&gt;dev&lt;/em&gt; or &lt;em&gt;prod&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://pip.pypa.io/en/stable/installing/" rel="noopener noreferrer"&gt;Have pip installed&lt;/a&gt; on your laptop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python version 3.6 or above (in your command line, you can check what version of Python is installed by running &lt;code&gt;$ python --version&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From your command line, create a new directory for your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir commute-alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate into it and create the following two files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd commute-alerts
$ touch alerts.py
$ touch credentials.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, your project &lt;a href="https://formulae.brew.sh/formula/tree" rel="noopener noreferrer"&gt;tree&lt;/a&gt; should look something like this (you can install tree with &lt;code&gt;$ sudo install tree&lt;/code&gt; and then use &lt;code&gt;$ tree&lt;/code&gt; to get the following output): &lt;/p&gt;

&lt;p&gt;└── alerts.py&lt;br&gt;
└── credentials.yaml&lt;/p&gt;

&lt;p&gt;If you plan on pushing your project to GitHub, you should also add a &lt;code&gt;.gitignore&lt;/code&gt; file in your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ touch .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is very important that you carefully &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/guides/securing-keys-and-tokens" rel="noopener noreferrer"&gt;guard your access keys and tokens&lt;/a&gt;, as they represent your unique access to the Twitter API. Keeping these in a separate file (credentials.yaml) will ensure that you &lt;a href="https://help.github.com/en/articles/ignoring-files" rel="noopener noreferrer"&gt;exclude them from source&lt;/a&gt; and that no one steals them from you. Make sure to add the following line to your &lt;code&gt;.gitignore&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;credentials.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check that you have the necessary dependencies installed, by running the following in your command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install searchtweets
$ pip install requests_oauthlib
$ pip install pandas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;alerts.py&lt;/code&gt; in your preferred code editor (I use &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;) and add the following lines of code to import the required modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;searchtweets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ResultStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gen_rule_payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collect_results&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests_oauthlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OAuth1Session&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Handling credentials
&lt;/h1&gt;

&lt;p&gt;Now open &lt;code&gt;credentials.yaml&lt;/code&gt; and add your access keys and tokens in the format below. Replace &lt;strong&gt;{ENV}&lt;/strong&gt; with the dev environment name you previously created and insert your access keys and tokens for each field accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;search_tweets_api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;account_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;premium&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.twitter.com/1.1/tweets/search/30day/{ENV}.json&lt;/span&gt;
  &lt;span class="na"&gt;consumer_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXX&lt;/span&gt;
  &lt;span class="na"&gt;consumer_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXX&lt;/span&gt;
  &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXX&lt;/span&gt;
  &lt;span class="na"&gt;access_token_secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXXXXXXX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back in &lt;code&gt;alerts.py&lt;/code&gt;, use &lt;code&gt;load_credentials&lt;/code&gt; from the &lt;a href="https://github.com/twitterdev/search-tweets-python" rel="noopener noreferrer"&gt;Search Tweet Python wrapper&lt;/a&gt;. This will automatically handle credentials for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./credentials.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;yaml_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;env_overwrite&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the POST statuses/update endpoint, we will manually load the credentials and store them into a new set of variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./credentials.yaml&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;consumer_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consumer_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;consumer_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consumer_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;access_token_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_tweets_api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will then use &lt;a href="https://requests-oauthlib.readthedocs.io/en/latest/oauth1_workflow.html" rel="noopener noreferrer"&gt;OAuth1Session&lt;/a&gt; to manage credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;oauth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OAuth1Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;consumer_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;client_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;consumer_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;resource_owner_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;resource_owner_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;access_token_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using the Premium 30-Day Search API
&lt;/h1&gt;

&lt;p&gt;This endpoint lets you access the last 30 days of Twitter data. You can find out more about this endpoint in the &lt;a href="https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search#DataEndpoint" rel="noopener noreferrer"&gt;Twitter Developer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This endpoint takes four different parameters: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query&lt;/li&gt;
&lt;li&gt;fromDate&lt;/li&gt;
&lt;li&gt;toDate&lt;/li&gt;
&lt;li&gt;maxResults (in other words, the number of results returned per call).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will use &lt;a href="https://docs.python.org/3/library/datetime.html" rel="noopener noreferrer"&gt;Python’s datetime module&lt;/a&gt; to generate a fromDate and a toDate and establish a timeframe during which we want to be searching for Tweets from &lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt;. In our case, we want to be looking for all Tweets that were created in the past two hours. Note that, with the Twitter API, times are in UTC. Add the following lines of code to &lt;code&gt;alerts.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;utc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;utc_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d%H%M&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toDate:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;two_hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;two_hours_prior&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;two_hours&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d%H%M&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fromDate:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;two_hours_prior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return something like this when you run &lt;code&gt;$ python alerts.py&lt;/code&gt; in the command line (which is the format required for the toDate and fromDate parameters):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;toDate: 201910071658
fromDate: 201910071458
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/twitterdev/search-tweets-python" rel="noopener noreferrer"&gt;Search Tweets Python Wrapper&lt;/a&gt; enables us to use the 30Day Search endpoint without too much setup on our side. In this case, we are looking to get all Tweets from &lt;a href="https://twitter.com/metline" rel="noopener noreferrer"&gt;@metline&lt;/a&gt; that do not contain any mention of other Twitter accounts. Our query is therefore "from:metline -has:mentions". You can read more about building queries in the &lt;a href="https://developer.twitter.com/en/docs/tweets/rules-and-filtering/guides/using-premium-operators" rel="noopener noreferrer"&gt;Twitter Dev documentation&lt;/a&gt;. We also want to return no more than 100 Tweets per call (this is the maximum we can have with the free Sandbox access).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;gen_rule_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from:metline -has:mentions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;from_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;two_hours_prior&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;to_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;results_per_call&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rule:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the print function will return something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rule: {"query": "from:metline -has:mentions", "maxResults": 100, "toDate": "201910071658", "fromDate": "201910071458"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We store the Tweets returned by this query in a new variable "tweets" and then we use &lt;a href="https://www.pythonforbeginners.com/basics/list-comprehensions-in-python" rel="noopener noreferrer"&gt;list comprehensions&lt;/a&gt; to print out the first 10 lines of Tweets returned by our query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tweets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collect_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                         &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="n"&gt;result_stream_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at_datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return something like the below. Note that if no Tweets were created in the previous two hours, nothing will be returned.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2019-10-07 05:06:17 Minor delays between Uxbridge and Harrow-on-the-Hill, southbound only, due to a temporary shortage of train operators. Good service on the rest of the line.

2019-10-07 04:36:30 Minor delays between Harrow-on-the-Hill and Watford / Rayners Lane northbound only due to the temporary unavailability of train operators. Good service on the rest of the line.

2019-10-06 22:27:02 A good service is now operating to all destinations.

2019-10-06 21:49:52 Minor delays between Chesham/Amersham and Rickmansworth, southbound only, due to a signal failure at Chalfont &amp;amp;amp; Latimer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Setting up trigger words and notifications
&lt;/h1&gt;

&lt;p&gt;We need to establish what words will trigger a notification for the commuter(s). We will use &lt;a href="https://docs.python.org/2/library/sets.html" rel="noopener noreferrer"&gt;Python sets&lt;/a&gt; to do this. &lt;/p&gt;

&lt;p&gt;In this example, there are two commuters: David and Aurelia. Certain words will trigger a notification for both commuters, whereas other words will only trigger a notification for one of the commuters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;all_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;closure&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;wembley&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delays&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;disruption&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cancelled&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sorry&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stadium&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;david_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hillingdon&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;harrow&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;aurelia_trigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;baker&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if you want to add strings made up of two words in these sets you will have to add an extra level of data processing with &lt;a href="https://docs.python.org/3/howto/regex.html" rel="noopener noreferrer"&gt;REs&lt;/a&gt; (this is not included in this tutorial). &lt;/p&gt;

&lt;p&gt;Next, we create two new lists in which to store the Tweet dates and Tweet text returned by the call above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;tweet_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will also want all of the words included in the Tweets from the previous two hours to be concatenated in one string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then use a &lt;a href="https://www.w3schools.com/python/python_for_loops.asp" rel="noopener noreferrer"&gt;For Loop&lt;/a&gt; to populate the lists we created with the Tweet text and Tweet dates, and to concatenate the text from the different Tweets into one string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="n"&gt;tweet_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tweet_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at_datetime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;combined_tweet_text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following line creates a new set containing all of the words in lowercase from Tweets created in the past two hours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined_tweet_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then use an &lt;a href="https://www.w3schools.com/python/python_conditions.asp" rel="noopener noreferrer"&gt;If statement&lt;/a&gt;, as well as the Python &lt;a href="https://www.w3schools.com/python/ref_func_len.asp" rel="noopener noreferrer"&gt;len() function&lt;/a&gt; and &lt;a href="https://www.w3schools.com/python/ref_set_intersection.asp" rel="noopener noreferrer"&gt;set intersection() method&lt;/a&gt; to define whether a notification has to be sent or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@AureliaSpecker &amp;amp; @_dormrod 👋 check https://twitter.com/metline for possible delays, [{}]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;david_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@_dormrod 👋 Check https://twitter.com/metline for possible delays, [{}]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweet_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aurelia_trigger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@AureliaSpecker 👋 Check https://twitter.com/metline for possible delays, [{}]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;utc_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;There are no delays&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can print the message output, to check that the correct information is returned when you run &lt;code&gt;$ python alerts.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Message:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using the POST statuses/update endpoint to post on Twitter
&lt;/h1&gt;

&lt;p&gt;The final step involves sending the notification, in the form of a new Tweet, when one of the trigger words appears in the Tweet text. &lt;/p&gt;

&lt;p&gt;We use Twitter’s &lt;a href="https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update" rel="noopener noreferrer"&gt;POST statuses/update&lt;/a&gt; endpoint and set the parameter "status" (i.e. the Tweet body) to our variable "message" defined above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;oauth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twitter.com/1.1/statuses/update.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as the receiving Twitter account(s) have notifications enabled, the commuter(s) will receive a notification every time their @username is included in the Tweet body.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying your app with DigitalOcean
&lt;/h1&gt;

&lt;p&gt;I chose to use &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; to deploy this app to a remote server. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Login to your DigitalOcean account (or sign up for one)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new project and, within that project, create a new droplet by selecting "Create" on the top right hand side corner. Here is a good tutorial on &lt;a href="https://www.digitalocean.com/docs/droplets/how-to/create/" rel="noopener noreferrer"&gt;how to create new droplets&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A "droplet" is a Linux-based virtual machine. In other words, each new droplet you create acts as a new server you can use to deploy projects. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once you’ve created a droplet, you will have to connect to your droplet. &lt;a href="https://www.digitalocean.com/docs/droplets/how-to/connect-with-ssh/" rel="noopener noreferrer"&gt;This tutorial&lt;/a&gt; explains how you can do this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you have connected to the droplet (i.e. you are connected to the server) you will have to upload your project to that server. You can think of your droplet (or server) as another local machine on which you can add your project by cloning the repository from GitHub.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you haven’t already, add your project to GitHub by following &lt;a href="https://help.github.com/en/articles/adding-an-existing-project-to-github-using-the-command-line" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;. Make sure to add your &lt;code&gt;credentials.yaml&lt;/code&gt; file to your &lt;code&gt;.gitignore&lt;/code&gt; file, as described above. &lt;strong&gt;Remember not to accidentally push any credentials to GitHub&lt;/strong&gt;. Check out this guide on &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/guides/securing-keys-and-tokens" rel="noopener noreferrer"&gt;how to secure your keys and access tokens&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This article explains &lt;a href="https://help.github.com/en/articles/cloning-a-repository" rel="noopener noreferrer"&gt;how to clone GitHub repositories&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you’ve added your project, you will have to create a new &lt;code&gt;credentials.yaml&lt;/code&gt; file (as the one you previously did) and save it in the project folder. You can use &lt;a href="https://www.linux.com/tutorials/vim-101-beginners-guide-vim/" rel="noopener noreferrer"&gt;vim&lt;/a&gt; or &lt;a href="https://www.howtogeek.com/howto/42980/the-beginners-guide-to-nano-the-linux-command-line-text-editor/" rel="noopener noreferrer"&gt;nano&lt;/a&gt; as a text editor to add your credentials to the file:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# touch credentials.yaml
# vim credentials.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;em&gt;ESC :wq&lt;/em&gt; to save your changes and quit VIM mode. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Also make sure to add a &lt;code&gt;.gitignore&lt;/code&gt; file and add &lt;code&gt;credentials.yaml&lt;/code&gt; to that file, to make sure you don’t accidentally commit any access keys and tokens:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# touch .gitignore
# vim .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again, you can use &lt;em&gt;ESC :wq&lt;/em&gt; to save your changes and quit VIM mode.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Going forward, if you want to pull any changes from GitHub, you can run the following in your project directory:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Then, install all required dependencies (as described previously) just as you would if you were on another local machine. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’re now ready to run your app:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# python3 alerts.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! 🥳 Your app is now installed on a remote server.&lt;/p&gt;

&lt;h1&gt;
  
  
  Scheduling your app to automatically run with Cron
&lt;/h1&gt;

&lt;p&gt;Cron allows you to schedule your app to run automatically at certain times and on certain days. For example, I only want &lt;code&gt;alerts.py&lt;/code&gt; to run on weekdays, at 6.30am and at 4.30pm.&lt;/p&gt;

&lt;p&gt;I used the following tutorials to learn how to set up a Cron job: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackabuse.com/scheduling-jobs-with-python-crontab/" rel="noopener noreferrer"&gt;Scheduling Jobs with python-crontab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/python-crontab/" rel="noopener noreferrer"&gt;Python-crontab official help page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dummies.com/computers/operating-systems/linux/how-to-schedule-jobs-in-linux-at-and-crontab-commands/" rel="noopener noreferrer"&gt;Crontab commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the steps I followed: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On your remote server, open &lt;code&gt;alerts.py&lt;/code&gt; with vim and change the two mentions of &lt;code&gt;./credentials.yaml&lt;/code&gt; to &lt;code&gt;root/met-line-alerts/credentials.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install crontab-python: &lt;code&gt;$ pip install python-crontab&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a new file &lt;code&gt;cron.txt&lt;/code&gt; and open it with vim:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# touch cron.txt
# vim cron.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In that file, add the following line (type the letter "i" to insert text in vim):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30 6,16 * * 1-5 python3 /root/met-line-alerts/alerts.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and quit vim mode with &lt;em&gt;ESC :wq&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This line of code basically tells Cron to execute the command &lt;code&gt;python3 /root/met-line-alerts/alerts.py&lt;/code&gt; at minute 30 past hour 6 and 16 on every day-of-week from Monday through Friday. &lt;/p&gt;

&lt;p&gt;You can check your Cron schedule expressions on this website: &lt;a href="https://crontab.guru/" rel="noopener noreferrer"&gt;https://crontab.guru/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should also make sure to check the time on your Linux remote server, to ensure that you’re setting the time in the correct time zone. You can do this by typing the date command: &lt;code&gt;# date&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command to initiate the Cron job:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# crontab cron.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can list your active Cron jobs with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# crontab -l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can remove existing Cron jobs with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# crontab -r
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Hopefully this tutorial inspires you to build with the Twitter API to solve problems in your daily life. I used several libraries and services beyond the Twitter API to make this tutorial, but you may have different needs and requirements and should evaluate whether those tools are right for you.&lt;/p&gt;

&lt;p&gt;Let us know if this inspires you to build anything on the &lt;a href="https://twittercommunity.com/" rel="noopener noreferrer"&gt;Twitter community forums&lt;/a&gt; or by Tweeting us at &lt;a href="https://twitter.com/TwitterDev" rel="noopener noreferrer"&gt;@TwitterDev&lt;/a&gt;. You can also give us feedback on our &lt;a href="https://twitterdevfeedback.uservoice.com/" rel="noopener noreferrer"&gt;Feedback platform&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>python</category>
      <category>twitter</category>
    </item>
    <item>
      <title>#100DaysOfCode</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Fri, 13 Sep 2019 13:53:30 +0000</pubDate>
      <link>https://dev.to/aureliaspecker/100daysofcode-36hj</link>
      <guid>https://dev.to/aureliaspecker/100daysofcode-36hj</guid>
      <description>&lt;p&gt;I don't have a technical background.&lt;/p&gt;

&lt;p&gt;I used to work in Market Research, and before that I was doing a degree in Modern Languages. In 2017, I took a coding course with &lt;a href="https://www.codefirstgirls.org.uk/" rel="noopener noreferrer"&gt;Code First: Girls&lt;/a&gt;. This is how I got into tech and what led me to start a new job as a Partner Engineer at Twitter. &lt;/p&gt;

&lt;p&gt;A few months into my new job, I felt like I wasn't improving my coding skills fast enough. I needed to find the motivation to code outside of work and force myself outside of my comfort zone to learn new things. This is what led me to take on this challenge. &lt;/p&gt;

&lt;p&gt;This post is based on a talk I recently gave about my experience of the #100DaysOfCode challenge.&lt;/p&gt;

&lt;h1&gt;
  
  
  What
&lt;/h1&gt;

&lt;p&gt;The #100DaysOfCode challenge was created by &lt;a href="https://twitter.com/ka11away" rel="noopener noreferrer"&gt;Alexander Kallaway&lt;/a&gt; when he became frustrated at the "slow speed of [his] progress in learning to code" (&lt;a href="https://medium.com/free-code-camp/start-2017-with-the-100daysofcode-improved-and-updated-18ce604b237b" rel="noopener noreferrer"&gt;you can read more here&lt;/a&gt;). Alexander wrote an article about this and, as others read about the challenge, many decided to join in. Since 2017, thousands of people have taken up the challenge.&lt;/p&gt;

&lt;p&gt;There are two rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Commit to coding for minimum 1 hour every day for the next 100 days. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publicly commit to the challenge and Tweet your progress every day with the &lt;a href="https://twitter.com/100xcode" rel="noopener noreferrer"&gt;#100DaysOfCode&lt;/a&gt; hashtag.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can add any other rule that will help you reach your goals and fit your schedule. For example, I added the following rule: "In order for the hour to count, I have to be working on something new." This meant that the regular day-to-day coding I did as part of my job didn't count.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why
&lt;/h1&gt;

&lt;h5&gt;
  
  
  Join a community of supportive, friendly, motivated and like-minded individuals
&lt;/h5&gt;

&lt;p&gt;The community is very active on Twitter and Slack, for example, and the support I got from others during the challenge was very motivating. &lt;/p&gt;

&lt;h5&gt;
  
  
  Make new friends
&lt;/h5&gt;

&lt;p&gt;I was surprised at how many people (both at work and outside of work) who follow me on Twitter approached me to ask how the challenge was going. I had conversations that I would probably never have had without this challenge.&lt;/p&gt;

&lt;h5&gt;
  
  
  Work on projects, not tutorials
&lt;/h5&gt;

&lt;p&gt;Every beginner will one day have to shift away from copying other people's code and following tutorials to start writing their own code. It's a difficult shift to make. The nature of the #100DaysOfCode challenge, and the fact that it spans a long period of time, will help you make this shift.&lt;/p&gt;

&lt;h5&gt;
  
  
  Opportunity to really commit to learning to code
&lt;/h5&gt;

&lt;p&gt;I'd been wanting to code more for a while. This challenge forced me to not just think about it, but actually do it.&lt;/p&gt;

&lt;h5&gt;
  
  
  An active GitHub profile
&lt;/h5&gt;

&lt;p&gt;You can clearly see how active my GitHub profile became when I started taking the challenge in January. It's also clear that I needed a bit of a break at the end of the challenge in April. But after that I kept on coding. The #100DaysOfCode challenge is a great way to build a new habit and consistency.   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6vr6sjifv0y4gaf7n2k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6vr6sjifv0y4gaf7n2k0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Keep track of your progress
&lt;/h5&gt;

&lt;p&gt;It's easy to not realise how far you've come. Being able to look back at the &lt;a href="https://twitter.com/AureliaSpecker/status/1077196955514818560" rel="noopener noreferrer"&gt;Tweet thread&lt;/a&gt; that tracks what I did every day during these 100 days helps me see how much I learnt and achieved in that period of time.&lt;/p&gt;

&lt;h5&gt;
  
  
  It's a good excuse to Tweet every day!
&lt;/h5&gt;

&lt;h1&gt;
  
  
  Challenges
&lt;/h1&gt;

&lt;h5&gt;
  
  
  Finding the time
&lt;/h5&gt;

&lt;p&gt;This was one of the hardest aspects for me. Work takes up a lot of my time, and I'm always busy when I'm not at work. I had to cut down the exercising and socialising to find an extra hour every day to code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe7kynrmrwkrp1d6nopo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe7kynrmrwkrp1d6nopo5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Not knowing exactly what technologies to learn
&lt;/h5&gt;

&lt;p&gt;The diversity of technologies and programming languages that exist is one of the most exciting aspects of tech. And yet, as a beginner, it can also be daunting and it can be hard to know what technologies to focus on. &lt;/p&gt;

&lt;h5&gt;
  
  
  Not knowing what resources to use
&lt;/h5&gt;

&lt;p&gt;The Internet is brimming with available resources (both free or for a fee). As much as this is amazing, it can also be overwhelming. How do I know which resources are good and trustworthy? How do I know what formats work well for me? Etc.&lt;/p&gt;

&lt;h5&gt;
  
  
  Feeling hopeless when progress is slow
&lt;/h5&gt;

&lt;p&gt;100 days is a long time and there will naturally be some days that feel more difficult. It's normal to feel discouraged at times. On days like that, it's important to take a step back and appreciate how much you've done so far.&lt;/p&gt;

&lt;h5&gt;
  
  
  The imposter syndrome is real!
&lt;/h5&gt;

&lt;p&gt;Tweeting about your progress daily can make you feel vulnerable. "What if people think I'm too slow or that what I'm learning is too easy?" "What if I'm not good enough?" It can be hard at times, but it's important to learn to block out these thoughts and ignore them.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to succeed
&lt;/h1&gt;

&lt;h5&gt;
  
  
  Find a way to hold yourself accountable
&lt;/h5&gt;

&lt;p&gt;This was really important for me. Knowing that my colleagues, my managers, my friends were following my progress is what ensured that I didn't give up in the harder moments.&lt;/p&gt;

&lt;h5&gt;
  
  
  Have a broad plan
&lt;/h5&gt;

&lt;p&gt;You don't need a specific plan, but I would suggest having a list of things you want to do or learn about. My list included items such as using my Raspberry Pi or refactoring a Python project to be object-oriented. As I made my way through the challenge, I found out about new technologies and concepts and added these to my list. This meant that, when I was stuck for what to do next, I could simply revert back to my list and get started on the next item.&lt;/p&gt;

&lt;h5&gt;
  
  
  It's ok to have a bad day
&lt;/h5&gt;

&lt;p&gt;You will have bad days. Embrace them and Tweet about it. You will likely get support from the community. Having a bad day is part of the journey. Talking about it will also help others feel less lonely when they have a bad day.&lt;/p&gt;

&lt;h5&gt;
  
  
  It's ok to take a few days off
&lt;/h5&gt;

&lt;p&gt;Similarly, it's important to take a few days off if you need to. Midway through the challenge I took 3 days off, to enjoy some time with my family. I was feeling particularly tired then, because of a busy period at work and in my personal life. Taking a short break enabled me to feel energised and motivated enough to take on the second half of the challenge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7wh8vifs6b03iccevloi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7wh8vifs6b03iccevloi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Consistency really matters
&lt;/h5&gt;

&lt;p&gt;Consistency is what will help you develop a habit. &lt;/p&gt;

&lt;h5&gt;
  
  
  Persevere
&lt;/h5&gt;

&lt;p&gt;It took me ~70 days before I started feeling the benefits of the challenge, before I started drawing connections, and before I started feeling that this challenge was worth it! Learning takes time. If I'd given up any earlier, I would never have realised how much I could learn during this period of time.&lt;/p&gt;

&lt;h5&gt;
  
  
  Don't be afraid to ask for help
&lt;/h5&gt;

&lt;p&gt;I was lucky to do some code pairing sessions throughout this challenge. Sometimes, you just need someone to sit down with you and explain a concept or help you debug. Don't be afraid to ask for help: there will always be someone out there who is willing to help you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;The community is very active and there are many resources to help get you started and support you along the way. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.100daysofcode.com/" rel="noopener noreferrer"&gt;The #100DaysOfCode official website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/search?q=%23100DaysOfCode&amp;amp;src=hashtag_click" rel="noopener noreferrer"&gt;The community on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://join.slack.com/t/100xcode/shared_invite/enQtNzQwMzIwMzQxODc5LWQwMjU5Mjg0N2ZiMzIzYzJiZmE0YjNiYTBiZDBjNjlkNjBmMTYxNDBmNmE2YmE2YzY4NTgzY2Y5NDQxNWY5ZDM" rel="noopener noreferrer"&gt;The #100DaysOfCode Slack workspace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Podcast episodes: &lt;a href="https://www.codenewbie.org/podcast/100-days-of-code" rel="noopener noreferrer"&gt;CodeNewbie&lt;/a&gt; and &lt;a href="https://learntocodewith.me/podcast/100-days-of-code-with-alexander-kallaway/" rel="noopener noreferrer"&gt;Learn To Code With Me&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  A snapshot into my learnings
&lt;/h1&gt;

&lt;p&gt;I chose to get a broad exposure to different technologies, concepts and languages rather than focus on one big project during the 100 days. Here are some examples:&lt;/p&gt;

&lt;h5&gt;
  
  
  I used a Raspberry Pi for the first time
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkflgbnxeyrrnr3ls73ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkflgbnxeyrrnr3ls73ht.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I learnt about object-oriented programming
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftndit1bq9g86dvlkpa4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftndit1bq9g86dvlkpa4o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I became more familiar with JavaScript and wrote code in Node.js
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F14adiy4tej59aclmnnnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F14adiy4tej59aclmnnnk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I looked into what happens when you deploy a project to Heroku
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo771wygfi2jzluii891p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo771wygfi2jzluii891p.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I explored asynchronous programming and promises
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4km1nlp56epmtk0fgzaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4km1nlp56epmtk0fgzaf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I dived into databases and used both MySQL and MongoDB
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgeghjy96jigj4td0lkya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgeghjy96jigj4td0lkya.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I honed my bash skills
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqavkd6edt09b0qse3joh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqavkd6edt09b0qse3joh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  I used Flask and Jinja to build the front-end for a Python project
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fohz1u4vva0p0xa4zb9dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fohz1u4vva0p0xa4zb9dg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  And lots, lots more...
&lt;/h5&gt;

</description>
      <category>100daysofcode</category>
      <category>motivation</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Getting started with Twitter's Account Activity API</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Fri, 31 May 2019 17:03:01 +0000</pubDate>
      <link>https://dev.to/xdevs/getting-started-with-twitter-s-account-activity-api-en8</link>
      <guid>https://dev.to/xdevs/getting-started-with-twitter-s-account-activity-api-en8</guid>
      <description>&lt;p&gt;Have you ever wanted to follow account events on Twitter in realtime? This tutorial will help you get started with Twitter's webhook-based Account Activity API. &lt;/p&gt;

&lt;p&gt;You can watch the tutorial here, or continue reading below.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1134499619759644672-96" src="https://platform.twitter.com/embed/Tweet.html?id=1134499619759644672"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1134499619759644672-96');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1134499619759644672&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Twitter's &lt;a href="https://developer.twitter.com/en/products/accounts-and-users/account-activity-api.html" rel="noopener noreferrer"&gt;Account Activity API&lt;/a&gt; sends you events related to a Twitter user's account activities in realtime. For example, the Account Activity API delivers a JSON event payload every time a subscribed user creates or deletes a Tweet, Retweets, receives or sends a Direct Message, follows a new user, or likes a post. You can find a full list of the types of activities served by the Account Activity API in &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview" rel="noopener noreferrer"&gt;Twitter's developer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A webhook-based API
&lt;/h3&gt;

&lt;p&gt;The Account Activity API is different to Twitter's REST and streaming APIs, because it uses a combination of REST endpoints for setup and management, and webhooks for data delivery. If you've never used them before, webhooks deliver data by "pushing" (aka POSTing) events to the webhook URL of a registered web application. This is done via an HTTP call in real-time when a specific event (aka an account activity) happens.&lt;/p&gt;

&lt;p&gt;Twitter's more common APIs are based on a client-server approach, where you would create a client application that makes a connection to Twitter's servers to receive some information. This can be based on a streaming model, where your client connection to Twitter's servers always stays open to receive data in realtime, or, it can be a client-triggered request, for example if you wanted to retrieve a specific Tweet. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi8qr6myrf6du3td5uwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi8qr6myrf6du3td5uwd.png" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the Account Activity API, this pattern is inverted. Instead of your client application making a connection request to Twitter's servers, it's Twitter's servers that make a connection back to your web application listening for data. In this case, Twitter acts as the client and opens a connection to your server to post activities to that webhook every time an event occurs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqiypwbj5bf7wq7a8ynd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqiypwbj5bf7wq7a8ynd2.png" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many advantages to using webhook-based APIs: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From a computing-resourcing perspective, webhooks require less resources than if you have an ongoing open connection to a streaming API. &lt;/li&gt;
&lt;li&gt;There is confirmation on both sides of an activity being delivered per POST with an HTTP 200 response code.&lt;/li&gt;
&lt;li&gt;If an activity is not successfully delivered, there is a built-in retry process to re-POST, which reduces the chance of missed data.&lt;/li&gt;
&lt;li&gt;With webhooks, your application no longer has to make periodic polling requests to an API to check for new data to be available. &lt;/li&gt;
&lt;li&gt;New data will automatically be sent to your server as soon as it's available. Therefore, the data received is almost always the most up-to-date.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What you need to get started
&lt;/h3&gt;

&lt;p&gt;You'll need the following: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://developer.twitter.com/en/account/get-started" rel="noopener noreferrer"&gt;A developer account&lt;/a&gt;&lt;/strong&gt; is required to use any of Twitter's APIs. You can &lt;a href="https://developer.twitter.com/en/apply-for-access" rel="noopener noreferrer"&gt;apply for one&lt;/a&gt; if you don't have one already.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A Twitter &lt;a href="https://developer.twitter.com/en/docs/basics/apps/overview" rel="noopener noreferrer"&gt;developer app&lt;/a&gt; with the right permissions&lt;/strong&gt;. You can create a new one if needed, by selecting the "Create an app" button under the &lt;a href="https://developer.twitter.com/en/apps" rel="noopener noreferrer"&gt;Apps section of your developer portal&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure to enable "Read, Write, and Direct Messages", on the permissions tab of your app page. Also, note that permission settings are not retroactive for authorized users with previous lower permission settings. &lt;/li&gt;
&lt;li&gt;On the "Keys and Access token" tab, take a note of your app's Consumer API Key and API Secret. This information will enable you to generate a &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/guides/bearer-tokens" rel="noopener noreferrer"&gt;bearer token&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;You will also have to generate your app's access token and access token secret. You will need these when you register your webhook URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A developer environment&lt;/strong&gt;, which you can set up in the &lt;a href="https://developer.twitter.com/en/account/environments" rel="noopener noreferrer"&gt;Dev Environments section of your developer portal&lt;/a&gt;. Select your app and choose an environment name. The name you choose will replace the &lt;code&gt;:env_name&lt;/code&gt; token when you start using the &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference" rel="noopener noreferrer"&gt;different Account Activity API endpoints&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A specific, secured web application with URL&lt;/strong&gt; for receiving data through webhooks. A tool like &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt; could be useful for creating a local web address to test your webhooks in development. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Securing your webhooks
&lt;/h3&gt;

&lt;p&gt;In order to receive activities from Twitter via webhooks, you'll need to create and secure a web application that can receive HTTP (POST and GET) requests on a URL of your choice. This app needs to be secured with the same Twitter app credentials that you set up in your developer environment for the Account Activity API, and coded to &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/securing-webhooks" rel="noopener noreferrer"&gt;create the &lt;code&gt;crc_token&lt;/code&gt;&lt;/a&gt; using these credentials. Twitter will regularly send your webhook &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/securing-webhooks.html" rel="noopener noreferrer"&gt;challenge response check (known as CRC) GET requests&lt;/a&gt;, for which your web app needs to return the &lt;code&gt;crc_token&lt;/code&gt; generated using the Twitter application credentials that match those of your whitelisted developer environment app. &lt;/p&gt;

&lt;p&gt;You can register a webhook URL for the Account Activity API using the &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference/aaa-premium#post-account-activity-all-env-name-webhooks" rel="noopener noreferrer"&gt;&lt;code&gt;POST account_activity/all/:env_name/webhooks&lt;/code&gt;&lt;/a&gt; endpoint.&lt;/p&gt;

&lt;p&gt;Set up for the Account Activity API is done with &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference" rel="noopener noreferrer"&gt;API requests&lt;/a&gt; - there's no user interface built into the developer portal. We've provided an example dashboard tool on our TwitterDev GitHub page, which you might find useful for testing: &lt;a href="https://github.com/twitterdev/account-activity-dashboard" rel="noopener noreferrer"&gt;https://github.com/twitterdev/account-activity-dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your registered webhook URL is where the Account Activity API will send account activities, in the form of HTTP POST requests containing the event data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;Authentication can be tricky with the Account Activity API, because there are different auth methods for different functions of the API. Most of the webhook setup is done through &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/overview/application-only" rel="noopener noreferrer"&gt;application-only authentication&lt;/a&gt; with a bearer token. Check the docs for more information on &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/guides/bearer-tokens" rel="noopener noreferrer"&gt;how to build one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Subscriptions are set up via application-user authentication for each user. If you want to receive events for your own Twitter account, you can use the access token generated with the API key and API secret key from your developer portal, and this is a great way to get started and test the API. If you want to receive events relating to another Twitter account, the owner of that account will have to grant you permission via the &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth" rel="noopener noreferrer"&gt;3-legged OAuth process&lt;/a&gt;. This process is also something that you will need to implement in your server-side code, as this will enable you to receive a user's access tokens. In the &lt;a href="https://github.com/twitterdev/account-activity-dashboard" rel="noopener noreferrer"&gt;example dashboard app&lt;/a&gt;, we use &lt;a href="https://developer.twitter.com/en/docs/twitter-for-websites/log-in-with-twitter/guides/implementing-sign-in-with-twitter.html" rel="noopener noreferrer"&gt;Sign in with Twitter&lt;/a&gt; to get the tokens for each user, so take a look if you want to learn more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscriptions
&lt;/h3&gt;

&lt;p&gt;Once you have a user's access token from the &lt;a href="https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth" rel="noopener noreferrer"&gt;3-legged OAuth process&lt;/a&gt;, you can use it with application-user authentication to create a new subscription for that user.&lt;/p&gt;

&lt;p&gt;At this stage, you should have these things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A running server-side web application&lt;/strong&gt; ready to receive webhook events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A registered webhook URL&lt;/strong&gt; where  Twitter will send events (also known as account activities) in the form of POST requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One or more authorised users&lt;/strong&gt; in the form of registered subscriptions for whom you will receive account activities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;OK! You're ready to start receiving events!&lt;/p&gt;

&lt;h3&gt;
  
  
  Events
&lt;/h3&gt;

&lt;p&gt;You'll start receiving events for a user as soon as they are subscribed to your webhook URL. So, what exactly is an event? In this case, an event corresponds with an activity related to the Twitter account of a subscribed user. Each event is delivered in the form of a JSON payload. In the example below, a "message create" event is delivered when the user receives a Direct Message. There is a "text" field that contains the content of the message, and other information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"for_user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"direct_message_events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"message_create"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1133674120380657669"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1559123947602"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message_create"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"recipient_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"sender_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"message_data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Good morning ☀️☕"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"entities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"hashtags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"symbols"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"user_mentions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"urls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1358552743000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aurelia Specker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"screen_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AureliaSpecker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"London, England"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partner engineer @TwitterUK 👩‍💻 • instructor @CodeFirstGirls • outdoor enthusiast 🌄"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"protected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"followers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;589&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"friends_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;745&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"statuses_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;521&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://pbs.twimg.com/profile_images/1025560966434443264/vsVPbXiT_normal.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url_https"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://pbs.twimg.com/profile_images/1025560966434443264/vsVPbXiT_normal.jpg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1534344560624"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aurelia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"screen_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"re_testing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"London, England"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I like traveling 🐪🌴☀️"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"protected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"followers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"friends_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"statuses_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://pbs.twimg.com/profile_images/1029742489090121728/-83RqB5N_normal.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url_https"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://pbs.twimg.com/profile_images/1029742489090121728/-83RqB5N_normal.jpg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"for_user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"direct_message_indicate_typing_events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1559123947551"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sender_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"recipient_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1102321381"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1358552743000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aurelia Specker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"screen_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AureliaSpecker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"London, England"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partner engineer @TwitterUK 👩‍💻 • instructor @CodeFirstGirls • outdoor enthusiast 🌄"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"protected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"followers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;589&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"friends_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;745&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"statuses_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;521&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://pbs.twimg.com/profile_images/1025560966434443264/vsVPbXiT_normal.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url_https"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://pbs.twimg.com/profile_images/1025560966434443264/vsVPbXiT_normal.jpg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1029741837916012544"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"created_timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1534344560624"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aurelia"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"screen_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"re_testing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"London, England"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I like traveling 🐪🌴☀️"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"protected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"followers_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"friends_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"statuses_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://pbs.twimg.com/profile_images/1029742489090121728/-83RqB5N_normal.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"profile_image_url_https"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://pbs.twimg.com/profile_images/1029742489090121728/-83RqB5N_normal.jpg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not possible to choose to receive certain types of events and exclude others - you'll always receive all event types related to the subscribed user(s). A full list of the event types can be reviewed in &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/account-activity-data-objects" rel="noopener noreferrer"&gt;the developer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you need &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/activity-retries" rel="noopener noreferrer"&gt;retries&lt;/a&gt;, you can sign up for a paid option to enable them. With retries, if the activity is not delivered and your webhook does not return a successful response, the Twitter server will try sending the activity again. Enterprise customers also have additional redundancy and recovery coverage with the &lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/activity-replay-api.html" rel="noopener noreferrer"&gt;Account Activity Replay API&lt;/a&gt;, providing a way to resend activities for a requested period of time in the previous five days.&lt;/p&gt;

&lt;p&gt;The more subscriptions you have, the more important capacity planning becomes, to ensure that your systems are capable of receiving a large number of events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further resources
&lt;/h3&gt;

&lt;p&gt;Twitter's developer docs contain further resources, including: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/getting-started-with-webhooks" rel="noopener noreferrer"&gt;Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/FAQ" rel="noopener noreferrer"&gt;Frequently asked questions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference" rel="noopener noreferrer"&gt;API Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/api-reference" rel="noopener noreferrer"&gt;Account Activity API reference index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/quick-start/enterprise-account-activity-api" rel="noopener noreferrer"&gt;Quick start guide&lt;/a&gt; (for enterprise customers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join our &lt;a href="https://twittercommunity.com/" rel="noopener noreferrer"&gt;Developer Community&lt;/a&gt; or Tweet us at &lt;a href="https://twitter.com/TwitterDev" rel="noopener noreferrer"&gt;@TwitterDev&lt;/a&gt; if this tutorial inspires you to build anything. Let us know what you think on our &lt;a href="https://twitterdevfeedback.uservoice.com/" rel="noopener noreferrer"&gt;feedback channel&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaawiyjoljbfsrwo8oq9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaawiyjoljbfsrwo8oq9.gif" width="600" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twitter</category>
      <category>webhooks</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Nevertheless, Aurelia Specker Coded</title>
      <dc:creator>Aurelia Specker</dc:creator>
      <pubDate>Thu, 07 Mar 2019 18:31:37 +0000</pubDate>
      <link>https://dev.to/aureliaspecker/nevertheless-aurelia-specker-coded--30jb</link>
      <guid>https://dev.to/aureliaspecker/nevertheless-aurelia-specker-coded--30jb</guid>
      <description>&lt;h2&gt;
  
  
  I started to code because...
&lt;/h2&gt;

&lt;p&gt;I didn't find my previous job challenging enough. I wanted to get a job where I could constantly learn new skills and push myself to achieve new goals. &lt;/p&gt;

&lt;p&gt;Coding is challenging - there are so many things to learn and, when you eventually do learn them, they change again (for example, libraries and languages get updated all the time). But coding is also extremely empowering and rewarding. There are so many resources available out there and you can learn to build pretty much anything if you put in the right amount of effort and time. And that addictive feeling when you finally get something to work... priceless!&lt;/p&gt;

&lt;p&gt;A year after I started coding, I got a job as a Partner Engineer. I love that my job stretches me and enables me to learn new things every day!&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm currently working on...
&lt;/h2&gt;

&lt;p&gt;Several things... In January, I committed to the &lt;a href="https://twitter.com/AureliaSpecker/status/1077196955514818560"&gt;#100DaysOfCode challenge&lt;/a&gt;. The idea is that for 100 days, you code for at least one hour a day. I've recently hit the halfway mark and I've already learnt so many things. Initially, I was worried that I wouldn't have the right inspiration to keep this going for 100 days, but I'm actually finding that I want to do too many things and don't have enough time. &lt;/p&gt;

&lt;p&gt;I've started my own little projects (such as building an app that tracks Tweet engagement with the Twitter API) and I've taken online courses (for example a Udemy course on using Node.js). &lt;/p&gt;

&lt;p&gt;I've also been code pairing with some more experienced developers and have learnt a huge amount from coding with them.&lt;/p&gt;

&lt;p&gt;I am also co-teaching the Code First: Girls Python course in London. It's a challenge at times, because explaining something requires of you that you really understand it (and I'm still relatively new to Python myself!). But it's also incredibly fun and so gratifying to inspire other girls to get into coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  My advice for others who are learning to code...
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get involved in the community of developers&lt;/strong&gt;. First of all, it's fun and you'll meet some like-minded people that will help you stay motivated during times of self-doubt. You will also learn a lot faster, by talking to other developers about their own experiences. Being part of the community will also bring up new opportunities: finding a new mentor, hearing about a job opening, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code on a regular basis&lt;/strong&gt;. We all have busy lives and, sometimes, it can be hard to continue learning when you're coding as a 'hobby on the side'. Make the time. Even if it's one hour every few days, make it a priority. The result is very fulfilling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, &lt;strong&gt;don't be too harsh on yourself&lt;/strong&gt;. It's really easy to get imposter syndrome, especially when you're surrounded by coders who know so much more than you do. There will be ups and there will be downs. Take things one baby step at a time and never give up - it's worth it &amp;amp; you can &lt;em&gt;totally&lt;/em&gt; do it!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>wecoded</category>
    </item>
  </channel>
</rss>
