{"id":18969127,"url":"https://github.com/ranman/celebrity-tweeter","last_synced_at":"2026-04-05T15:30:19.926Z","repository":{"id":141492468,"uuid":"95052874","full_name":"ranman/celebrity-tweeter","owner":"ranman","description":null,"archived":false,"fork":false,"pushed_at":"2017-07-26T02:27:45.000Z","size":14,"stargazers_count":1,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-01T07:10:18.287Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ranman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-21T22:50:02.000Z","updated_at":"2020-02-01T18:05:55.000Z","dependencies_parsed_at":"2024-05-19T17:03:25.270Z","dependency_job_id":null,"html_url":"https://github.com/ranman/celebrity-tweeter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ranman%2Fcelebrity-tweeter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ranman%2Fcelebrity-tweeter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ranman%2Fcelebrity-tweeter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ranman%2Fcelebrity-tweeter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ranman","download_url":"https://codeload.github.com/ranman/celebrity-tweeter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239966157,"owners_count":19726273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T14:51:58.906Z","updated_at":"2026-04-05T15:30:19.870Z","avatar_url":"https://github.com/ranman.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Build A Rekognition Powered Celebrity Rekognition Twitter Bot\n\n# This readme has not been updated from another project but it's basically the same stuff\n# TL;DR How do I 🚀launch🚀 this stack? Click one of these!\nRegion (that supports Rekognition) | Button\n------------ | -------------\nus-east-1 | [![launch stack button](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=CelebTwitterBot\u0026templateURL=https://s3.amazonaws.com/aws-rekog-twitter-celeb-us-east-1/template-us-east-1.yaml)\nus-west-2 | [![launch stack button](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=CelebTwitterBot\u0026templateURL=https://s3.amazonaws.com/aws-rekog-twitter-celeb-us-west-2/template-us-west-2.yaml)\neu-west-1 | [![launch stack button](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=CelebTwitterBot\u0026templateURL=https://s3.amazonaws.com/aws-rekog-twitter-celeb-eu-west-1/template-eu-west-1.yaml)\n\n### **WARNING**: not all of these resources are within the free-tier\n#### Cost Estimate: ~$12/month with ~10 requests per second: [Simple Monthly Calculator](https://calculator.s3.amazonaws.com/index.html#r=IAD\u0026key=calc-C1BFFEDA-A944-472A-9A52-0B57AA3E95CE)\n\n\n# Overview\n### This workshop will allow you to build a twitter bot that recognizes celebrities\n\n## Example:\n[![example photo](imgs/example.png)](https://twitter.com/AWSCloudNinja/status/865568765836185601)\n\nWe'll cover the concepts of:\n\n* [Twitter API](https://apps.twitter.com/)\n* [AWS Lambda](https://aws.amazon.com/lambda/)\n* [Amazon DynamoDB](https://aws.amazon.com/dynamodb/)\n* [Amazon EC2](https://aws.amazon.com/ec2/), [Amazon EC2 SSM](http://docs.aws.amazon.com/systems-manager/latest/APIReference/Welcome.html), AWS Autoscaling, Amazon VPC\n* [AWS IAM](https://aws.amazon.com/iam/)\n* [AWS CloudFormation](https://aws.amazon.com/cloudformation/)\n* Python\n\nTo design your own bot you should have a working knowledge of:\n\n* JSON\n* Twitter API\n* A programming language\n* REST APIs\n* OAuth\n\n\n# TOC:\n1. Setup Twitter App\n2. Launch Stack\n3. Send a test tweet\n4. How does it all work?\n5. Additional Exercises\n\n## Video of setup: [https://youtu.be/cOTZxTJ3pN4](https://youtu.be/cOTZxTJ3pN4)\n\n## Setting up a Twitter App\n1. First we need to create a new twitter app by navigating to: [https://apps.twitter.com/](https://apps.twitter.com/)\n\n2. Next we will create a new twitter application\n![click create new app](imgs/1_create.png)\n\n3. Now we'll fill out some info to create that application\n![fill out info for new app](imgs/2_create_details.png)\n\n4. Next we'll generate some additional credentials for accessing our application as ourselves:\n![create access tokens](imgs/3_credentials.png)\n\n5. Then we'll save all this info somewhere safe!\n![access tokens](imgs/4_access_token.png)\n\n## Launching The Stack\nTo setup the lambda function and associated infrastructure we can either use the launch stack button or we can simply\nupload this template-{region}.yaml file into the CloudFormation console and have CloudFormation set everything up for us!\n\n\nNow we go to CloudFormation:\n![cloudformation permissions](imgs/5_cloudformation.png)\n\nThen we click next and fill out the credentials we saved earlier!\n\n![cloudformation credentials](imgs/6_filledout.png)\n\nNext we continue to click next and accept and then we launch the stack!\n\nYou can walk through the CloudFormation template in detail below:\n\u003cdetails\u003e\n\n### CloudFormation Details:\nYou can see the template file here: [template-us-east-1.yaml](template-us-east-1.yaml)\n\n#### Preamble\nThe first section of the CloudFormation template are the `Parameters`. The only required parameters are the Twitter credentials.\n\nThe rest of the parameters are for testing and convenience sake (or for when you want to easily deploy your own bot later).\n\nThere's a small metadata section that just includes some details on how to render the parameters page.\n\nThe final part of the preamble are the Mappings. In this case we just have a simple Region-to-AMI map that gives us a amazon linux instance.\n\n#### Resources\n\n##### Kinesis, and DynamoDB\nWe create a Kinesis Stream: `AWS::Kinesis::Stream` with a single shard.\nWe create a DynamoDB (DDB): `AWS::DynamoDB::Table` with some basic attributes.\n\n##### Credentials and IAM\nNow that we have most of our resources we can create a role for our application: `AWS::IAM::Role`.\n\nWe'll give our role an `AssumeRolePolicyDocument` AKA a Trust Policy that allows both Lambda and EC2 instances to assumme this role.\n\nWe'll also give our policy access to: x-ray, logging, rekognition, our dynamodb table, and our S3 Buckets.\n\nFinally we also create an SSM Parameter: `AWS::SSM::Parameter` of type `StringList` from the credentials provided in the Parameters section of the template.\n\n##### Lambda Functions\nNext we create our lambda function: `AWS::Lambda::Function` and connect it to our kinesis stream through an `AWS::Lambda::EventSourceMapping`.\n\nWe also assign this lambda function the IAM role we created above.\n\n##### Infrastructure\nWe start by declaring a VPC: `AWS::EC2::VPC` with a CIDR Block of `10.0.0.0/16`.\n\nThis tells CloudFormation to build us a Virtual Private Cloud with 65536 addresses (2^(32-16)).\n\nNext we build and attach an Internet Gateway (IGW): `AWS::EC2::InternetGateway`.\n\nWe create a Route Table: `AWS::EC2::RouteTable`, and populate it with a route to our IGW.\n\nThen we declare 2 subnets: `AWS::EC2::Subnet` of `10.0.0.0/24` and `10.0.1.0/24` with 255 addresses each (2^(32-24)) and in two separate AZs.\n\nNext we associate our route table created above with our 2 subnets.\n\nNow we create an IAM profile to associate with our EC2 instances.\n\nNext we create an AutoScaling Group Launch Configuration: `AWS::AutoScaling::LaunchConfiguration` with some UserData to setup our streaming instance.\n\nNow we associate the LaunchConfiguration with our AutoScaling Group: `AWS::AutoScaling::Group` with a `CreationPolicy` to wait for a signal from our user data on the EC2 instances.\n\nWe give our AutoScaling group a desired, min, and max size of 1 but access to two AZs to ensure our ingestion continues during a single AZ outage.\n\u003c/details\u003e\n\n## Sending A Test Tweet:\n\nIt's easy! Just make sure you mention the name of your twitter bot and include a photo and you should get a response:\n```\nHey @awscloudninja cloud ninja me and @werner!\n```\n\n\n## How does it all work?\n\nIt's really straight forward and all the magic happens in [process_stream.py](process_stream.py)\n\n\n\n## Additional Exercises\n1. Change the \"mask.png\" in the lambda to whatever you want and re-zip and re-upload the lambda function!\n1. Can you make this detect beards and rate them (based on confidence value) ?\n1. Can you make this bot detect celebrities and return their name (or tag them on twitter!?!) ?\n1. Can you make this use Lex instead of rekogntion to respond to users ?\n\n\n## I want to build this myself:\nRun `./build.sh process_stream.zip process_stream.py mask.png` to create the lambda package.\n\nIf you've only changed the proccess_stream.py file you can just `zip -9 process_stream.zip process_stream.py`\n\nUpload that package to lambda:\n`aws lambda update-function-code --function-name \u003cFUNCTION_NAME\u003e --code s3://\u003cBUCKET\u003e/\u003cKEY\u003e`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Franman%2Fcelebrity-tweeter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Franman%2Fcelebrity-tweeter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Franman%2Fcelebrity-tweeter/lists"}