Exploring the Three Core Components of Our Social Media Automation Solution
Introduction
When we first created our social media automation solution, we struggled with a lot of copy-pasting and messy code. But with the release of V2, we’ve tackled those issues head-on by modularizing workflows. Now, the main posting logic in our scripts is based on workloads and event definitions, which enables us to set up multiple accounts that follow entirely different approaches to content creation and uploading. This upgrade has been a game-changer for our platform, allowing us to set up various accounts in no time at all. And with our modular approach, we’ve made our solution even more flexible, allowing us to customize our social media strategies easily.
Three Core Components
Worker
A worker, which is essentially the entire automation unit that acts on strategies. It is responsible for executing the steps necessary to complete a task. In our social media automation system, workers might be responsible for content creation, scheduling, or e ngaging with followers. There are three core components to our automation system
Strategies
Strategies, on the other hand, define the specific approach a worker uses to accomplish a task. A strategy might include steps for creating, building, uploading, or handling errors related to a piece of content or engagement. The strategy also exposes events to transform data used in the workflow, which allows for customization and flexibility in the automation process.There are three core components to our automation system
Contexts
Finally, context objects which are dynamically injected and passed to strategy callbacks. This objects wrap runtime or static data and allows interactions with various systems, subsystems, and third-party systems. Essentially, the context object allows for the strategy to interact with the larger automation system and adjust its behavior accordingly Overall, these three concepts are critical to our solution that allows us to build a system that is customizable, flexible, and capable of achieving specific business goals. Below is an example of the workflow definition for one of our social media channels, ‘officiallyuselessfacts’
def on_init(threefold_ctx: ThreefolderContext):
# ...
def on_build(threefold_ctx: ThreefolderContext, gpt_ctx: GptContext, image_editor_ctx: ImageEditorContext,
speech_ctx: SpeechContext, video_editor_ctx: VideoEditorContext):
# ...
def on_upload(threefold_ctx: ThreefolderContext, instagram_ctx: InstagramContext, twitter_ctx: TwitterContext):
# ...
def on_error(exception_ctx: ExceptionContext):
# ...
config = Config.from_json_file("./config/config.json")
strategy = ThreeFolderStrategy(config, on_init, on_build, on_upload, on_error)
worker = AutomationWorker(strategy)
worker.execute()
The code snippet shown above demonstrates how to initialize a new AutomationWorker, which serves as a basic worker that executes a specific strategy. One of our most straightforward strategy implementations is the ThreeFolderStrategy, which is fully automated and focused on content creation. This strategy is structured around the creation of three folders: Content, Uploaded, and Error. When executed by a worker, this strategy initiates a full iteration of the init, build, and upload steps, while also handling any errors that may arise.
The ThreeFolderStrategy works by generating a folder within the content folder, which is identified by an ID representing the currently built content. The build process is skipped, if there is enough content already available, which allows to prebuild batches of content. This folder is then used to store and inject requested contexts via the on_build callback. Once this callback has been executed, the workflow moves on to the upload step. Here, a folder is selected from the content folder, requested contexts are built, and the upload callback is called with the provided contexts.
Upon successful completion of the upload process, the content folder is moved to the uploaded folder. If any errors occur during the workflow, the content folder is moved to the error folder (if possible), and metadata related to the error and the content build is logged. The error callback is then invoked with the requested contexts.
class GptContext(Context):
def __init__(self, config: ConfigGptMixin) -> None:
super().__init__()
self.config = config
self.gpt = gpt.Gpt(config.gpt_key)
def prompt(self, prompt):
return self.gpt.prompt(prompt)
@classmethod
def config_needs(cls):
return [ConfigGptMixin]
This is an example context that can be requested in callbacks. Typically, every context is passed in the configuration file of the strategy and also provides a method to check if the provided configuration supports this context. In this case, the GptContext expects the configuration to have the data provided by the ConfigGptMixin. Specifically, it should contain API key files for OpenAI GPT or our local GPT-J 6B server.
Dynamic Config
The configuration for all of our automation and context objects, which I deleted recently in an act of overconfidence, is stored within our database and dynamically constructed on the executing script’s side. Built-in validation measures have been implemented to ensure that requesting a context in a callback is only possible if the corresponding configuration has been specified. This practice guarantees that the context, upon successful injection, is always equipped with the necessary configuration to function optimally.
Context Injection
The creation and validation of contexts are executed dynamically through the use of a callback function signature. Should a requested context be unsupported by the provided configuration, an exception is triggered.
An important consideration is that, as contexts are stateless, a strategy may introduce state data by implementing an interceptor that augments the context builder. This approach is exemplified by the ThreeFolderContext, which contains pertinent details regarding the current folder’s name and location. The latter values are subject to change based on the specific state of the strategy.
def build_context_pairs(func: Callable, *args, interceptors: dict[type, Interceptor] = {}):
requested_args = utils.arg_annotations(func)
context_pairs: dict[str, Context] = {}
for arg_name, arg_type in requested_args:
instance = arg_type(*args)
interceptor = interceptors.get(arg_type)
if interceptor:
instance.__dict__.update(interceptor.values)
context_pairs[arg_name] = instance
return context_pairs
context_pairs = build_context_pairs(self.on_upload, self.config, interceptors= {
ThreefolderContext: Interceptor(dynamic_folder = working_folder),
})
self.on_upload(**context_pairs)
More
A variety of strategies and contexts are available to support content creation, including the ConsumerStrategy . This content upload strategy functions as an uploading service without a build process, allowing external tools to generate and place content in the designated folder. The system can consume content at predetermined intervals or as it becomes available.
For Instagram engagement, the EngagementStrategy is available as a dedicated solution. The EngagementStrategy can follow accounts that post specific content and generate likes, comments, and replies. The ImageCaptionReaderContext provides additional support for this strategy, leveraging our object recognition network to determine image content. The output is further utilized by the GptContext to create appropriate comments.
The system also provides context for image generation, such as the MidjourneyContext, which automates Midjourney, and the StableDiffusionContext, which executes image generation hosted on our own servers. Both contexts support image generation for content creation, with the latter allowing us to specify our own trained models in the strategy’s configuration.
One of the key contexts used across all our channels, including our news channel ‘officalignews,’ is the image editor. This powerful tool enables us to transform and edit images to suit our needs. By resizing, cropping, blurring, pasting, and adding text to a base image, we can create the perfect visual asset for any occasion.
For example, we can take an image from a news post and transform it to a post with the image editor
The possibilities are endless with the image editor, and we are constantly discovering new ways to leverage its capabilities to enhance our content across all our channels.
With its intuitive interface and powerful features, the image editor is a crucial component of our content creation process. Whether we need to create eye-catching thumbnails for our videos, engaging images for our social media posts, or stunning visuals for our articles, the image editor helps us achieve our creative vision with ease and efficiency.