{"id":13767170,"url":"https://github.com/lorey/totally-not-jarvis","last_synced_at":"2025-04-12T13:20:24.570Z","repository":{"id":91914043,"uuid":"92436600","full_name":"lorey/totally-not-jarvis","owner":"lorey","description":":robot: My personal assistant","archived":false,"fork":false,"pushed_at":"2017-06-30T08:55:32.000Z","size":217,"stargazers_count":21,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T20:13:10.405Z","etag":null,"topics":["ical","jarvis","personal-assistant","telegram-bot","weather"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lorey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-05-25T19:20:32.000Z","updated_at":"2024-05-30T17:35:37.000Z","dependencies_parsed_at":"2024-01-07T03:40:14.189Z","dependency_job_id":"ca28bcc7-99fd-4f74-8d6f-263c7de9b323","html_url":"https://github.com/lorey/totally-not-jarvis","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/lorey%2Ftotally-not-jarvis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lorey%2Ftotally-not-jarvis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lorey%2Ftotally-not-jarvis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lorey%2Ftotally-not-jarvis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lorey","download_url":"https://codeload.github.com/lorey/totally-not-jarvis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248571836,"owners_count":21126522,"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":["ical","jarvis","personal-assistant","telegram-bot","weather"],"created_at":"2024-08-03T16:01:05.737Z","updated_at":"2025-04-12T13:20:24.540Z","avatar_url":"https://github.com/lorey.png","language":"Python","funding_links":[],"categories":["How it works","Tools"],"sub_categories":[],"readme":"![Not a picture of Jarvis](.github/robot.jpg)\n\n# Totally not Jarvis - a personal assistant bot\n\nThis is a personal assistant bot built with [Telegram](https://github.com/python-telegram-bot/python-telegram-bot). I've attempted to lay the foundations for a framework that allows you to switch intents by issuing new commands while not forgetting about old intents. An example:\n\n```\nJarvis: Karl, what are you planning to do today?\nKarl: I have no idea. How is the weather?\nJarvis: The weather is fine.\nJarvis: So what are you planning to do today?\nKarl: I'm going to the beach.\nJarvis: Oh, a very good idea.\n```\n\nNote: Most other bots would forget about their initial question (plans for the day) if you issue a new command. But not mine :)\n\nCurrent skills:\n- Ask me to take memos during meetings and remind me later (based on iCAL calendar entries)\n- Send emails that propose dates for a meeting\n- Check the weather (based on [OpenWeatherMap](https://openweathermap.org/api))\n- Check the next calendar entry (iCal integration that works with Google Calendar)\n\nFeatures:\n- Context classes that encapsulate dialogs, e.g. checking the weather.\n- no hard dependency on Telegram, so I can use a voice interface like Alexa or Google Home later\n\nSkills I'd love to implement:\n- smart scheduling: automatically derive possible timeslots when scheduling a meeting or use something like doodle\n- get recommendations to keep in touch with people you have not contacted for a while (hubspot integration)\n- send meeting reminders via email or sms (based on calendar and hubspot contacts)\n- log current position on demand\n- save reminders\n- let others talk to the bot and play with it\n- send contacts your current phone number, etc.\n- delay tasks (e.g. meeting memos: delay so that the dialog reappears after 10 minutes)\n- email meeting memos to participants\n- create drafts of emails via smtp\n\n\n## Example of meeting time proposals\nThe command `/schedule` triggers the creation of an meeting proposal that is sent to all participants after you have answered all necessary questions. It looks like this:\n\n\u003e Hello,\n\u003e\n\u003e this is Jarvis, personal assistant of Karl Lorey. For your appointment ('Learning more about Jarvis, my personal\n\u003e assistant') I propose a time slot of 60 minutes on one of the following dates:\n\u003e - Tomorrow\n\u003e - Friday\n\u003e\n\u003e Currently, I just send the proposals, so please hit 'reply all' to get Karl Lorey back into the loop.\n\u003e __________\n\u003e Jarvis\n\u003e Personal Assistant of Karl Lorey\n\u003e\n\u003e You can find my code at https://github.com/lorey/totally-not-jarvis\n\n\n## The config file: config.py\n\nThe config file should look like this (not included for obvious reasons):\n\n```python\n# names\nBOT_NAME = 'Jarvis'\nOWNER_NAME = 'Karl Lorey'\nPOSITION = {'lat': 49.01, 'lon': 8.4}\n\n# telegram\nTELEGRAM_TOKEN = ''\nTELEGRAM_CHAT_ID = ''\n\n# weather\nOPENWEATHERMAP_API_KEY = ''\n\n# calendar (name: url)\nICAL_URLS = {\n    \"private\": \"https://calendar.google.com/calendar/ical/exampleexampleexample/basic.ics\",\n    \"work\": \"https://calendar.google.com/calendar/ical/justanexample/public/basic.ics\",\n}\n\n# email\nEMAIL_ADDRESS_JARVIS = 'jarvis@mail.com'\nEMAIL_ADDRESS_CC = 'your@mail.com'\nEMAIL_SMTP_HOST = 'www.server.com'\nEMAIL_SMTP_PORT = 465\nEMAIL_IMAP_USER = 'jarvis'\nEMAIL_IMAP_PASSWORD = 'captainwho?'\n\n\n```\n\n\n## Implement own functionality\n\nTo implement own skills, you just have to extend the base class and make sure a command puts the context on top of the contexts stack. We'll start with a `RepeatContext` that just repeats your input:\n\n```python\nclass RepeatContext(BaseContext):\n    def is_done(self):\n        return True  # executed only once\n\n    def process(self, bot, update):\n        bot.send_message(chat_id=update.message.chat_id, text=update.message.text.replace('/repeat ', '')\n```\n\nThe base class only has two methods that you need to implement:\n- `process` receives all user input while the context is active (`is_done() == False`). You can basically do whatever you want as long as you want. Messages can be accessed with `update.message.text`.\n- `is_done` ist self-explanatory. If true, the context will be removed and the context before that will start again.\n\nAfterwards, you just have to check for the command and open the context:\n\n```python\nclass DefaultContext(BaseContext):\n    # ...\n\n    def process(self, bot, update):\n        if update.message is not None and update.message.text.startswith('/repeat '):\n            # starts the repeat context\n            context = RepeatContext()  # crate context\n            self.jarvis.contexts.append(context)  # put it on the stack\n            context.process(bot, update)  # start by processing for the first time\n        else:\n            bot.send_message(chat_id=update.message.chat_id, text=\"I don't understand\")\n```\n\n# Also check my other HubSpot-related projects\n\nIf you came here for the HubSpot integration, make sure to check out my other projects:\n\n- [awesome-hubspot: Tools and libraries for HubSpot](https://github.com/lorey/awesome-hubspot)\n- [hubspot-contact-import: A HubSpot import tool for vcards and Xing](https://github.com/lorey/hubspot-contact-import)\n- [hubspot-reporting: tool to generate diagrams from your HubSpot data](https://github.com/lorey/hubspot-reporting)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Florey%2Ftotally-not-jarvis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Florey%2Ftotally-not-jarvis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Florey%2Ftotally-not-jarvis/lists"}