11 KiB
Having a look at the projects ~/projects/obsidian_vault_maintainers and '~/projects/redmine/`, I would like to have a set of scripts, cronjobs, or agents/prompts that does something like the following:
First, import the PROJECT.md from configs and apply it to ~/projects/redmine
This is to ensure that further work on this project is documented and worked on in the manner we're beginning to standardize for most of our projects.
Second, critical update to the redmine project script: redmine_contacts.py
- Fetch and search should have an option to only show contacts based on optional filters (if possible):
- Filter what contacts are fetched based on:
- created_on and/or updated_on
- presence or lack of a specific tag, "no tag at all", etc
- Filter what contacts are fetched based on:
- Add command to fetch an entire ticket by issue_id. This should be similar to how the
redMCPhandles being asked to retrieve a complete ticket (it should include the journals/notes, helpdesk info, etc. as well as the basic ticket info). - Add an options for
show, which outputs the full data/json object for a specific contact_id- Should be able to pull from the local cache if it exists, so we don't keep calling the API without good reason
- Should also be able to pull directly from the API
- Cleaner support for particular aspects of the
updatecommand:- tag_list:
- It should be easy to add or remove a specific tag. As it stands, using update and
--set tag_list=requires listing all of the desired tags (delimited by commas), and overwrites any pre-existing value.- Instead, we should just have a simple '--addTag ' and '--removeTag ' options for the
updatecommand
- Instead, we should just have a simple '--addTag ' and '--removeTag ' options for the
- It should be easy to add or remove a specific tag. As it stands, using update and
- custom_fields:
- We should be able to set a specific custom field to a new value, without deleting/overwriting other customer fields.
- E.g. "Account Number" is customer field id 70. We should be able to easily set a particular contact's account number to something new without overwriting, deleting, or needing to re-send the values of other customer fields (like field 42, their Facebook profile/link)
- Specify by kebab-case custom-field name, rather than numeric id:
- Examples:
- Custom field id 70 is "Account Number". Should be able to do --setCustomField account-number="whatever"
- Custom field id 88 is "X/Twitter". Should be able to do --setCustomField x-twitter="foobar"
- Examples:
- We should be able to set a specific custom field to a new value, without deleting/overwriting other customer fields.
- tag_list:
- Conduct some related research: research the following and add it to documentation within the project:
- Possible duplicates: The web interface for the helpdesk_contacts plugin has a feature which shows possible duplicate contacts, and supports a workflow for "merging them". We need to know if it's feasible to implement this feature via the API or through a bash script, so we can merge contacts if needed.
- The existing web workflow ends up at a url like this:
/contacts/<contact1_id>/duplicates?project_id=<project_slug>, and allows submitting a form which passesduplicate_id.- E.g. If we wanted to merge contact 1500 with contact 11, we'd end up at
/contacts/1500/duplicates?project_id=customer-serviceand then submit the form withduplicate_id=11as a POSTed data field. Doing so would:- Delete contact 1500
- Any tickets, deals, etc. previously associated with 1500 would then be associated with 11
- E.g. If we wanted to merge contact 1500 with contact 11, we'd end up at
- Subgoal 1: Check if the API seems to support a call for replicating this workflow.
- If it does, spec out how easily it could be added as an option/tool for this script
- If it does not, check if utilizing something like
curlto achieve it would be safe and feasible. Do so by investigating how the normal browser path would work.
- The existing web workflow ends up at a url like this:
- Possible duplicates: The web interface for the helpdesk_contacts plugin has a feature which shows possible duplicate contacts, and supports a workflow for "merging them". We need to know if it's feasible to implement this feature via the API or through a bash script, so we can merge contacts if needed.
It's not super important to implement this exactly the way I'm saying. Please pay more attention to how I want to use the data.
Some context:
Local testing copy/instance of Redmine
192.168.50.170 hosts a local instance of Redmine that is synced from the production system daily, so it acts and behaves like the real website. This can be used for testing/verifying features/changes. To do so, in any of these commands which reference a --base-url option, use http://192.168.50.170 instead of https://rm.ldrprep.com.
How to fetch a JSON blob of all visible contacts:
~/projects/redmine/redmine_contacts.py --project customer-service --base-url https://rm.ldrprep.com fetch
The above will save a cached JSON blob of all visible contacts in ~/.cache/redmine_contacts/rm.ldrprep.com_customer-service.json
Fetch recent tickets for a specific contact
# Outdated
# ~/projects/redmine/redmine_contacts.py --base-url https://rm.ldrprep.com --project customer-service helpdesk-timeline --limit 5 <contact_id>
# Use this method
~/projects/redmine/redmine_contacts.py --base-url https://rm.ldrprep.com --project customer-service helpdesk-issues --limit 5 <contact_id>
This will show metadata about the five most recent tickets involving that contact (if there are any). The results will include the subject of the ticket, issue_id for pulling up more details, assigned_to_name (person or group assigned to, if any), updated_on (date and time the ticket last changed by anybody), created_on (date and time the email chain started), from_address (actual email address the contact used to email us), and other fields.
Overall project objectives
- Support programmatic recall/fetch of Redmine contacts in these kinds of ways:
- All contacts who have been created since date1 but have not been updated more recently than date2.
- This is for the purpose of doing things such as cycling through all of our contacts to apply basic changes to them like fixing their name or possibly adding basic tags to them. The idea being, we could ask for "20 newest contacts not updated within the last 7 days" or something, update them, and then go again. Eventually, we would get through all of the contacts.
- Contacts with a specific combination of tags (specific tag or couple tags, TagA but not TagB, no tags at all, etc)
- E.g. "All contacts with the tag 'customer', but without the tag 'prep'"
- No background entry recorded
- All contacts who have been created since date1 but have not been updated more recently than date2.
- Core outcomes we want to enable:
- Tagging contacts as a guide for other automated tools: We want to be able to use tags to control how other automated tools may do things, such as triaging new tickets received, automatically adding additional context, etc.
- Identify and link 'company' contacts with people who work at that company:
- From context within tickets, we can tell that a contact works at a company, and we can infer the name of that company.
- If it does not already exist, add the company as a contact in Redmine, then:
- Identify contacts who are people that work at that company, and update their profile so the
companyfield=the company they work at.
- Identify contacts who are people that work at that company, and update their profile so the
- Support robust profiles across obsidian, Redmine, NMI, and other systems:
- Outside the scope of this project right now, but we want to be able to do enrichment with our contacts, working to complete missing information like their LinkedIn profile or job title.
- Obsidian should have a matching entry for any significant contact, such as a customer, employee, or vendor.
- Each of these profiles should cross-reference each other, where possible. For instance:
- Redmine profile contacts
user_account.user_account_idvalue from NMI which corresponds to that contact's account in the NMI portal (if they are a customer or employee) - User account notes in NMI link to the highest-level contact entity in Redmine (typically the company the person works at/for)
- Accurate phone number appears the same in all relevant places
- Redmine profile contacts
- Compile/calculated Gist:
- Given a particular contact and a timespan, we should be able to fetch all
customer-servicetickets from Redmine that were updated within that timespan and which involve that contact. - If we specified a contact that is a company, this should fetch all tickets involving anybody at that company
- We should then be able to generate an AI summary of the main topics or situations that contact was interested in or talking about during that timespan.
- This kind of summary/gist can be displayed or referenced in various places, and would be saved within obsidian in a manner that ties it together with the contact and timespan.
- Given a particular contact and a timespan, we should be able to fetch all
- Identify and mark contacts as customers as follows:
- Fetch contacts that do not have the "customer" tag and have not been updated recently
- Check for the 5 most recent tickets involving that contact, and do as folows:
- Determine if they are likely a customer, and then document them:
- The following things indicate the contact is a customer. The more of these which apply, the stronger the chance is they are a customer:
- The ticket(s) are assigned to a specific person (a name);
- Someone on our side replied to the ticket, appearing to answer their question or provide information;
- The content of the ticket is talking about something like a package, shipment, order, prep, or pictures;
- The contact does not appear to be selling us anything or trying to get us to register to a service of some kind;
- If they are a customer, update the contact as follows:
- Add the tag "customer"
- Add the tag "needs-enriched"
- Add the tag "needs-nmi-sync"
- Check obsidian-ldr to see if there is a file about the customer.
- If there isn't, create one. Place it under
people/DRAFT/to indicate a human should confirm it seems to be accurate. - The file should cross-reference/link to the Redmine contact, including the following information:
- First and last name, name of company they work for, email address, phone number, and contact_id
- If there isn't, create one. Place it under
- They are not a customer, but are clearly something else:
- Automated Mailer: The contact is most likely an automated mailer.
- This is determined by checking for the following criteria. If most of these are true, they're probably an automated mailer:
- There are five or more tickets from them, and those tickets all seem to be about the same general topic;
- There are no replies to their tickets from anyone on our team;
- The tickets are not assigned to named person or group;
- The email body says something like "this inbox is not monitored";
- Their email address includes "no-reply@" or "noreply@"
- Apply the tag "Automailer" to the contact
- This is determined by checking for the following criteria. If most of these are true, they're probably an automated mailer:
- Automated Mailer: The contact is most likely an automated mailer.
- The following things indicate the contact is a customer. The more of these which apply, the stronger the chance is they are a customer:
- Determine if they are likely a customer, and then document them:
- This system should have a "dry run" feature for testing purposes, and should work so it can be limited to updating a specific number of contacts each time it is run.
The main goal to start with is tuning up and improving the redmine_contacts.py CLI script. Feel free to note and sideline goals which seem too ambicious to handle at the moment.